Now I am learning perspective correct texture mapping. I had wrote a bit of code. My code do not works correctly. I understand common sense of perspective correct text.map. x/z and y/z -> u/z and v/z. But x and y in 3D space but u and v in 2D space- what is means? How works perspective correct texture mapping inside? I read many articles in Internet by this issue- but I had caught only common comprehend. My code I posted below. What is wrong in my code?
Thanks in advance.
void CMy3DApp::Draw_Textured_Triangle(My3DTriangle tri,
UCHAR *dest_buffer, // pointer to video buffer
int mem_pitch) // bytes per line, 320, 640 etc.
{
double du,dv,dudyl,dvdyl,dudyr,dvdyr,ui,vi,ul,vl,ur,vr;
int dx,dy,dyl,dyr, // general deltas
xi,yi, // the current interpolated x,y
xstart,
xend,
ystart,
yrestart,
yend,
xl,
dxdyl,
xr,
dxdyr;
int x0,y0, // cached vertices
x1,y1,
x2,y2;
double tu0,tv0, // cached vertices
tu1,tv1,
tu2,tv2;
int texture_shift2 = logbase2ofx[64];
irestart = INTERP_LHS;
// degenerate triangle
if ( ((tri.v1.x==tri.v2.x) && (tri.v2.x==tri.v3.x)) ||
((tri.v1.y==tri.v2.y) && (tri.v2.y==tri.v3.y)))
return;
My3DTexturedVert temp_1;
int temp;
// sort vertices
if (tri.v2.y < tri.v1.y)
{SWAP(tri.v1,tri.v2,temp_1);}
if (tri.v3.y < tri.v1.y)
{SWAP(tri.v1,tri.v3,temp_1);}
if (tri.v3.y < tri.v2.y)
{SWAP(tri.v2,tri.v3,temp_1);}
z0 = (double)1.0/ tri.v1.z;
z1 = (double)1.0/ tri.v2.z;
z2 = (double)1.0/ tri.v3.z;
x0 = (int)(tri.v1.x+0.5);
y0 = (int)(tri.v1.y+0.5);
x1 = (int)(tri.v2.x+0.5);
y1 = (int)(tri.v2.y+0.5);
x2 = (int)(tri.v3.x+0.5);
y2 = (int)(tri.v3.y+0.5);
tu0 = (double)(tri.v1.tu/ tri.v1.z);
tv0 = (double)(tri.v1.tv/ tri.v1.z);
tu1 = (double)(tri.v2.tu/ tri.v2.z);
tv1 = (double)(tri.v2.tv/ tri.v2.z);
tu2 = (double)(tri.v3.tu/ tri.v3.z);
tv2 = (double)(tri.v3.tv/ tri.v3.z);
// compute all deltas
// LHS
dyl = (y1 - y0);
dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
dudyl = (tu1 - tu0)/dyl;
dvdyl = (tv1 - tv0)/dyl;
dzdyl = z1 - z0;
// RHS
dyr = (y2 - y0);
dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
dudyr = (tu2 - tu0) /dyr;
dvdyr = (tv2 - tv0) /dyr;
dzdyr = z2 - z0;
xl = (x0 << FIXP16_SHIFT);
xr = (x0 << FIXP16_SHIFT);
ul = tu0;
vl = tv0;
ur = tu0;
vr = tv0;
zl = z0;
zr = z0;
ystart = y0;
// test if we need swap to keep rendering left to right
if (dxdyr < dxdyl)
{
SWAP(dxdyl,dxdyr,temp);
SWAP(dudyl,dudyr,temp);
SWAP(dvdyl,dvdyr,temp);
SWAP(xl,xr,temp);
SWAP(ul,ur,temp);
SWAP(vl,vr,temp);
SWAP(x1,x2,temp);
SWAP(y1,y2,temp);
SWAP(tu1,tu2,temp);
SWAP(tv1,tv2,temp);
// set interpolation restart
irestart = INTERP_RHS;
}
screen_ptr = dest_buffer + (ystart * mem_pitch);
for (yi = ystart; yi<=yend; yi++)
{
// compute span endpoints
xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
xend = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
// compute starting points for u,v interpolants
ui = ul;
vi = vl;
zi = zl;
// compute u,v interpolants
if ((dx = (xend - xstart))>0)
{
du = (ur - ul)/dx;
dv = (vr - vl)/dx;
dz = (zr - zl)/dx;
} // end if
else
{
du = (ur - ul);
dv = (vr - vl);
dz = (zr - zl);
}
int indx = xstart*4;
for (xi=xstart; xi<=xend; xi++)
{
double z = 1.0 / (1.0/zi);
int u = (ui / z) * z;
int v = (vi / z) * z;
int t = (u ) + ((v) << texture_shift2);
t= t*3;
screen_ptr[indx] = pRes[t];
indx++;
screen_ptr[indx] = pRes[t+1];
indx++;
screen_ptr[indx] = pRes[t+2];
indx++;
screen_ptr[indx] = 0;
indx++;
ui+=du;
vi+=dv;
zi+=dz;
} // end for xi
// interpolate u,v,x along right and left edge
xl+=dxdyl;
ul+=dudyl;
vl+=dvdyl;
zl+=dzdyl;
xr+=dxdyr;
ur+=dudyr;
vr+=dvdyr;
zr+=dzdyr;
// advance screen ptr
screen_ptr+=mem_pitch;
if (yi==yrestart)
{
if (irestart == INTERP_LHS)
{
// LHS
dyl = (y2 - y1);
dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
dudyl = (tu2 - tu1)/dyl;
dvdyl = (tv2 - tv1)/dyl;
dzdyl = z2 - z1;
// set starting values
xl = (x1 << FIXP16_SHIFT);
ul = tu1;
vl = tv1;
zl = z1;
// interpolate down on LHS to even up
xl+=dxdyl;
ul+=dudyl;
vl+=dvdyl;
zl+=dzdyl;
}
else
{
// RHS
dyr = (y1 - y2);
dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
dudyr = (tu1 - tu2)/dyr;
dvdyr = (tv1 - tv2)/dyr;
dzdyr = z1 - z2;
// set starting values
xr = (x2 << FIXP16_SHIFT);
ur = tu2;
vr = tv2;
zr = z2;
// interpolate down on RHS to even up
xr+=dxdyr;
ur+=dudyr;
vr+=dvdyr;
zr+=dzdyr;
}
} //end for y












