📄 tmapper.cpp
字号:
dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
// RHS
dyr = (y2 - y0);
dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
// compute overclip
dyr = (poly_clip_min_y - y0);
dyl = (poly_clip_min_y - y1);
// computer new LHS starting values
xl = dxdyl*dyl + (x1 << FIXP16_SHIFT);
ul = dudyl*dyl + (tu1 << FIXP16_SHIFT);
vl = dvdyl*dyl + (tv1 << FIXP16_SHIFT);
// compute new RHS starting values
xr = dxdyr*dyr + (x0 << FIXP16_SHIFT);
ur = dudyr*dyr + (tu0 << FIXP16_SHIFT);
vr = dvdyr*dyr + (tv0 << FIXP16_SHIFT);
// compute new starting y
ystart = poly_clip_min_y;
// 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;
} // end if
} // end if
else
if (y0 < poly_clip_min_y)
{
// compute all deltas
// LHS
dyl = (y1 - y0);
dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
// RHS
dyr = (y2 - y0);
dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
// compute overclip
dy = (poly_clip_min_y - y0);
// computer new LHS starting values
xl = dxdyl*dy + (x0 << FIXP16_SHIFT);
ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
// compute new RHS starting values
xr = dxdyr*dy + (x0 << FIXP16_SHIFT);
ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
// compute new starting y
ystart = poly_clip_min_y;
// 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;
} // end if
} // end if
else
{
// no initial y clipping
// compute all deltas
// LHS
dyl = (y1 - y0);
dxdyl = ((x1 - x0) << FIXP16_SHIFT)/dyl;
dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;
dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;
// RHS
dyr = (y2 - y0);
dxdyr = ((x2 - x0) << FIXP16_SHIFT)/dyr;
dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;
dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;
// no clipping y
// set starting values
xl = (x0 << FIXP16_SHIFT);
xr = (x0 << FIXP16_SHIFT);
ul = (tu0 << FIXP16_SHIFT);
vl = (tv0 << FIXP16_SHIFT);
ur = (tu0 << FIXP16_SHIFT);
vr = (tv0 << FIXP16_SHIFT);
// set starting y
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;
} // end if
} // end else
// test for horizontal clipping
if ((x0 < poly_clip_min_x) || (x0 > poly_clip_max_x) ||
(x1 < poly_clip_min_x) || (x1 > poly_clip_max_x) ||
(x2 < poly_clip_min_x) || (x2 > poly_clip_max_x))
{
// clip version
// x clipping
// point screen ptr to starting line
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 + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
// compute u,v interpolants
if ((dx = (xend - xstart))>0)
{
du = (ur - ul)/dx;
dv = (vr - vl)/dx;
} // end if
else
{
du = (ur - ul);
dv = (vr - vl);
} // end else
///////////////////////////////////////////////////////////////////////
// test for x clipping, LHS
if (xstart < poly_clip_min_x)
{
// compute x overlap
dx = poly_clip_min_x - xstart;
// slide interpolants over
ui+=dx*du;
vi+=dx*dv;
// set x to left clip edge
xstart = poly_clip_min_x;
} // end if
// test for x clipping RHS
if (xend > poly_clip_max_x)
xend = poly_clip_max_x;
///////////////////////////////////////////////////////////////////////
// draw span
for (xi=xstart; xi<=xend; xi++)
{
// write textel
screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << 6)];
// interpolate u,v
ui+=du;
vi+=dv;
} // end for xi
// interpolate u,v,x along right and left edge
xl+=dxdyl;
ul+=dudyl;
vl+=dvdyl;
xr+=dxdyr;
ur+=dudyr;
vr+=dvdyr;
// advance screen ptr
screen_ptr+=mem_pitch;
// test for yi hitting second region, if so change interpolant
if (yi==yrestart)
{
// test interpolation side change flag
if (irestart == INTERP_LHS)
{
// LHS
dyl = (y2 - y1);
dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
// set starting values
xl = (x1 << FIXP16_SHIFT);
ul = (tu1 << FIXP16_SHIFT);
vl = (tv1 << FIXP16_SHIFT);
// interpolate down on LHS to even up
xl+=dxdyl;
ul+=dudyl;
vl+=dvdyl;
} // end if
else
{
// RHS
dyr = (y1 - y2);
dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
// set starting values
xr = (x2 << FIXP16_SHIFT);
ur = (tu2 << FIXP16_SHIFT);
vr = (tv2 << FIXP16_SHIFT);
// interpolate down on RHS to even up
xr+=dxdyr;
ur+=dudyr;
vr+=dvdyr;
} // end else
} // end if
} // end for y
} // end if
else
{
// no x clipping
// point screen ptr to starting line
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 + FIXP16_ROUND_UP;
vi = vl + FIXP16_ROUND_UP;
// compute u,v interpolants
if ((dx = (xend - xstart))>0)
{
du = (ur - ul)/dx;
dv = (vr - vl)/dx;
} // end if
else
{
du = (ur - ul);
dv = (vr - vl);
} // end else
// draw span
for (xi=xstart; xi<=xend; xi++)
{
// write textel
screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << 6)];
// interpolate u,v
ui+=du;
vi+=dv;
} // end for xi
// interpolate u,v,x along right and left edge
xl+=dxdyl;
ul+=dudyl;
vl+=dvdyl;
xr+=dxdyr;
ur+=dudyr;
vr+=dvdyr;
// advance screen ptr
screen_ptr+=mem_pitch;
// test for yi hitting second region, if so change interpolant
if (yi==yrestart)
{
// test interpolation side change flag
if (irestart == INTERP_LHS)
{
// LHS
dyl = (y2 - y1);
dxdyl = ((x2 - x1) << FIXP16_SHIFT)/dyl;
dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;
dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;
// set starting values
xl = (x1 << FIXP16_SHIFT);
ul = (tu1 << FIXP16_SHIFT);
vl = (tv1 << FIXP16_SHIFT);
// interpolate down on LHS to even up
xl+=dxdyl;
ul+=dudyl;
vl+=dvdyl;
} // end if
else
{
// RHS
dyr = (y1 - y2);
dxdyr = ((x1 - x2) << FIXP16_SHIFT)/dyr;
dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;
dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;
// set starting values
xr = (x2 << FIXP16_SHIFT);
ur = (tu2 << FIXP16_SHIFT);
vr = (tv2 << FIXP16_SHIFT);
// interpolate down on RHS to even up
xr+=dxdyr;
ur+=dudyr;
vr+=dvdyr;
} // end else
} // end if
} // end for y
} // end else
} // end if
} // end Draw_Textured_Triangle
/******************************* EXAMPLE ***********************************
This is the setup:
To create a single triangle to be rendered consisting of the 3
points (in CC order I think):
(x0,y0,u0,v0)
(x1,y1,u1,v1)
(x2,y2,u2,v2)
64x64 texture at address texture_buffer in row major form
FACE3D face; // the triangle object
// set up the vertices
face.tlist[0].x = x0;
face.tlist[0].y = y0;
face.tlist[0].u = u0;
face.tlist[0].v = v0;
face.tlist[1].x = x1;
face.tlist[1].y = y1;
face.tlist[1].u = u1;
face.tlist[1].v = v1;
face.tlist[2].x = x2;
face.tlist[2].y = y2;
face.tlist[2].u = u2;
face.tlist[2].v = v2;
// assign the texture to your 64x64 texture map buffer
face.texture = texture_buffer;
// set the clipping coords of the desired 2D viewport
poly_clip_min_x = 0;
poly_clip_max_x = 0;
poly_clip_min_y = SCREEN_WIDTH-1;
poly_clip_max_y = SCREEN_HEIGHT-1
// then draw the triangle to the rendering buffer
Draw_Textured_Triangle((void *)&face, double_buffer, memory_pitch);
***************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -