2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
import algebra.*;
|
|
|
|
|
|
|
|
/**
|
2022-04-14 20:42:57 +00:00
|
|
|
* The PerspectiveCorrectRasterizer class extends Rasterizer to perform
|
|
|
|
* Persepctive Correct interpolation
|
2022-04-12 10:08:58 +00:00
|
|
|
* of attributes.
|
|
|
|
*
|
|
|
|
* @author cdehais
|
|
|
|
*/
|
|
|
|
public class PerspectiveCorrectRasterizer extends Rasterizer {
|
|
|
|
|
2022-04-14 20:42:57 +00:00
|
|
|
public PerspectiveCorrectRasterizer(Shader shader) {
|
2022-04-12 10:08:58 +00:00
|
|
|
super(shader);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Rasterizes the triangular face made of the Fragment v1, v2 and v3
|
|
|
|
*/
|
2022-04-14 20:42:57 +00:00
|
|
|
public void rasterizeFace(Fragment v1, Fragment v2, Fragment v3) {
|
|
|
|
Matrix C = makeBarycentricCoordsMatrix(v1, v2, v3);
|
2022-04-12 10:08:58 +00:00
|
|
|
|
|
|
|
/* iterate over the triangle's bounding box */
|
2022-04-14 20:42:57 +00:00
|
|
|
int xmin = Math.min(v1.getX(), Math.min(v2.getX(), v3.getX()));
|
|
|
|
int ymin = Math.min(v1.getY(), Math.min(v2.getY(), v3.getY()));
|
|
|
|
int xmax = Math.max(v1.getX(), Math.max(v2.getX(), v3.getX()));
|
|
|
|
int ymax = Math.max(v1.getY(), Math.max(v2.getY(), v3.getY()));
|
|
|
|
|
|
|
|
Fragment fragment = new Fragment(0, 0);
|
|
|
|
int numAttributes = fragment.getNumAttributes();
|
2022-04-12 10:08:58 +00:00
|
|
|
try {
|
2022-04-14 20:42:57 +00:00
|
|
|
for (int x = xmin; x <= xmax; x++) {
|
|
|
|
for (int y = ymin; y <= ymax; y++) {
|
|
|
|
|
|
|
|
/* setup position now to allow early clipping */
|
|
|
|
fragment.setPosition(x, y);
|
|
|
|
if (!shader.isClipped(fragment)) {
|
|
|
|
|
|
|
|
Vector3 v = new Vector3(1.0, (double) x, (double) y);
|
|
|
|
Vector bar = C.multiply(v);
|
2022-04-19 09:02:07 +00:00
|
|
|
|
2022-04-14 20:42:57 +00:00
|
|
|
if ((bar.get(0) >= 0.0) && (bar.get(1) >= 0.0) && (bar.get(2) >= 0.0)) {
|
2022-04-19 09:02:07 +00:00
|
|
|
|
2022-04-14 20:42:57 +00:00
|
|
|
double oneOverZ = bar.get(0) / v1.getDepth() +
|
|
|
|
bar.get(1) / v2.getDepth() +
|
|
|
|
bar.get(2) / v3.getDepth();
|
2022-04-19 09:02:07 +00:00
|
|
|
|
2022-04-14 20:42:57 +00:00
|
|
|
for (int i = 0; i < numAttributes; i++) {
|
2022-04-19 09:02:07 +00:00
|
|
|
|
2022-04-14 20:42:57 +00:00
|
|
|
double aOverZ = bar.get(0) * v1.getAttribute(i) / v1.getDepth() +
|
|
|
|
bar.get(1) * v2.getAttribute(i) / v2.getDepth() +
|
|
|
|
bar.get(2) * v3.getAttribute(i) / v3.getDepth();
|
|
|
|
|
|
|
|
fragment.setAttribute(i, aOverZ / oneOverZ);
|
|
|
|
}
|
|
|
|
shader.shade(fragment);
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (SizeMismatchException e) {
|
|
|
|
/* should not reach */
|
2022-04-14 20:42:57 +00:00
|
|
|
e.printStackTrace();
|
2022-04-12 10:08:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|