2014年11月1日星期六(DEMO9-3模型纹理读取)

2014111日星期六(DEMO9-3模型纹理读取)

这一节理论很简单,无非就是纹理坐标通过插值和采样两种方式组成的。这节新加的内容就是对模型中的纹理进行了处理。

void ddraw_math::Draw_Textured_TriangleFS16( POLYF4DV2_PTR face, UCHAR * _dest_buffer, int mem_pitch )        // bytes per line, 320, 640 etc.

{

// this function draws a textured triangle in 16-bit mode with flat shading

 

     UCHAR logbase2ofx[513] =

     {

         0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,

         5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,

         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,

         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,

         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,

 

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

         8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,

 

     };

int v0=0,

    v1=1,

     v2=2,

     temp=0,

     tri_type = TRI_TYPE_NONE,

     irestart = INTERP_LHS;

 

int dx,dy,dyl,dyr,      // general deltas

    u,v,

    du,dv,

    xi,yi,              // the current interpolated x,y

     ui,vi,              // the current interpolated u,v

     index_x,index_y,    // looping vars

     x,y,                // hold general x,y

     xstart,

     xend,

     ystart,

     yrestart,

     yend,

     xl,                

     dxdyl,             

     xr,

     dxdyr,            

     dudyl,   

     ul,

     dvdyl,  

     vl,

     dudyr,

     ur,

     dvdyr,

     vr;

 

USHORT r_base, g_base, b_base,

       r_textel, g_textel, b_textel, textel;

 

int x0,y0,tu0,tv0,    // cached vertices

     x1,y1,tu1,tv1,

     x2,y2,tu2,tv2;

 

USHORT *screen_ptr  = NULL,

        *screen_line = NULL,

        *textmap     = NULL,

       *dest_buffer = (USHORT *)_dest_buffer;

 

#ifdef DEBUG_ON

     // track rendering stats

    debug_polys_rendered_per_frame++;

#endif

 

// extract texture map

textmap = (USHORT *)face->texture->buffer;

 

// extract base 2 of texture width

int texture_shift2 = logbase2ofx[face->texture->width];

 

// adjust memory pitch to words, divide by 2

mem_pitch >>=1;

 

// first trivial clipping rejection tests

if (((face->tvlist[0].y < m_min_clip_y)  &&

      (face->tvlist[1].y < m_min_clip_y)  &&

      (face->tvlist[2].y < m_min_clip_y)) ||

 

     ((face->tvlist[0].y > m_max_clip_y)  &&

      (face->tvlist[1].y > m_max_clip_y)  &&

      (face->tvlist[2].y > m_max_clip_y)) ||

 

     ((face->tvlist[0].x < m_min_clip_x)  &&

      (face->tvlist[1].x < m_min_clip_x)  &&

      (face->tvlist[2].x < m_min_clip_x)) ||

 

     ((face->tvlist[0].x > m_max_clip_x)  &&

      (face->tvlist[1].x > m_max_clip_x)  &&

      (face->tvlist[2].x > m_max_clip_x)))

   return;

 

// degenerate triangle

if ( ((face->tvlist[0].x==face->tvlist[1].x) && (face->tvlist[1].x==face->tvlist[2].x)) ||

      ((face->tvlist[0].y==face->tvlist[1].y) && (face->tvlist[1].y==face->tvlist[2].y)))

   return;

 

// sort vertices

if (face->tvlist[v1].y < face->tvlist[v0].y)

     {SWAP(v0,v1,temp);}

 

if (face->tvlist[v2].y < face->tvlist[v0].y)

     {SWAP(v0,v2,temp);}

 

if (face->tvlist[v2].y < face->tvlist[v1].y)

     {SWAP(v1,v2,temp);}

 

// now test for trivial flat sided cases

if (face->tvlist[v0].y==face->tvlist[v1].y)

     {

     // set triangle type

     tri_type = TRI_TYPE_FLAT_TOP;

 

     // sort vertices left to right

     if (face->tvlist[v1].x < face->tvlist[v0].x)

         {SWAP(v0,v1,temp);}

 

     } // end if

else

// now test for trivial flat sided cases

if (face->tvlist[v1].y==face->tvlist[v2].y)

     {

     // set triangle type

     tri_type = TRI_TYPE_FLAT_BOTTOM;

 

     // sort vertices left to right

     if (face->tvlist[v2].x < face->tvlist[v1].x)

         {SWAP(v1,v2,temp);}

    

     } // end if

else

     {

     // must be a general triangle

     tri_type = TRI_TYPE_GENERAL;

 

     } // end else

 

// extract base color of lit poly, so we can modulate texture a bit

// for lighting

_RGB565FROM16BIT(face->lit_color[0], &r_base, &g_base, &b_base);

 

// extract vertices for processing, now that we have order

x0  = (int)(face->tvlist[v0].x+0.5);

y0  = (int)(face->tvlist[v0].y+0.5);

tu0 = (int)(face->tvlist[v0].u0);

tv0 = (int)(face->tvlist[v0].v0);

 

x1  = (int)(face->tvlist[v1].x+0.5);

y1  = (int)(face->tvlist[v1].y+0.5);

tu1 = (int)(face->tvlist[v1].u0);

tv1 = (int)(face->tvlist[v1].v0);

 

x2  = (int)(face->tvlist[v2].x+0.5);

y2  = (int)(face->tvlist[v2].y+0.5);

tu2 = (int)(face->tvlist[v2].u0);

tv2 = (int)(face->tvlist[v2].v0);

 

// set interpolation restart value

yrestart = y1;

 

// what kind of triangle

if (tri_type & TRI_TYPE_FLAT_MASK)

     {

 

     if (tri_type == TRI_TYPE_FLAT_TOP)

     {

     // compute all deltas

     dy = (y2 - y0);

 

     dxdyl = ((x2 - x0)   << FIXP16_SHIFT)/dy;

     dudyl = ((tu2 - tu0) << FIXP16_SHIFT)/dy; 

     dvdyl = ((tv2 - tv0) << FIXP16_SHIFT)/dy;   

 

     dxdyr = ((x2 - x1)   << FIXP16_SHIFT)/dy;

     dudyr = ((tu2 - tu1) << FIXP16_SHIFT)/dy; 

     dvdyr = ((tv2 - tv1) << FIXP16_SHIFT)/dy;  

 

     // test for y clipping

     if (y0 < m_min_clip_y)

         {

         // compute overclip

         dy = (m_min_clip_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 + (x1  << FIXP16_SHIFT);

         ur = dudyr*dy + (tu1 << FIXP16_SHIFT);

         vr = dvdyr*dy + (tv1 << FIXP16_SHIFT);

 

         // compute new starting y

         ystart = m_min_clip_y;

 

         } // end if

     else

         {

         // no clipping

 

         // set starting values

         xl = (x0 << FIXP16_SHIFT);

         xr = (x1 << FIXP16_SHIFT);

 

         ul = (tu0 << FIXP16_SHIFT);

         vl = (tv0 << FIXP16_SHIFT);

 

         ur = (tu1 << FIXP16_SHIFT);

         vr = (tv1 << FIXP16_SHIFT);

 

         // set starting y

         ystart = y0;

 

         } // end else

 

     } // end if flat top

     else

     {

     // must be flat bottom

 

     // compute all deltas

     dy = (y1 - y0);

 

     dxdyl = ((x1 - x0)   << FIXP16_SHIFT)/dy;

     dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dy; 

     dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dy;   

 

     dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dy;

     dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dy; 

     dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dy;  

 

     // test for y clipping

     if (y0 < m_min_clip_y)

         {

         // compute overclip

         dy = (m_min_clip_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 = m_min_clip_y;

 

         } // end if

     else

         {

         // no clipping

 

         // 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;

 

         } // end else

 

     } // end else flat bottom

 

     // test for bottom clip, always

     if ((yend = y2) > m_max_clip_y)

         yend = m_max_clip_y;

 

    // test for horizontal clipping

     if ((x0 < m_min_clip_x) || (x0 > m_max_clip_x) ||

         (x1 < m_min_clip_x) || (x1 > m_max_clip_x) ||

         (x2 < m_min_clip_x) || (x2 > m_max_clip_x))

     {

    // clip version

 

     // 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 < m_min_clip_x)

              {

              // compute x overlap

              dx = m_min_clip_x - xstart;

 

              // slide interpolants over

              ui+=dx*du;

              vi+=dx*dv;

             

              // reset vars

              xstart = m_min_clip_x;

 

              } // end if

        

         // test for x clipping RHS

         if (xend > m_max_clip_x)

              xend = m_max_clip_x;

 

         ///

 

         // draw span

         for (xi=xstart; xi<=xend; xi++)

              {

              // write textel

             // get textel first

              textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];

 

            // extract rgb components

            r_textel  = ((textel >> 11)       );

            g_textel  = ((textel >> 5)  & 0x3f);

            b_textel =   (textel        & 0x1f);

 

            // modulate textel with lit background color

            r_textel*=r_base;

            g_textel*=g_base;

            b_textel*=b_base;

 

            // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32

            // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift

            // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts

            // and they all cancel out for the most part, but we will need logical anding, we will do

            // it later when we optimize more...

            screen_ptr[xi] = ((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11));

 

              // 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;

 

         } // end for y

 

     } // end if clip

     else

     {

     // non-clip version

 

     // 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

             // get textel first

              textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];

 

            // extract rgb components

            r_textel  = ((textel >> 11)       );

            g_textel  = ((textel >> 5)  & 0x3f);

            b_textel =   (textel        & 0x1f);

 

            // modulate textel with lit background color

            r_textel*=r_base;

            g_textel*=g_base;

            b_textel*=b_base;

 

            // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32

            // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift

            // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts

            // and they all cancel out for the most part, but we will need logical anding, we will do

            // it later when we optimize more...

            screen_ptr[xi] = ((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11));

 

              // 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;

 

         } // end for y

 

     } // end if non-clipped

 

     } // end if

