CSE 328 -- FUNDAMENTALS OF COMPUTER GRAPHICS
Assignment 5 solution
unsigned int* zDepth = NULL;
int width, height, size;
void EnableHiddenSurfaceRemoval(int widthIn, int heightIn)
{
int i;
height = heightIn;
width = widthIn;
size = width*height;
if (zDepth) free(zDepth);
zDepth = (unsigned int*)malloc(sizeof(unsigned int)*size);
for(i=0;i < size;i++) zDepth[i] = 999999;
}
void ComputePlaneAndDepths(vertex v1, vertex v2, vertex v3, float* dZx)
{
float A,B,C;
float vect12x,vect12y,vect12z;
float vect13x,vect13y,vect13z;
float length;
float vect21x,vect21y,vect21z;
float vect23x,vect23y,vect23z;
float vect31x,vect31y,vect31z;
float vect32x,vect32y,vect32z;
// compute 2 vectors which lie in the plane of the
// polygon. Specifically, vectors v1->v2 and v1->v3
vect12x = v2.x-v1.x;
vect12y = v2.y-v1.y;
vect12z = v2.z-v1.z;
vect13x = v3.x-v1.x;
vect13y = v3.y-v1.y;
vect13z = v3.z-v1.z;
// normalize the two vectors
length = sqrtf(vect12x*vect12x+vect12y*vect12y+vect12z*vect12z);
if (length !=0.0) {
vect12x /= length;
vect12y /= length;
vect12z /= length;
} else {
vect12x = 0;
vect12y = 0;
vect12z = 0;
}
length = sqrtf(vect13x*vect13x+vect13y*vect13y+vect13z*vect13z);
if (length !=0.0) {
vect13x /= length;
vect13y /= length;
vect13z /= length;
} else {
vect13x = 0;
vect13y = 0;
vect13z = 0;
}
// compute the coefficients of the plane equation of the
// polygon (Ax+By+Cz+d=0). A, B & C are coefficients of
// the normal to the plane and they are computed using the
// cross product of two vectors in the plane. Specifically
// vect12 X vect13 since they must share their starting point.
A = vect12y*vect13z - vect13y*vect12z;
B = vect12z*vect13x - vect13z*vect12x;
C = vect12x*vect13y - vect13x*vect12y;
// compute dZx from the plane equation.
if (C!=0.0)
*dZx = -(A/C);
else
*dZx = 0;
} // ComputePlaneAndDepths
// -------------------------------------------------------------
// LoadLine
// Draw a line into the Frame buffer using the current color
// -------------------------------------------------------------
void LoadLine(int startX, int stopX, int y,
float currentZ, float dZx)
{
unsigned int x;
if (startX <= stopX) { // Left to right
for(x=startX; x < stopX; x++) {
if (!zDepth || currentZ < = zDepth[y*width+x]) {
put_line(x,y,x,y);
zDepth[y*width+x] = currentZ;
} // endif this fragment is in front of the z-buffer stored here
currentZ += dZx;
} // endfor all pixels in this scanline
} else {
for(x=startX; x>=stopX; x--) {
if (!zDepth || currentZ < = zDepth[y*width+x]) {
put_line(x,y,x,y);
zDepth[y*width+x] = currentZ;
} // endif this fragment is in front of the z-buffer stored here
currentZ += dZx;
} // endfor all pixels in this scanline
}
} // LoadLine
// -------------------------------------------------------------
// DrawTriangle
// Draw a triangle into the Frame buffer
// -------------------------------------------------------------
void DrawTriangle(int x1, int y1, int z1,
int x2, int y2, int z2,
int x3, int y3, int z3)
{
vertex v1;
vertex v2;
vertex v3;
unsigned int start = 0;
unsigned int stop = 1;
unsigned int startX,stopX;
unsigned int y;
unsigned int yoff;
tEdge edge[3];
float currentZ;
float this_dZx;
float weight;
v1.x = x1; v1.y = y1; v1.z = z1;
v2.x = x2; v2.y = y2; v2.z = z2;
v3.x = x3; v3.y = y3; v3.z = z3;
Transform(&v1);
Transform(&v2);
Transform(&v3);
//printf("(%d,%d,%d) ", v1.x,v1.y,v1.z);
//printf("(%d,%d,%d) ", v2.x,v2.y,v2.z);
//printf("(%d,%d,%d)\n", v3.x,v3.y,v2.z);
Project(&v1);
Project(&v2);
Project(&v3);
//printf("(%d,%d,%d) ", v1.x,v1.y,v1.z);
//printf("(%d,%d,%d) ", v2.x,v2.y,v2.z);
//printf("(%d,%d,%d)\n", v3.x,v3.y,v2.z);
LoadEdges(v1,v2,v3,edge);
ComputePlaneAndDepths(v1,v2,v3,&this_dZx);
//printf("%f\n",this_dZx);
//put_line(v1.x,v1.y,v2.x,v2.y);
//put_line(v1.x,v1.y,v3.x,v3.y);
//put_line(v2.x,v2.y,v3.x,v3.y);
for (y = edge[start].bottomVertex.y; y<=edge[start].yMax && y<=edge[stop].yMax; y++) {
if( y == edge[stop].yMax ) {
stop=2;
} else if( y == edge[start].yMax ) {
start=2;
} // endif change an edge
// interpolate the starting zDepth for this scanline
if (edge[start].topVertex.y != edge[start].bottomVertex.y)
weight = (float)( y - edge[start].bottomVertex.y) /
( edge[start].topVertex.y - edge[start].bottomVertex.y );
else
weight = 1.0;
currentZ = weight *edge[start].topVertex.z +
(1-weight)*edge[start].bottomVertex.z;
startX = edge[start].currentX+0.5;
stopX = edge[stop].currentX+0.5;
//put_line(startX, y, stopX, y);
LoadLine(startX, stopX, y, currentZ, this_dZx);
edge[start].currentX += edge[start].xInc;
edge[stop ].currentX += edge[stop ].xInc;
} // endfor still more polygon to rasterize
} // DrawTriangle