...
void
SWAP(float& a,
float& b)
{
float temp = a;
a =
b;
b =
temp;
}
void
MultiSwap(int &x0,
int &y0, float &u0,
float &v0,
int &x1,
int &y1, float
&u1, float &v1,
int &x2,
int &y2, float
&u2, float &v2 )
{
// Sort our points into order of y
// 0 top
// 2 middle
// 1 bottom
if( y1 < y0 )
{
SWAP(y1, y0);
SWAP(x1, x0);
SWAP(u1, u0);
SWAP(v1, v0);
}
if( y2 < y0 )
{
SWAP(y2, y0);
SWAP(x2, x0);
SWAP(u2, u0);
SWAP(v2, v0);
}
if( y1 < y2 )
{
SWAP(y2, y1);
SWAP(x2, x1);
SWAP(u2, u1);
SWAP(v2, v1);
}
}//
End of MultiSwap(..)
void
Draw_Textured_Triangle( unsigned
int* pBits, int
w, int h, int
pitch,
int
x0, int y0, float
u0, float v0,
int
x1, int y1, float
u1, float v1,
int
x2, int y2, float
u2, float v2,
stImage* pImage )
{
// Sort our y values into order:
// y0 < y2 < y1
MultiSwap(x0,y0,u0,v0, x1,y1,u1,v1, x2,y2,u2,v2);
// Declare some variables that we'll use and where
starting from y0 at the
// top of the triangle
float dxdy1 = (float)(x2-x0);
float dxdu1 = (u2-u0);
float dxdv1 = (v2-v0);
float dxdy2 = (float)(x1-x0);
float dxdu2 = (u1-v0);
float dxdv2 = (v1-v0);
float sdx,sdu,sdv;
float edx,edu,edv;
float pu, pv;
int x, y;
float dy1 = (float)(y2-y0);
float dy2 = (float)(y1-y0);
// Check for divide by zero's
if( y2-y0 != 0 )
{
dxdy1 /= dy1;
dxdu1 /= dy1;
dxdv1 /= dy1;
}
if( y1-y0 != 0 )
{
dxdy2 /= dy2;
dxdu2 /= dy2;
dxdv2 /= dy2;
}
float dxldy; float
dxrdy;
float dxldu; float
dxrdu;
float dxldv; float
dxrdv;
// Determine our left and right points for our x
value gradient..
// e.g. the starting and ending line for our x
inner loop
if( dxdy1 < dxdy2 )
{
dxldy = dxdy1; dxrdy = dxdy2;
dxldu = dxdu1; dxrdu = dxdu2;
dxldv = dxdv1; dxrdv = dxdv2;
}
else
{
dxldy = dxdy2; dxrdy = dxdy1;
dxldu = dxdu2; dxrdu = dxdu1;
dxldv = dxdv2; dxrdv = dxdv1;
}
// Initial starting x and ending x is sdx and edx
which are x0,y0...the
// top of our triangle
sdx
= (float)x0; sdu=u0; sdv=v0;
edx
= (float)x0; edu=u0; edv=v0;
pu
= u0; pv = v0;
float p_delta_u;
float p_delta_v;
for( y=(int)y0; y<= (int)y2; y++ )
{
p_delta_u = (edu - sdu);
p_delta_v = (edv - sdv);
if( edx - sdx != 0 )
{
p_delta_u /= (float)(edx -
sdx);
p_delta_v /= (float)(edx -
sdx);
}
pu=sdu; pv=sdv;
for( x=(int)sdx;
x<=(int)edx; x++ )
{
int iwidth = pImage->iWidth;
int iheight = pImage->iHeight;
int ww = (int)(pu*(iwidth-1));
int hh = (int)(pv*(iheight-1));
int pos = ww + hh*(iwidth);
if( pos >
(iwidth-1)*(iheight-1)) pos=(iwidth-1)*(iheight-1);
if( pos < 0 ) pos=0;
setpixel(pBits, w, h, pitch,
x, y,
pImage->pARGB[pos]);
pu += p_delta_u;
pv += p_delta_v;
}// End for loop x
sdx += dxldy; sdu+=dxldu; sdv+=dxldv;
edx += dxrdy; edu+=dxrdu; edv+=dxrdv;
}//
End for loop y
///////////////Now for the bottom of the
triangle////////////////////
if( dxdy1 < dxdy2 )
{
dxldy = (float)(x1-x2);
dxldu = (u1-u2);
dxldv = (v1-v2);
if(y1-y2 != 0)
{
dxldy /= (float)(y1-y2);
dxldu /= (float)(y1-y2);
dxldv /= (float)(y1-y2);
}// End inner if
sdx=(float)x2; sdu=u2; sdv=v2;
}
else
{
dxrdy = (float)(x1-x2);
dxrdu = (u1-u2);
dxrdv = (v1-v2);
if(y1-y2 != 0)
{
dxrdy /= (float)(y1-y2);
dxrdu /= (float)(y1-y2);
dxrdv /= (float)(y1-y2);
}// End inner if
edx=(float)x2; edu=u2; edv=v2;
}//
End of else
pu=u2;
pv=v2;
for( y=(int)y2; y<= (int)y1; y++ )
{
p_delta_u = (edu - sdu);
p_delta_v = (edv - sdv);
if( edx - sdx != 0 )
{
p_delta_u /= (float)(edx -
sdx);
p_delta_v /= (float)(edx -
sdx);
}
pu=sdu; pv=sdv;
for( x=(int)sdx;
x<=(int)edx; x++ )
{
int iwidth = pImage->iWidth;
int iheight = pImage->iHeight;
int ww = (int)(pu*(iwidth-1));
int hh = (int)(pv*(iheight-1));
int pos = ww + hh*(iwidth);
if( pos >
(iwidth-1)*(iheight-1)) pos=(iwidth-1)*(iheight-1);
if( pos < 0 ) pos=0;
setpixel(pBits, w, h, pitch,
x, y,
pImage->pARGB[pos]);
pu += p_delta_u;
pv += p_delta_v;
}// End for loop x
sdx += dxldy; sdu+=dxldu; sdv+=dxldv;
edx += dxrdy; edu+=dxrdu; edv+=dxrdv;
}//
End for loop y
}//
End of Draw_Textured_Triangle(..)
...... |