else

if (tri_type==TRI_TYPE_GENERAL)

     {

 

     // first test for bottom clip, always

     if ((yend = y2) > m_max_clip_y)

         yend = m_max_clip_y;

 

     // pre-test y clipping status

     if (y1 < m_min_clip_y)

         {

         // compute all deltas

         // LHS

         dyl = (y2 - y1);

 

         dxdyl = ((x2  - x1)  << FIXP16_SHIFT)/dyl;

         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 = (m_min_clip_y - y0);

         dyl = (m_min_clip_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 = m_min_clip_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 < m_min_clip_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 = (m_min_clip_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 = m_min_clip_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 < m_min_clip_x) || (x0 > m_max_clip_x) ||

         (x1 < m_min_clip_x) || (x1 > m_max_clip_x) ||

         (x2 < m_min_clip_x) || (x2 > m_max_clip_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 < m_min_clip_x)

              {

              // compute x overlap

              dx = m_min_clip_x - xstart;

 

              // slide interpolants over

              ui+=dx*du;

              vi+=dx*dv;

             

              // set x to left clip edge

              xstart = m_min_clip_x;

 

              } // end if

        

         // test for x clipping RHS

         if (xend > m_max_clip_x)

              xend = m_max_clip_x;

 

         ///

 

         // draw span

         for (xi=xstart; xi<=xend; xi++)

              {

              // write textel

            //screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];

             // get textel first

              textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];

 

            // extract rgb components

            r_textel  = ((textel >> 11)       );

            g_textel  = ((textel >> 5)  & 0x3f);

            b_textel =   (textel        & 0x1f);

 

            // modulate textel with lit background color

            r_textel*=r_base;

            g_textel*=g_base;

            b_textel*=b_base;

 

            // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32

            // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift

            // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts

            // and they all cancel out for the most part, but we will need logical anding, we will do

            // it later when we optimize more...

            screen_ptr[xi] = ((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11));

 

              // 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

             // get textel first

              textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];

 

            // extract rgb components

            r_textel  = ((textel >> 11)       );

            g_textel  = ((textel >> 5)  & 0x3f);

            b_textel =   (textel        & 0x1f);

 

            // modulate textel with lit background color

            r_textel*=r_base;

            g_textel*=g_base;

            b_textel*=b_base;

 

            // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32

            // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift

            // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts

            // and they all cancel out for the most part, but we will need logical anding, we will do

            // it later when we optimize more...

            screen_ptr[xi] = ((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11));

 

              // 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_TriangleFS16

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值