So I am working on implementing a z-buffer in my graphics code, and I am having some problems with interpolating along the z axis. I am not sure exactly what the problem is, but maybe one of you can spot it.
First of all, here is my line function which draws from an (x,y,z) point to another (x,y,z) point. The two endpoints of the line have already been passed through the model view and projection matrices, divided by w, and the viewport transformation. Therefore the (x,y) coordinates are the actual coordinates on the screen where they should be plotted.
I do interpolation along the z-axis in the same way that I do color interpolation, so I am not exactly sure why it isn't work. Color interpolation works perfectly. Just interpolation along the z-axis doesn't work. I have highlighted in red everything that pertains to interpolating along the z axis.
Code://draws a line the fast way, using Bresenham's algorithm
void line ( float *surface, point a, point b, color sColor, color fColor )
{
int Ax = a.x;
int Bx = b.x;
int Ay = a.y;
int By = b.y;
float Az = a.z;
float Bz = b.z;
color curColor = sColor;
int dX = abs(Bx-Ax); // store the change in X and Y of the line endpoints
int dY = abs(By-Ay);
float dZ = Bz-Az;
if ( dZ < 0.0f ) dZ = -dZ;
float curZ = Az;
int Xincr, Yincr;
if (Ax > Bx) { Xincr=-1; } else { Xincr=1; } // which direction in X?
if (Ay > By) { Yincr=-1; } else { Yincr=1; } // which direction in Y?
if (dX >= dY) // if X is the independent variable
{
int dPr = dY<<1; // amount to increment decision if right is chosen (always)
int dPru = dPr - (dX<<1); // amount to increment decision if up is chosen
int P = dPr - dX; // decision variable start value
for (int counter = 0; counter <= dX; counter++)
{
//putpixel(screen, Ax, Ay, Color); // plot the pixel
putpixel ( surface, Ax, Ay, curZ, curColor );
curColor.r += ( fColor.r - sColor.r ) / dX;
curColor.g += ( fColor.g - sColor.g ) / dX;
curColor.b += ( fColor.b - sColor.b ) / dX;
curColor.a += ( fColor.a - sColor.a ) / dX;
curZ += dZ / dX;
if (P > 0) // is the pixel going right AND up?
{
Ax+=Xincr; // increment independent variable
Ay+=Yincr; // increment dependent variable
P+=dPru; // increment decision (for up)
}
else // is the pixel just going right?
{
Ax+=Xincr; // increment independent variable
P+=dPr; // increment decision (for right)
}
}
}
else // if Y is the independent variable
{
int dPr = dX<<1; // amount to increment decision if right is chosen (always)
int dPru = dPr - (dY<<1); // amount to increment decision if up is chosen
int P = dPr - dY; // decision variable start value
for (int counter = 0; counter <= dY; counter++)
{
//putpixel(screen, Ax, Ay, Color); // plot the pixel
putpixel ( surface, Ax, Ay, curZ, curColor );
curColor.r += ( fColor.r - sColor.r ) / dY;
curColor.g += ( fColor.g - sColor.g ) / dY;
curColor.b += ( fColor.b - sColor.b ) / dY;
curColor.a += ( fColor.a - sColor.a ) / dY;
curZ += dZ / dY;
if (P > 0) // is the pixel going up AND right?
{
Ax+=Xincr; // increment dependent variable
Ay+=Yincr; // increment independent variable
P+=dPru; // increment decision (for up)
}
else // is the pixel just going up?
{
Ay+=Yincr; // increment independent variable
P+=dPr; // increment decision (for right)
}
}
}
}
Now, it's important that you know the details of how I implement the z buffer. It is declared as a float*, and it is initialized to be of the size 640 * 480, with each value being initialized to 1.0f.
Here is how I implement z buffering in my putpixel function:
Does anyone see anything wrong with that code?Code:void putpixel( float *surface, int x, int y, float z, color myColor )
{
//Clip points that are outside of our viewport
if ( x < masterViewPort.x || x > (masterViewPort.x + masterViewPort.width) )
return;
if ( y < masterViewPort.y || y > (masterViewPort.y + masterViewPort.height) )
return;
//Z buffering
if ( z > zBuffer[(y * 640) + x] ) return;
//Plot the point if it passes all tests.
surface[((y*640) + x)*3 + 0] = myColor.r;
surface[((y*640) + x)*3 + 1] = myColor.g;
surface[((y*640) + x)*3 + 2] = myColor.b;
}