9-2加上光照计算的GOURAUD shader多边形)

9-2加上光照计算的GOURAUD shader多边形)

 

对于光照计算的颜色,就是考虑了法线和初始颜色。

对于固定着色的多边形,将多边形的颜色复制到lit_color[0]中;对于恒定着色的多边形,计算面法线,存储在lit_color[0] GOURAUD着色计算顶点法线,存储在lit_color{0,1,2}中。

 

光照计算步骤

1只计算光照强度,并对顶点进行标记,以防重复计算

2使用多边形的初始颜色对顶点的光照强度调制。

另外, 提到了一个物体转换为多边形时,顶点结合性将丧失,说白了,就是重复计算,因此,在物体级进行Gouraud计算较为合适。

原理仍然如此简单,代码仍然如此多。绝知此事要躬行。

 

 

 

intDDRAW_LIUSHUIXIAN_TEXTURE::Light_OBJECT4DV2_World16(ddraw_math math,int rgb_format,OBJECT4DV2_PTR obj,CAM4DV1_PTR cam,LIGHTV1_PTR lights,int max_lights )

{

    unsigned      int              r_base, g_base, b_base,         //原来的颜色值

                                         r_sum, g_sum,b_sum,             //全部光源的总体光照效果

                                         r_sum0, g_sum0,b_sum0,

                                         r_sum1, g_sum1,b_sum1,

                                         r_sum2, g_sum2,b_sum2,

                                         ri, gi,bi,

                                         shaded_color;                   //最后的颜色

    float                               dp,                                 //点积

                                         dist,                               //表面和光源之间的距离

                                         dists,

                                         i,                                  //强度

                                         nl,                                 //法线长度

                                         atten;                              //衰减计算结果

 

    VECTOR4D                        u, v,n, l, d, s;

    if ( ! ( obj->state &OBJECT4DV2_STATE_ACTIVE ) ||

        ( obj-> state &OBJECT4DV2_STATE_CULLED ) ||

        ! ( obj->state &OBJECT4DV2_STATE_VISIBLE))

    {

        return ( 0 );

    }

    for ( int poly = 0; poly < obj->num_polys; poly++)

    {

        POLY4DV2_PTR       curr_poly              = &obj->plist[poly];

        if ( ! ( curr_poly->state &POLY4DV2_STATE_ACTIVE) ||

             ( curr_poly->state &POLY4DV2_STATE_CLIPPED) ||

             ( curr_poly->state &POLY4DV2_STATE_BACKFACE ))

 

        {

             continue;

        }

        SET_BIT( curr_poly->state,POLY4DV2_STATE_LIT );

 

        //提取指向主列表的顶点索引

        int                vindex_0                   = curr_poly->vert[0];

        int                vindex_1                   = curr_poly->vert[1];

        int                vindex_2                   = curr_poly->vert[2];

 

        //检查多边形的着色模式

        if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_FLAT  )

        {

             //提取多边形颜色的RGB

        

                  _RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );

                  //转换成.8.8格式

                  r_base                                   <<= 3;

                  g_base                                   <<= 2;

                  b_base                                   <<= 3;

             

        

 

             //初始化总体光照颜色

             r_sum                                         = 0;

             g_sum                                         = 0;

             b_sum                                         = 0;

 

             n.z                                           = FLT_MAX;

 

             //遍历光照

             for ( int curr_light = 0; curr_light < max_lights; curr_light ++)

             {

                  //光源是否被打开

                  if ( lights[curr_light].state==LIGHTV1_STATE_OFF)

                  {

                      continue;

                  }

 

                  //判断光源类型

                  if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )

                  {

                      r_sum                               += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );

                      g_sum                               += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );

                      b_sum                               += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );

 

                  }

                  else

                      if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )

                      {

                           if( n.z ==FLT_MAX)

                           {

                                math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );

                                math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );

                                math.VECTOR4D_CROSS( &u, &v, &n );

 

                           }

        

                           nl                                  = curr_poly->nlength;

 

                           dp                                  = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );

 

                           if ( dp > 0 )

                           {

                                i                               = 128 * dp / nl;

                                r_sum                           += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                g_sum                           += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                b_sum                           += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                           }

 

 

                      }

                      else

                           if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )

                           {

                                if ( n.z ==FLT_MAX)

                                {

                                    math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );

                                    math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );

                                    math.VECTOR4D_CROSS( &u, &v, &n );

                                }

 

 

                                nl                                  = curr_poly->nlength;

 

                                //计算从表面到光源的向量

                                math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );

                                //计算距离和衰减

                                dist                            = math.VECTOR4D_length( &l);

 

 

                                dp                                  = math.VECTOR4D_DOT( &n, &l);

 

                                if ( dp > 0 )

                                {

                                    atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                    i                               = 128 * dp / ( nl * dist * atten );

                                    r_sum                           += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum                           += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum                           += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

 

 

                           }

                           else

                                if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )

                                {

                                    if (n.z ==FLT_MAX)

                                    {

                                         math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );

                                         math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );

                                         math.VECTOR4D_CROSS( &v, &u, &n );

 

                                    }

                                

                                    nl                                  = curr_poly->nlength;

 

                                    //计算从表面到光源的向量333

                                    math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );

                                    //计算距离和衰减

                                    dist                            = math.VECTOR4D_length( &l);

 

 

                                    dp                                  = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );

 

                                    if ( dp > 0 )

                                    {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( nl * atten );

                                         r_sum                           += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum                           += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum                           += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

 

 

                                }   

                                else

                                    if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )

                                    {

                                         if (n.z ==FLT_MAX )

                                         {

                                              math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_1].v, &u );

                                              math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &obj->vlist_trans[vindex_2].v, &v );

                                              math.VECTOR4D_CROSS( &v, &u, &n );

 

                                         }

    

                                         nl                                  = curr_poly->nlength;

                                         dp                                  = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              //计算从表面到光源的向量

                                              math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_0].v, &s );

                                              dists                           = math.VECTOR4D_length( &s);

 

                                              float    dpsl              = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                              if ( dpsl > 0)

                                              {

                                                   atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

                                                  float    dpsl_exp     = dpsl;

                                                  for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index++ )

                                                  {

                                                       dpsl              *= dpsl;

                                                  }

                                                  i                          = 128 * dp * dpsl_exp / ( nl * atten );

                                                  r_sum                      += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                  g_sum                      += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                  b_sum                      += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                              }

 

 

                                         }

 

 

                                    }   

             }

             //确保颜色分量不溢出

             if ( r_sum   > 255 )

             {

                  r_sum                                                  = 255;

 

             }

             if ( g_sum   > 255 )

             {

                  g_sum                                                  = 255;

 

             }

             if ( b_sum   > 255 )

             {

                  b_sum                                                  = 255;

 

             }

 

             //写入颜色

        

 

                  curr_poly->lit_color[0]                                = _RGB16BIT565( r_sum, g_sum, b_sum );

        

        }

        else

             if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_GOURAUD )

             {

                  //提取多边形颜色的RGB

 

                  _RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );

                  //转换成.8.8格式

                  r_base                                        <<= 3;

                  g_base                                        <<= 2;

                  b_base                                        <<= 3;

 

 

 

                  //初始化顶点的累积RGB

                  r_sum0                                        = 0;

                  g_sum0                                        = 0;

                  b_sum0                                        = 0;

 

                  r_sum1                                        = 0;

                  g_sum1                                        = 0;

                  b_sum1                                        = 0;

 

                  r_sum2                                        = 0;

                  g_sum2                                        = 0;

                  b_sum2                                        = 0;

 

 

                  //遍历光照

                  for ( int curr_light = 0; curr_light < max_lights; curr_light ++)

                  {

                      //光源是否被打开

                      if ( lights[curr_light].state==LIGHTV1_STATE_OFF)

                      {

                           continue;

                      }

 

                      //判断光源类型

                      if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )

                      {

                           ri                              += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );

                           gi                              += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );

                           bi                              += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );

 

                           //环境光源对每个顶点的影响相同

                           r_sum0                          += ri;

                           g_sum0                          += gi;

                           b_sum0                          += bi;

 

                           r_sum1                          += ri;

                           g_sum1                          += gi;

                           b_sum1                          += bi;

 

                           r_sum2                          += ri;

                           g_sum2                          += gi;

                           b_sum2                          += bi;

 

 

 

                      }

                      else

                           if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )

                           {

                      

 

                                //顶点

                                dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, &lights[curr_light].dir );

 

                                if ( dp > 0 )

                                {

                                    i                               = 128 * dp / nl;

                                    r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

                                //顶点

 

                                dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, &lights[curr_light].dir );

 

                                if ( dp > 0 )

                                {

                                    i                               = 128 * dp / nl;

                                    r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

                                //顶点

                                dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, &lights[curr_light].dir );

 

                                if ( dp > 0 )

                                {

                                     i                               = 128 * dp / nl;

                                    r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

                           }

                           else

                                if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )

                                {

                                    

                                    

 

                                    //计算从表面到光源的向量

                                    math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );

                                    //计算距离和衰减

                                    dist                            = math.VECTOR4D_length( &l);

 

 

                                    //顶点

                                    dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, & l);

 

                                    if ( dp > 0 )

                                    {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( dist * atten );

                                         r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

                                    //顶点

                                    dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, & l);

 

                                    if ( dp > 0 )

                                     {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( dist * atten );

                                         r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

                                    //顶点

                                    dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, & l);

 

                                    if ( dp > 0 )

                                    {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( dist * atten );

                                         r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

 

                                }

                                else

                                    if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )

                                    {

                                

 

                                         //计算从表面到光源的向量

                                         math.VECTOR4D_Build( &obj->vlist_trans[vindex_0].v, &lights[curr_light].pos, &l );

                                         //计算距离和衰减

                                         dist                            = math.VECTOR4D_length( &l);

 

                                         //顶点

 

                                         dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, & lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                              i                               = 128 * dp / ( atten );

                                              r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                              g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                              b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                         }

 

                                         //顶点

 

                                         dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, & lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                              i                               = 128 * dp / ( atten );

                                              r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                              g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                              b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                         }

                                         //顶点

 

                                         dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, & lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                              i                               = 128 * dp / ( atten );

                                              r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                              g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                              b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                         }

                                    }   

                                    else

                                         if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )

                                         {

 

 

                                              //顶点

 

                                              dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_0].n, & lights[curr_light].dir );

 

                                              if ( dp > 0 )

                                             {

                                                  math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_0].v, &s );

                                                  dists                           = math.VECTOR4D_length( &s );

                                                  float         dpsl         = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                                  if ( dpsl > 0)

                                                  {

                                                       atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

 

                                                       float    dpsl_exp     = dpsl;

                                                       for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )

                                                       {

                                                            dpsl_exp           *= dpsl;

                                                       }

                                                       i                          = 128 * dp * dpsl_exp / ( atten );

                                                       r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                       g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                       b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                                  }

    

 

                                              }

 

                                              //顶点

 

                                              dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_1].n, & lights[curr_light].dir );

 

                                              if ( dp > 0 )

                                              {

                                                  math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_1].v, &s );

                                                  dists                           = math.VECTOR4D_length( &s );

                                                  float         dpsl         = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                                  if ( dpsl > 0)

                                                  {

                                                       atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

 

                                                       float    dpsl_exp     = dpsl;

                                                       for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )

                                                       {

                                                            dpsl_exp           *= dpsl;

                                                       }

                                                       i                          = 128 * dp * dpsl_exp / ( atten );

                                                       r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                       g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                       b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                                  }

 

 

                                              }                                        

                                              //顶点

 

                                              dp                                  = math.VECTOR4D_DOT( &obj->vlist_trans[vindex_2].n, & lights[curr_light].dir );

 

                                              if ( dp > 0 )

                                              {

                                                  math.VECTOR4D_Build( &lights[curr_light].pos, &obj->vlist_trans[vindex_2].v, &s );

                                                  dists                           = math.VECTOR4D_length( &s );

                                                  float         dpsl         = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                                  if ( dpsl > 0)

                                                  {

                                                       atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

 

                                                       float    dpsl_exp     = dpsl;

                                                       for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )

                                                       {

                                                            dpsl_exp           *= dpsl;

                                                       }

                                                       i                          = 128 * dp * dpsl_exp / ( atten );

                                                       r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                       g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                       b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                                  }

 

 

                                              }

 

                                         }   

                  }

                  //确保颜色分量不溢出

                  if ( r_sum0  > 255 )

                  {

                      r_sum0                                                 = 255;

 

                  }

                  if ( g_sum0  > 255 )

                  {

                      g_sum0                                                 = 255;

 

                  }

                 if ( b_sum0   > 255 )

                  {

                      b_sum0                                                 = 255;

 

                  }

                  if ( r_sum1  > 255 )

                  {

                      r_sum1                                                 = 255;

 

                  }

                  if ( g_sum1  > 255 )

                  {

                      g_sum1                                                 = 255;

 

                  }

                  if ( b_sum1  > 255 )

                  {

                      b_sum1                                                 = 255;

 

                  }

                  if ( r_sum2  > 255 )

                  {

                      r_sum2                                                 = 255;

 

                  }

                  if ( g_sum2  > 255 )

                  {

                      g_sum2                                                 = 255;

 

                  }

                  if ( b_sum2  > 255 )

                  {

                      b_sum2                                                 = 255;

 

                  }

 

                  //写入颜色

 

 

                  curr_poly->lit_color[0]                                = _RGB16BIT565( r_sum0, g_sum0, b_sum0 );

                  curr_poly->lit_color[1]                                = _RGB16BIT565( r_sum1, g_sum1, b_sum1 );

                  curr_poly->lit_color[2]                                = _RGB16BIT565( r_sum2, g_sum2, b_sum2 );

 

             }

             else

             {

                  curr_poly->lit_color[0]                                = curr_poly->color;

             }

        

 

    }

    return ( 1 );

}

 

现在,看下渲染列表的。

先加个渲染列表版本2结构

 

 

typedefstruct RENDERLIST4DV2_TYP

{

    int                                 state;        //渲染列表的状态

    int                                 attr;         //渲染列表的属性

 

    POLYF4DV2_PTR                   poly_ptrs[RENDERLIST4DV2_MAX_POLYS];//索引缓存数组(多边形面)

    POLYF4DV2                       poly_data[RENDERLIST4DV2_MAX_POLYS];//顶点数组

 

    int                                 num_polys;    //渲染列表中包含的多边形数目

 

}RENDERLIST4DV2, *RENDERLIST4DV2_PTR;

 

 

 

intDDRAW_LIUSHUIXIAN_TEXTURE::Light_RENDERLIST4DV2_World16(ddraw_math math,int rgb_format,RENDERLIST4DV2_PTR rend_list, CAM4DV1_PTR cam, LIGHTV1_PTR lights, int max_lights )

{

    unsigned      int               r_base, g_base,b_base,          //原来的颜色值

                                         r_sum, g_sum,b_sum,             //全部光源的总体光照效果

                                         r_sum0, g_sum0,b_sum0,

                                         r_sum1, g_sum1,b_sum1,

                                         r_sum2, g_sum2,b_sum2,

                                         ri, gi,bi,

                                         shaded_color;                   //最后的颜色

    float                               dp,                                 //点积

                                         dist,                               //表面和光源之间的距离

                                         dists,

                                         i,                                  //强度

                                         nl,                                 //法线长度

                                         atten;                              //衰减计算结果

 

    VECTOR4D                        u, v,n, l, d, s;

    

    for ( int poly = 0; poly < rend_list->num_polys; poly++)

    {

        POLYF4DV2_PTR      curr_poly              = &rend_list->poly_ptrs[poly];

        if ( ! ( curr_poly->state &POLY4DV2_STATE_ACTIVE) ||

             ( curr_poly->state &POLY4DV2_STATE_CLIPPED) ||

             ( curr_poly->state &POLY4DV2_STATE_BACKFACE) ||

             ( curr_poly->state &POLY4DV2_STATE_LIT ))

 

        {

             continue;

        }

        SET_BIT( curr_poly->state,POLY4DV2_STATE_LIT );

 

    

        //检查多边形的着色模式

        if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_FLAT  )

        {

             //提取多边形颜色的RGB

 

             _RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );

             //转换成.8.8格式

             r_base                                   <<= 3;

             g_base                                   <<= 2;

             b_base                                   <<= 3;

 

 

 

             //初始化总体光照颜色

             r_sum                                         = 0;

             g_sum                                         = 0;

             b_sum                                         = 0;

 

             n.z                                           = FLT_MAX;

 

             //遍历光照

             for ( int curr_light = 0; curr_light < max_lights; curr_light ++)

             {

                  //光源是否被打开

                  if ( lights[curr_light].state==LIGHTV1_STATE_OFF)

                  {

                      continue;

                  }

 

                  //判断光源类型

                  if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )

                  {

                      r_sum                               += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );

                      g_sum                               += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );

                      b_sum                               += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );

 

                  }

                  else

                      if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )

                      {

                           if( n.z ==FLT_MAX)

                           {

                                math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );

                                math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );

                                math.VECTOR4D_CROSS( &u, &v, &n );

 

                           }

 

                           nl                                  = curr_poly->nlength;

 

                           dp                                  = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );

 

                           if ( dp > 0 )

                           {

                                i                               = 128 * dp / nl;

                                r_sum                           += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                g_sum                           += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                b_sum                           += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                           }

 

 

                      }

                      else

                           if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )

                           {

                                if ( n.z ==FLT_MAX)

                                {

                                    math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );

                                    math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );

 

                                    math.VECTOR4D_CROSS( &u, &v, &n );

                                }

 

 

                                nl                                  = curr_poly->nlength;

 

                                //计算从表面到光源的向量

                                math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );

                                //计算距离和衰减

                                dist                            = math.VECTOR4D_length( &l);

 

 

                                dp                                  = math.VECTOR4D_DOT( &n, &l);

 

                                if ( dp > 0 )

                                {

                                    atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                    i                               = 128 * dp / ( nl * dist * atten );

                                    r_sum                           += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum                           += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum                           += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

 

 

                           }

                           else

                                if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )

                                {

                                    if (n.z ==FLT_MAX)

                                    {

                                         math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );

                                         math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );

                                         math.VECTOR4D_CROSS( &u, &v, &n );

 

                                    }

 

                                    nl                                  = curr_poly->nlength;

 

                                    //计算从表面到光源的向量

                                    math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );

                                    //计算距离和衰减

                                    dist                            = math.VECTOR4D_length( &l);

 

 

                                    dp                                  = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );

 

                                    if ( dp > 0 )

                                    {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( nl * atten );

                                         r_sum                           += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum                           += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum                           += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

 

 

                                }   

                                else

                                    if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )

                                    {

                                         if (n.z ==FLT_MAX )

                                         {

                                              math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[1].v, &u );

                                              math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &curr_poly->tvlist[2].v, &v );

                                              math.VECTOR4D_CROSS( &u, &v, &n );

 

                                         }

 

                                         nl                                  = curr_poly->nlength;

                                         dp                                  = math.VECTOR4D_DOT( &n, &lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              //计算从表面到光源的向量

                                              math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[0].v, &s );

                                              dists                           = math.VECTOR4D_length( &s);

 

                                              float    dpsl              = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                              if ( dpsl > 0)

                                              {

                                                  atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

                                                  float    dpsl_exp     = dpsl;

                                                  for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index++ )

                                                  {

                                                       dpsl               *= dpsl;

                                                  }

                                                  i                          = 128 * dp * dpsl_exp / ( nl * atten );

                                                  r_sum                      += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                  g_sum                      += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                  b_sum                      += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                              }

 

 

                                         }

 

 

                                    }   

             }

             //确保颜色分量不溢出

             if ( r_sum   > 255 )

             {

                  r_sum                                                  = 255;

 

             }

             if ( g_sum   > 255 )

             {

                  g_sum                                                  = 255;

 

             }

             if ( b_sum   > 255 )

             {

                  b_sum                                                  = 255;

 

             }

 

             //写入颜色

 

 

             curr_poly->lit_color[0]                                = _RGB16BIT565( r_sum, g_sum, b_sum );

 

        }

        else

             if ( curr_poly->attr &POLY4DV2_ATTR_SHADE_MODE_GOURAUD )

             {

                  //提取多边形颜色的RGB

 

                  _RGB565FROM16BIT( curr_poly->color, & r_base, & g_base, & b_base );

                  //转换成.8.8格式

                  r_base                                        <<= 3;

                  g_base                                        <<= 2;

                  b_base                                        <<= 3;

 

 

 

                  //初始化顶点的累积RGB

                  r_sum0                                        = 0;

                  g_sum0                                        = 0;

                  b_sum0                                        = 0;

 

                  r_sum1                                        = 0;

                  g_sum1                                        = 0;

                  b_sum1                                        = 0;

 

                  r_sum2                                        = 0;

                  g_sum2                                        = 0;

                  b_sum2                                        = 0;

 

 

                  //遍历光照

                  for ( int curr_light = 0; curr_light < max_lights; curr_light ++)

                  {

                      //光源是否被打开

                      if ( lights[curr_light].state==LIGHTV1_STATE_OFF)

                      {

                           continue;

                      }

 

                      //判断光源类型

                      if ( lights[curr_light].attr &LIGHTV1_ATTR_AMBIENT )

                      {

                           ri                              += ( ( lights[curr_light].c_ambient.r *r_base) / 256 );

                           gi                              += ( ( lights[curr_light].c_ambient.g *g_base) / 256 );

                           bi                              += ( ( lights[curr_light].c_ambient.b *b_base) / 256 );

 

                           //环境光源对每个顶点的影响相同

                           r_sum0                          += ri;

                           g_sum0                          += gi;

                           b_sum0                          += bi;

 

                           r_sum1                          += ri;

                           g_sum1                          += gi;

                           b_sum1                          += bi;

 

                           r_sum2                          += ri;

                           g_sum2                          += gi;

                           b_sum2                          += bi;

 

 

 

                      }

                      else

                           if ( lights[curr_light].attr &LIGHTV1_ATTR_INFINITE )

                           {

 

 

                                //顶点

                                dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &lights[curr_light].dir );

 

                                if ( dp > 0 )

                                {

                                    i                               = 128 * dp;

                                    r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

                                //顶点

 

                                dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &lights[curr_light].dir );

 

                                if ( dp > 0 )

                                {

                                    i                               = 128 * dp;

                                    r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

                                //顶点

                                dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &lights[curr_light].dir );

 

                                if ( dp > 0 )

                                {

                                    i                               = 128 * dp ;

                                    r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                    g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                    b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                }

                           }

                           else

                                if ( lights[curr_light].attr &LIGHTV1_ATTR_POINT )

                                {

 

 

 

                                    //计算从表面到光源的向量

                                    math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );

                                    //计算距离和衰减

                                    dist                            = math.VECTOR4D_length( &l);

 

 

                                    //顶点

                                    dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &l);

 

                                    if ( dp > 0 )

                                    {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( dist * atten );

                                         r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

                                    //顶点

                                    dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &l);

 

                                    if ( dp > 0 )

                                    {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( dist * atten );

                                         r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

                                    //顶点

                                    dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &l);

 

                                    if ( dp > 0 )

                                    {

                                         atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                         i                               = 128 * dp / ( dist * atten );

                                         r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                         g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                         b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                    }

 

                                }

                                else

                                    if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT1 )

                                    {

 

 

                                         //计算从表面到光源的向量

                                         math.VECTOR4D_Build( &curr_poly->tvlist[0].v, &lights[curr_light].pos, &l );

                                         //计算距离和衰减

                                         dist                            = math.VECTOR4D_length( &l);

 

                                         //顶点

 

                                         dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                              i                               = 128 * dp / ( atten );

                                              r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                              g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                              b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                         }

 

                                         //顶点

 

                                         dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                              i                               = 128 * dp / ( atten );

                                              r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                              g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                              b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                         }

                                         //顶点

 

                                         dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &lights[curr_light].dir );

 

                                         if ( dp > 0 )

                                         {

                                              atten                           = ( lights[curr_light].kc +lights[curr_light].kl *dist + lights[curr_light].kq *dist * dist );

                                              i                               = 128 * dp / ( atten );

                                              r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                              g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                              b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

 

                                         }

                                    }   

                                    else

                                         if ( lights[curr_light].attr &LIGHTV1_ATTR_SPOTLIGHT2 )

                                         {

 

 

                                              //顶点

 

                                              dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[0].n, &lights[curr_light].dir );

 

                                              if ( dp > 0 )

                                              {

                                                  math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[0].v, &s );

                                                  dists                           = math.VECTOR4D_length( &s );

                                                  float         dpsl         = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                                  if ( dpsl > 0)

                                                  {

                                                       atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

 

                                                       float    dpsl_exp     = dpsl;

                                                       for (int e_index = 1;e_index < ( int )lights[curr_light].pf;e_index ++ )

                                                       {

                                                            dpsl_exp           *= dpsl;

                                                       }

                                                       i                          = 128 * dp * dpsl_exp / ( atten );

                                                       r_sum0                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                       g_sum0                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                       b_sum0                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                                  }

 

 

                                              }

 

                                             //顶点

 

                                              dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[1].n, &lights[curr_light].dir );

 

                                              if ( dp > 0 )

                                              {

                                                  math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[1].v, &s );

                                                  dists                           = math.VECTOR4D_length( &s );

                                                  float         dpsl         = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                                  if ( dpsl > 0)

                                                  {

                                                       atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

 

                                                       float    dpsl_exp     = dpsl;

                                                       for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )

                                                       {

                                                            dpsl_exp           *= dpsl;

                                                       }

                                                       i                          = 128 * dp * dpsl_exp / ( atten );

                                                       r_sum1                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                       g_sum1                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                       b_sum1                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                                  }

 

 

                                              }                                        

                                              //顶点

 

                                              dp                                  = math.VECTOR4D_DOT( &curr_poly->tvlist[2].n, &lights[curr_light].dir );

 

                                              if ( dp > 0 )

                                              {

                                                  math.VECTOR4D_Build( &lights[curr_light].pos, &curr_poly->tvlist[2].v, &s );

                                                  dists                           = math.VECTOR4D_length( &s );

                                                  float         dpsl         = math.VECTOR4D_DOT( &s, & lights[curr_light].dir ) /dists;

 

                                                  if ( dpsl > 0)

                                                  {

                                                       atten                      = ( lights[curr_light].kc +lights[curr_light].kl *dists + lights[curr_light].kq *dists * dists );

 

                                                       float    dpsl_exp     = dpsl;

                                                       for ( int e_index = 1; e_index < ( int ) lights[curr_light].pf;e_index ++ )

                                                       {

                                                            dpsl_exp         *= dpsl;

                                                       }

                                                       i                          = 128 * dp * dpsl_exp / ( atten );

                                                       r_sum2                          += (  lights[curr_light].c_diffuse.r *r_base * i ) / ( 256 * 128);

                                                       g_sum2                          += (  lights[curr_light].c_diffuse.g *g_base * i ) / ( 256 * 128);

                                                       b_sum2                          += (  lights[curr_light].c_diffuse.b *b_base * i ) / ( 256 * 128);

                                                  }

 

 

                                              }

 

                                         }   

                  }

                  //确保颜色分量不溢出

                  if ( r_sum0  > 255 )

                  {

                      r_sum0                                                 = 255;

 

                  }

                  if ( g_sum0  > 255 )

                  {

                      g_sum0                                                 = 255;

 

                  }

                  if ( b_sum0  > 255 )

                  {

                      b_sum0                                                 = 255;

 

                  }

                  if ( r_sum1  > 255 )

                  {

                      r_sum1                                                 = 255;

 

                  }

                  if ( g_sum1  > 255 )

                  {

                      g_sum1                                                 = 255;

 

                  }

                  if ( b_sum1  > 255 )

                  {

                      b_sum1                                                 = 255;

 

                  }

                  if ( r_sum2  > 255 )

                  {

                      r_sum2                                                 = 255;

 

                  }

                  if ( g_sum2  > 255 )

                  {

                      g_sum2                                                 = 255;

 

                  }

                  if ( b_sum2  > 255 )

                  {

                      b_sum2                                                 = 255;

 

                  }

 

                  //写入颜色

 

 

                  curr_poly->lit_color[0]                                = _RGB16BIT565( r_sum0, g_sum0, b_sum0 );

                  curr_poly->lit_color[1]                                = _RGB16BIT565( r_sum1, g_sum1, b_sum1 );

                  curr_poly->lit_color[2]                                = _RGB16BIT565( r_sum2, g_sum2, b_sum2 );

 

             }

             else

             {

                  curr_poly->lit_color[0]                                = curr_poly->color;

             }

 

 

    }

    return ( 1 );

}    

 

现在从头到尾弄下吧,遇到啥算啥。

#define                             SPOT_LIGHT1_INDEX  4

#define                                                              SPOT_LIGHT2_INDEX  3

摄像机位置改变下

POINT4D cam_pos = {0,0,0,1};

GAME_INIT()初始化中,

    liushuixian.Init_CAM4DV1( &cam, CAM_MODEL_EULER, &cam_pos, & cam_dir, &cam_target, 200.0, 12000.0, 120.0, SCREEN_WIDTH, SCREEN_HEIGHT );

    math->VECTOR4D_INITXYZ( &vscale, 10.00, 10.00, 10.00 );

 

接下来加载新版本的.COB模型,可以看到,多了个mipmap的生成(可选)。新增了加载和识别纹理的功能,目前只支持1个纹理。

 

首先加上个提取文件名函数

 

char *DDRAW_LIUSHUIXIAN_TEXTURE::Extract_Filename_From_Path(char * filepath,char * filename )

{

if( !filepath || strlen(filepath ) == 0 )

return (NULL );

 

intindex_end      = strlen( filepath ) - 1;

 

//查找文件名

while( (filepath[index_end] !='\\' ) && ( filepath[index_end] !='/' ) && ( filepath[index_end] > 0 ) )

index_end --;

 

//将文件名复制到变量filename

memcpy(filename, & filepath[index_end + 1 ],strlen( filepath ) -index_end );

 

returnfilename;

}

 

重置列表

 

voidDDRAW_LIUSHUIXIAN_TEXTURE::Reset_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list)

{

    rend_list->num_polys                                        = 0;     // 渲染的多边形数,默认为0

}

重置物体

 

voidDDRAW_LIUSHUIXIAN_TEXTURE::Reset_OBJECT4DV2(OBJECT4DV2_PTR obj )

{

    RESET_BIT( obj->state, OBJECT4DV2_STATE_CULLED);

 

    for( int poly = 0; poly < obj->num_polys; poly ++ )

    {

        POLY4DV2_PTR       curr_poly              = &obj->plist[poly];

        if ( ! curr_poly->state &POLY4DV2_STATE_ACTIVE)

        {

             continue;

        }

        RESET_BIT( curr_poly->state, POLY4DV2_STATE_CLIPPED );

        RESET_BIT( curr_poly->state, POLY4DV2_STATE_BACKFACE );

        RESET_BIT( curr_poly->state, POLY4DV2_STATE_LIT );

 

    }

 

 

}

转换

 

 

voidDDRAW_LIUSHUIXIAN_TEXTURE::Transform_OBJECT4DV2(OBJECT4DV2_PTRobj,

                                                             MATRIX4X4_PTR mt,          //变换矩阵

                                                             int coord_select,

                                                             int transform_basis,

                                                             int all_frames,

                                                             ddraw_math math2 )              //指定要变换的坐标

{

    if( ! all_frames )

    {

 

        switchcoord_select )

        {

        case TRANSFORM_LOCAL_ONLY:

             {

                  //对物体的每个局部/模型顶点坐标进行变换

                  for( int vertex = 0; vertex < obj->num_vertices; vertex++ )

                  {

 

                      POINT4D            presult;      //用于暂时存储变换结果

                      math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].v,mt, & presult );

                      math2.VECTOR4D_COPY( &obj->vlist_local[vertex].v, &presult );

 

                      if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )

                      {

                           math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].n,mt, & presult );

                           math2.VECTOR4D_COPY( &obj->vlist_local[vertex].n, &presult );

                      }

 

 

                  }

             }

             break;

 

        case TRANSFORM_TRANS_ONLY:

             {

 

                  for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )

                  {

                      //使用矩阵mt对顶点进行变换

                      POINT4D            presult;      //用于暂时存储变换结果

                      math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_trans[vertex].v,mt, & presult );

                      math2.VECTOR4D_COPY( &obj->vlist_trans[vertex].v, &presult );

                      if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )

                      {

                           math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].n,mt, & presult );

                           math2.VECTOR4D_COPY( &obj->vlist_local[vertex].n, &presult );

                      }

                  }

 

             }

             break;

 

        case TRANSFORM_LOCAL_TO_TRANS:

             {

                  for( int vertex = 0; vertex < obj->num_vertices; vertex++ )

                  {

                      POINT4D            presult;      //用于暂时存储变换结果

 

                      //使用矩阵mt对顶点进行变换

                      math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].v,mt, & obj->vlist_trans[vertex].v );

                      if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )

                      {

                           math2.Mat_Mul_VECTOR4D_4X4( &obj->vlist_local[vertex].n,mt, & presult );

                           math2.VECTOR4D_COPY( &obj->vlist_local[vertex].n, &presult );

                      }

                  }

             }

             break;

 

        default:

             break;

        }

    }

    else

    {

        switchcoord_select )

        {

        case TRANSFORM_LOCAL_ONLY:

             {

                  //对物体的每个局部/模型顶点坐标进行变换

                  for( int vertex = 0; vertex < obj->num_vertices; vertex++ )

                  {

 

                      POINT4D            presult;      //用于暂时存储变换结果

                      math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].v,mt, & presult );

                      math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].v, &presult );

 

                      if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )

                      {

                           math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].n,mt, & presult );

                           math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &presult );

                      }

 

 

                  }

             }

             break;

 

        case TRANSFORM_TRANS_ONLY:

             {

 

                  for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )

                  {

                      //使用矩阵mt对顶点进行变换

                      POINT4D            presult;      //用于暂时存储变换结果

                      math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].v,mt, & presult );

                      math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].v, &presult );

                      if( obj->vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )

                      {

                           math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].n,mt, & presult );

                           math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &presult );

                      }

                  }

 

             }

             break;

 

        case TRANSFORM_LOCAL_TO_TRANS:

             {

                  for( int vertex = 0; vertex < obj->num_vertices; vertex++ )

                  {

                      POINT4D            presult;      //用于暂时存储变换结果

 

                      //使用矩阵mt对顶点进行变换

                      math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].v,mt, & obj->vlist_trans[vertex].v );

                      if( obj->head_vlist_local[vertex].attr &VERTEX4DTV1_ATTR_NORMAL )

                      {

                           math2.Mat_Mul_VECTOR4D_4X4( &obj->head_vlist_local[vertex].n,mt, & presult );

                           math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &presult );

                      }

                  }

             }

             break;

 

        default:

             break;

        }

    }

 

 

    //最后检查是否对朝向向量进行变换

    if ( transform_basis)

    {

        //旋转物体的朝向向量

        VECTOR4D           vresult;               //用于存储旋转结果

        //旋转ux

        math2.Mat_Mul_VECTOR4D_4X4( &obj->ux, mt, & vresult );

        math2.VECTOR4D_COPY( &obj->ux, & vresult );

 

        //旋转uy

        math2.Mat_Mul_VECTOR4D_4X4( &obj->uy, mt, & vresult );

        math2.VECTOR4D_COPY( &obj->uy, & vresult );

        //旋转uz

        math2.Mat_Mul_VECTOR4D_4X4( &obj->uz, mt, & vresult );

        math2.VECTOR4D_COPY( &obj->uz, & vresult );

            

 

    }

 

 

 

}

 

 

模型坐标系转换到世界坐标系

voidDDRAW_LIUSHUIXIAN_TEXTURE::Model_To_World_OBJECT4DV2(OBJECT4DV2_PTR objddraw_math math2,int coord_select,int all_frames )

{

 

 

    if( ! all_frames )

    {

        if( coord_select ==TRANSFORM_LOCAL_TO_TRANS )

        {

             //满足条件,对其进行变换

             for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )

             {

                  //平移顶点

                  math2.VECTOR4D_ADD( &obj->vlist_local[vertex].v, &obj->world_pos, &obj->vlist_trans[vertex].v );

                  math2.VECTOR4D_COPY( &obj->vlist_trans[vertex].n, &obj->vlist_local[vertex].n );

             }

 

        }

        else

        {

 

             for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )

             {

                  //平移顶点

                  math2.VECTOR4D_ADD( &obj->vlist_trans[vertex].v, &obj->world_pos, &obj->vlist_trans[vertex].v );

             }

        }

 

    }

    else

    {

        if( coord_select ==TRANSFORM_LOCAL_TO_TRANS )

        {

             //满足条件,对其进行变换

             for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )

             {

                  //平移顶点

                  math2.VECTOR4D_ADD( &obj->head_vlist_local[vertex].v, &obj->world_pos, &obj->head_vlist_local[vertex].v );

                  math2.VECTOR4D_COPY( &obj->head_vlist_local[vertex].n, &obj->head_vlist_local[vertex].n );

             }

 

        }

        else

        {

 

             for( int vertex = 0; vertex < obj->num_vertices; vertex ++ )

             {

                  //平移顶点

                  math2.VECTOR4D_ADD( &obj->head_vlist_local[vertex].v, &obj->world_pos, &obj->head_vlist_local[vertex].v );

             }

        }

 

    }

 

 

 

}

 

 

 

 

intDDRAW_LIUSHUIXIAN_TEXTURE::Insert_OBJECT4DV2_RENDERLIST4DV2(ddraw_mathmath, RENDERLIST4DV2_PTRrend_list, OBJECT4DV2_PTRobj, int insert_local = 0 )

{

    unsigned intbase_color;

 

    if ( ! ( obj->state &OBJECT4DV2_STATE_ACTIVE ) ||

        ( obj-> state &OBJECT4DV2_STATE_CULLED ) ||

        ! ( obj->state &OBJECT4DV2_STATE_VISIBLE))

    {

        return ( 0 );

    }

    for ( int poly = 0; poly < obj->num_polys; poly++)

    {

        POLY4DV2_PTR       curr_poly              = &obj->plist[poly];

        if ( ! ( curr_poly->state &POLY4DV2_STATE_ACTIVE) ||

             ( curr_poly->state &POLY4DV2_STATE_CLIPPED) ||

             ( curr_poly->state &POLY4DV2_STATE_BACKFACE ))

 

        {

             continue;

        }

        VERTEX4DTV1_PTR            vlist_old              = curr_poly->vlist;

        if ( insert_local )

        {

             curr_poly->vlist                         = obj->vlist_local;

 

        }

        else

        {

             curr_poly->vlist                         = obj->vlist_trans;

        }

        if ( ! Insert_POLY4DV2_RENDERLIST4DV2(rend_list, curr_poly,math))

        {

             curr_poly->vlist                         = vlist_old;

             return ( 0 );

 

        }

        curr_poly->vlist                              = vlist_old;

 

    }

    return ( 1 );

 

}

 

向列表插入顶点

intDDRAW_LIUSHUIXIAN_TEXTURE::Insert_POLY4DV2_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, POLY4DV2_PTRpoly, ddraw_mathmath)

{

    if( rend_list->num_polys >=RENDERLIST4DV2_MAX_POLYS )

        return ( 0 );

 

    rend_list->poly_ptrs[rend_list->num_polys]                  = &rend_list->poly_data[rend_list->num_polys];

 

    rend_list->poly_data[rend_list->num_polys].state       = poly->state;

    rend_list->poly_data[rend_list->num_polys].attr             = poly->attr;

    rend_list->poly_data[rend_list->num_polys].color       = poly->color;

    rend_list->poly_data[rend_list->num_polys].nlength     = poly->nlength;

    rend_list->poly_data[rend_list->num_polys].texture     = poly->texture;

 

    rend_list->poly_data[rend_list->num_polys].lit_color[0]=    poly->lit_color[0];

    rend_list->poly_data[rend_list->num_polys].lit_color[1]=    poly->lit_color[1];

    rend_list->poly_data[rend_list->num_polys].lit_color[2]=    poly->lit_color[2];

 

 

    VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].tvlist[0], &poly->vlist[poly->vert[0]] );

    VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].tvlist[1], &poly->vlist[poly->vert[1]] );

    VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].tvlist[2], &poly->vlist[poly->vert[2]] );

 

    VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].vlist[0], &poly->vlist[poly->vert[0]] );

    VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].vlist[1], &poly->vlist[poly->vert[1]] );

    VERTEX4DTV1_COPY( & rend_list->poly_data[rend_list->num_polys].vlist[2], &poly->vlist[poly->vert[2]] );

 

    rend_list->poly_data[rend_list->num_polys].tvlist[0].t          = poly->tlist[poly->text[0]];

    rend_list->poly_data[rend_list->num_polys].tvlist[1].t          = poly->tlist[poly->text[1]];

    rend_list->poly_data[rend_list->num_polys].tvlist[2].t          = poly->tlist[poly->text[2]];

 

    rend_list->poly_data[rend_list->num_polys].vlist[0].t           = poly->tlist[poly->text[0]];

    rend_list->poly_data[rend_list->num_polys].vlist[1].t           = poly->tlist[poly->text[1]];

    rend_list->poly_data[rend_list->num_polys].vlist[2].t           = poly->tlist[poly->text[2]];

 

    if( rend_list->num_polys == 0 )

    {

        rend_list->poly_data[0].next                           = NULL;

        rend_list->poly_data[0].prev                           = NULL;

    }

    else

    {

        rend_list->poly_data[rend_list->num_polys].next        = NULL;

        rend_list->poly_data[rend_list->num_polys].prev        = & rend_list->poly_data[rend_list->num_polys-1];

        rend_list->poly_data[rend_list->num_polys-1].next = & rend_list->poly_data[rend_list->num_polys];

 

    }

    rend_list->num_polys++;

 

    return ( 1 );

}

 

 

去除背面

voidDDRAW_LIUSHUIXIAN_TEXTURE::Remove_Backfaces_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam, ddraw_mathmath )

{

 

    // process each poly in mesh

    for (int poly=0; poly < rend_list->num_polys; poly++)

    {

        // acquire polygon

        POLYF4DV2_PTR curr_poly = rend_list->poly_ptrs[poly];

 

        // is this polygon valid?

        // test this polygon if and only if it's not clipped, not culled,

        // active, and visible and not 2 sided. Note we test for backface in the event that

        // a previous call might have already determined this, so why work

        // harder!

        if ( ( curr_poly ==NULL) ||

             !(curr_poly->state &POLY4DV2_STATE_ACTIVE) ||

             (curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||

             (curr_poly->attr & POLY4DV2_ATTR_2SIDED)   ||

             (curr_poly->state &POLY4DV2_STATE_BACKFACE) )

        {

 

             continue;

        }

 

 

 

        VECTOR4D u,v, n;

 

        // build u, v

        math.VECTOR4D_Build(&curr_poly->tvlist[0].v,&curr_poly->tvlist[1].v, &u);

        math.VECTOR4D_Build(&curr_poly->tvlist[0].v,&curr_poly->tvlist[2].v, &v);

 

        // compute cross product

        math.VECTOR4D_CROSS(&u, &v, &n);

 

        // now create eye vector to viewpoint

        VECTOR4D view;

        math.VECTOR4D_Build(&curr_poly->tvlist[0].v, &cam->pos, &view);

 

        // and finally, compute the dot product

        float dp =math.VECTOR4D_DOT(&n, &view);

 

        // if the sign is > 0 then visible, 0 = scathing, < 0 invisible

        if (dp <= 0.0 )

             SET_BIT(curr_poly->state,POLY4DV2_STATE_BACKFACE);

 

 

    } // end for poly

 

}// end Remove_Backfaces_OBJECT4DV1

 

 

//世界坐标系到摄像机坐标系

voidDDRAW_LIUSHUIXIAN_TEXTURE::World_To_Camera_RENDERLIST4DV2(ddraw_math math2,RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam)

{

    for( int poly = 0; poly < rend_list->num_polys; poly++ )

    {

        //获得当前多边形

        POLYF4DV2_PTR      curr_poly              =rend_list->poly_ptrs[poly];

 

        //当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)

        if( ( curr_poly ==NULL ) ||

             !( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||

             ( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||

             ( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )

             continue; //进入下一个多边形

 

        //满足条件,对其进行变换

        for( int vertex = 0; vertex < 3; vertex ++ )

        {

             //使用相机对象中的矩阵mcma对顶点进行变换

             POINT4D            presult;      //用于存储每次变换的结果

             //对顶点进行变换

             math2.Mat_Mul_VECTOR4D_4X4( &curr_poly->tvlist[vertex].v, &cam->mcam, &presult );

             //将结果存回去

             math2.VECTOR4D_COPY( &curr_poly->tvlist[vertex].v, &presult );

        }

    }

}

 

同样,更改Z排序

 

voidSort_RENDERLIST4DV2( RENDERLIST4DV2_PTR rend_list, int sort_method = SORT_POLYLIST_AVGZ )

{

    switch( sort_method )

    {

    case SORT_POLYLIST_AVGZ:

        {

             qsort( ( void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof( POLYF4DV2_PTR ),Compare_AvgZ_PolyF4DV2 );

        }

        break;

    case SORT_POLYLIST_NEARZ:

        {

             qsort( ( void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof( POLYF4DV2_PTR ),Compare_NearZ_PolyF4DV2);

        }

        break;

    case SORT_POLYLIST_FARZ:

        {

             qsort( ( void *)rend_list->poly_ptrs,rend_list->num_polys,sizeof( POLYF4DV2_PTR ),Compare_FarZ_PolyF4DV2 );

        }

        break;

 

    default:

        break;

    }

}

 

intCompare_AvgZ_PolyF4DV2( const void * arg1,const void * arg2 )

{

    float                  z1, z2;

    POLYF4DV2_PTR      poly_1, poly_2;

 

    poly_1                                        = * ( ( POLYF4DV2_PTR * ) ( arg1 ));

    poly_2                                        = * ( ( POLYF4DV2_PTR * ) ( arg2 ));

 

    z1                                            = ( float ) 0.33333 * ( poly_1->tvlist[0].z +poly_1->tvlist[1].z +poly_1->tvlist[2].z );

    z2                                            = ( float ) 0.33333 * ( poly_2->tvlist[0].z +poly_2->tvlist[1].z +poly_2->tvlist[2].z );

 

    if ( z1 >z2 )

    {

        return -1;

    }

    else

        if ( z1 <z2)

        {

             return 1;

        }

        else

        {

             return 0;

        }

 

 

}

intCompare_NearZ_PolyF4DV2( const void * arg1,const void * arg2 )

{

    float                  z1, z2;

    POLYF4DV2_PTR      poly_1, poly_2;

 

    poly_1                                        = * ( ( POLYF4DV2_PTR * ) ( arg1 ));

    poly_2                                        = * ( ( POLYF4DV2_PTR * ) ( arg2 ));

 

    z1                                            = MIN( poly_1->tvlist[0].z,poly_1->tvlist[1].z );

    z1                                            = MIN( z1,poly_1->tvlist[2].z );

    z2                                            = MIN( poly_2->tvlist[0].z,poly_2->tvlist[1].z );

    z2                                            = MIN( z2,poly_2->tvlist[2].z );

 

    if ( z1 >z2 )

    {

        return -1;

    }

    else

        if ( z1 <z2)

        {

             return 1;

        }

        else

        {

             return 0;

        }

 

 

}

intCompare_FarZ_PolyF4DV2( const void * arg1,const void * arg2 )

{

    float                  z1, z2;

    POLYF4DV2_PTR      poly_1, poly_2;

 

    poly_1                                        = * ( ( POLYF4DV2_PTR * ) ( arg1 ));

    poly_2                                        = * ( ( POLYF4DV2_PTR * ) ( arg2 ));

 

    z1                                            = MAX( poly_1->tvlist[0].z,poly_1->tvlist[1].z );

    z1                                            = MAX( z1,poly_1->tvlist[2].z );

    z2                                            = MAX( poly_2->tvlist[0].z,poly_2->tvlist[1].z );

    z2                                            = MAX( z2,poly_2->tvlist[2].z );

 

    if ( z1 >z2 )

    {

        return -1;

    }

    else

        if ( z1 <z2)

        {

             return 1;

        }

        else

        {

             return 0;

        }

 

 

}

 

相应的摄像机坐标系到投影坐标系

 

voidDDRAW_LIUSHUIXIAN_TEXTURE::Camera_To_Perspective_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam)

{

    for( int poly = 0; poly < rend_list->num_polys; poly++ )

    {

        //获得当前多边形

        POLYF4DV2_PTR      curr_poly              =rend_list->poly_ptrs[poly];

 

        //当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)

        if( ( curr_poly ==NULL ) ||

             !( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||

             ( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||

             ( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )

             continue; //进入下一个多边形

 

        //满足条件,对其进行变换

        for( int vertex = 0; vertex < 3; vertex ++ )

        {

             float              z                          = curr_poly->tvlist[vertex].z;

 

             //根据相机的观察参数对顶点进行变换

             curr_poly->tvlist[vertex].x              = cam->view_dist *curr_poly->tvlist[vertex].x /z;

             curr_poly->tvlist[vertex].y              = cam->view_dist *curr_poly->tvlist[vertex].y *cam->aspect_ratio /z;

        }

    }

 

}

 

 

投影坐标系到屏幕坐标系

 

voidDDRAW_LIUSHUIXIAN_TEXTURE::Perspective_To_Screen_RENDERLIST4DV2(RENDERLIST4DV2_PTRrend_list, CAM4DV1_PTRcam)

{

    for( int poly = 0; poly < rend_list->num_polys; poly++ )

    {

        //获得当前多边形

        POLYF4DV2_PTR      curr_poly              =rend_list->poly_ptrs[poly];

 

        //当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)

        if( ( curr_poly ==NULL ) ||

             !( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||

             ( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||

             ( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )

             continue; //进入下一个多边形

 

        float                  alpha                       = ( 0.5 * cam->viewport_width - 0.5 );

        float                  beta                   = ( 0.5 *cam->viewport_height - 0.5 );

        //满足条件,对其进行变换

        for( int vertex = 0; vertex < 3; vertex ++ )

        {

             //顶点的透视坐标是归一化的,取值范围为-1到,对坐标进行缩放,并反转Y

             curr_poly->tvlist[vertex].x              = alpha + alpha *curr_poly->tvlist[vertex].x;

             curr_poly->tvlist[vertex].y              = beta - beta *curr_poly->tvlist[vertex].y;

        }

    }

}

GOURAUD类似,用纹理代替颜色值

voidddraw_math::Draw_Textured_Triangle16(POLYF4DV2_PTR face,UCHAR * _dest_buffer,int mem_pitch )

{

    int                    v0 = 0, v1 = 1,v2 = 2, temp = 0,tri_type = TRI_TYPE_NONE,irestartINTERP_LHS;

 

    int                    dx, dy, dyl, dyr,      //存储差值

        u, v,                 //UV

        du, dv

        xi, yi,                    //当前的xy坐标

        ui,vi,                //当前的UV

        index_x, index_y,     //循环变量

        x, y,                      //存储一般性XY坐标

        xstart, xend,ystart,yrestart, yend,xl,

        dxdyl, xr,dxdyr, dudyl,ul, dvdyl, vl,

        dudyr, ur,dvdyr, vr;

 

    int                    x0, y0, tu0, tv0, //顶点的初始颜色

        x1, y1,tu1, tv1,

        x2, y2,tu2, tv2

 

    USHORT        *       screen_ptr                      = NULL,

        *        screen_line                     = NULL,

        *        textmap                         = NULL,

        *        dest_buffer                     = (USHORT * )_dest_buffer;

 

    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,

 

    };

 

 

    //提取纹理图

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

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

 

    //将内存跨距的单位调整为字

    mem_pitch                                         >>= 1;

 

    //判断三角形是否在屏幕内

    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;

    }

 

    //判断三角形是否退化为直线

    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;

    }

 

    //对顶点进行排序

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

    }

 

 

    //判断三角形是否平顶

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

    {

        //设置三角形类型

        tri_type                        = TRI_TYPE_FLAT_TOP;

        //将顶点从左到右的顺序排列

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

        {

             SWAP( v0,v1, temp );

        }

    }

    else

        //判断三角形是否平底

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

        {

             //设置三角形类型

             tri_type                        = TRI_TYPE_FLAT_BOTTOM;

             //将顶点从左到右的顺序排列

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

             {

                  SWAP( v1,v2, temp );

             }

        }

        else

             //肯定是常规三角形

        {

             tri_type                        = TRI_TYPE_GENERAL;

        }

 

 

 

        //提取各个顶点的坐标值和RGB

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

 

        //设置斜率转折点

        yrestart                            = y1;

 

        //判断三角形类型

        if ( tri_type &TRI_TYPE_FLAT_MASK )

        {

             if ( tri_type ==TRI_TYPE_FLAT_TOP )

             {

                  //计算各种差值

                  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;

 

                  //垂直裁剪测试

                  if ( y0 <m_min_clip_y )

                  {

                      //垂直计算Y坐标差值

                      dy                         = ( m_min_clip_y - y0 );

                      //计算第一条扫描线起点的各种值

                      xl                         = dxdyl * dy + (x0 << FIXP16_SHIFT );

                      ul                         = dudyl * dy + (tu0 << FIXP16_SHIFT );

                      vl                         = dvdyl * dy + (tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线终点的各种值

                      xr                         = dxdyr * dy + (x1 << FIXP16_SHIFT );

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

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

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = m_min_clip_y;

                  }

                  else

                  {

                      //不用裁剪

                      //设置第一条扫描线起点和终点的各种值

                      xl                         = ( x0 << FIXP16_SHIFT );

                      ul                         = ( tu0 << FIXP16_SHIFT );

                      vl                         = ( tv0 << FIXP16_SHIFT );

 

                      xr                         = ( x1 << FIXP16_SHIFT );

                      ur                         = ( tu1 << FIXP16_SHIFT );

                      vr                         = ( tv1 << FIXP16_SHIFT );

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = y0;

 

                  }

 

             }

             else   //肯定是平底三角形

             {

                  //计算各种差值

                  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;

 

                  //垂直裁剪测试

                  if ( y0 <m_min_clip_y )

                  {

                      //垂直计算Y坐标差值

                      dy                         = ( m_min_clip_y - y0 );

                      //计算第一条扫描线起点的各种值

                      xl                         = dxdyl * dy + (x0 << FIXP16_SHIFT );

                      ul                         = dudyl * dy + (tu0 << FIXP16_SHIFT );

                      vl                         = dvdyl * dy + (tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线终点的各种值

                      xr                         = dxdyr * dy + (x0 << FIXP16_SHIFT );

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

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

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = m_min_clip_y;

                  }

                  else

                  {

                      //不用裁剪

                      //设置第一条扫描线起点和终点的各种值

                      xl                         = ( x0 << FIXP16_SHIFT );

                      ul                         = ( tu0 << FIXP16_SHIFT );

                      vl                         = ( tv0 << FIXP16_SHIFT );

 

                      xr                         = ( x0 << FIXP16_SHIFT );

                      ur                         = ( tu0 << FIXP16_SHIFT );

                      vr                         = ( tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = y0;

 

                  }

 

             }

 

             //总是检测三角形最下面的部分是否会被裁剪掉

             if (( yend =y2 ) > m_max_clip_y )

             {

                  yend                       = m_max_clip_y;

             }

 

             //水平裁剪测试

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

             {

                  //裁剪版本

                  //让指screen_ptr指向第一条扫描线起点在缓存的位置

                  screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                  for ( yi =ystart; yi <=yend; yi++ )

                  {

                      //计算扫描线起点和终点的X坐标

                      xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                      xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                      //计算扫描线起点和终点的坐标

                      ui                         = ul + FIXP16_ROUND_UP;

                      vi                         = vl + FIXP16_ROUND_UP;

                      //计算扫描线上的RGB梯度

                      if ( ( dx = (xend - xstart )) > 0 )

                      {

                           du                     = ( ur - ul ) /dx;

                           dv                     = ( vr - vl ) /dx;

 

                      }

                      else

                      {

                           du                     = ( ur - ul );

                           dv                     = ( vr - vl );

 

                      }

                      //扫描线起点水平裁剪测试

                      if ( xstart <m_min_clip_x )

                      {

                           //计算起点移动距离

                           dx                     = m_min_clip_x - xstart;

                           //重新计算扫描线起点的RGB

                           ui                     += dx * du;

                           vi                     += dx * dv;

 

                           //重新设置循环起始条件

                           xstart                 = m_min_clip_x;

                      }

 

                      //终点水平测试

                      if ( xend >m_max_clip_x )

                      {

                           xend               = m_max_clip_x;

                      }

 

                      //绘制扫描线

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

                      {

                           //绘制像素,假设格式为.6.5

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

 

                           //计算下一个像素的UV

                           ui                     += du;

                           vi                     += dv;

                      }

 

                      //计算下一条扫描线起点和终点的x坐标和RGB

                      xl                         += dxdyl;

                      ul                         += dudyl;

                      vl                         += dvdyl;

 

                      xr                         += dxdyr;

                      ur                         += dudyr;

                      vr                         += dvdyr;

 

                      //让指针screen_ptr指向视频缓存的下一行

                      screen_ptr                 += mem_pitch;

 

                  }

 

             }

 

             //三角形没有被裁剪时的绘制代码

             else

             {

                  screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                  for ( yi =ystart; yi <=yend; yi++ )

                  {

                      //计算扫描线起点和终点的X坐标

                      xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                      xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                      //计算扫描线起点和终点的坐标

                      ui                         = ul + FIXP16_ROUND_UP;

                      vi                         = vl + FIXP16_ROUND_UP;

 

                      //计算扫描线上的RGB梯度

                      if ( ( dx = (xend - xstart )) > 0 )

                      {

                           du                     = ( ur - ul ) /dx;

                           dv                     = ( vr - vl ) /dx;

 

                      }

                      else

                      {

                           du                     = ( ur - ul );

                           dv                     = ( vr - vl );

 

                      }

 

 

                       //绘制扫描线

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

                      {

                           //绘制像素,

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

                           //计算下一个像素的RGB

                           ui                     += du;

                           vi                     += dv;

                      }

 

                      //计算下一条扫描线起点和终点的x坐标和RGB

                      xl                         += dxdyl;

                      ul                         += dudyl;

                      vl                         += dvdyl;

 

                      xr                         += dxdyr;

                      ur                         += dudyr;

                      vr                         += dvdyr;

 

                      //让指针screen_ptr指向视频缓存的下一行

                      screen_ptr                 += mem_pitch;

 

                  }

             }

 

        }

        else

             //绘制常规三角形

             if ( tri_type ==TRI_TYPE_GENERAL )

             {

                  if (( yend =y2 ) > m_max_clip_y )

                  {

                      yend                       = m_max_clip_y;

                  }

                  if ( y1 <m_min_clip_y )

                  {

                      //垂直计算Y坐标差值

                      //左侧

                      dyl                        = ( y2 - y1 );

 

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

                      dudyl                           = ( ( tu2 - tu1 ) << FIXP16_SHIFT ) / dyl;

                      dvdyl                           = ( ( tv2 - tv1 ) << FIXP16_SHIFT ) / dyl;

 

                      //右侧

                      dyr                             = ( y2 - y0 );

 

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

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

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

 

 

                      //垂直计算Y坐标差值

                      dyr                             = ( m_min_clip_y - y0 );

                      dyl                             = ( m_min_clip_y - y1 ) ;

                      //计算第一条扫描线起点的各种值

                      xl                         = dxdyl * dyl + (xl << FIXP16_SHIFT );

                      ul                         = dudyl * dyl + (tu1 << FIXP16_SHIFT );

                      vl                         = dvdyl * dyl + (tv1 << FIXP16_SHIFT );

 

                      //计算第一条扫描线终点的各种值

                      xr                         = dxdyr * dyr + (x0 << FIXP16_SHIFT );

                      ur                         = dudyr * dyr + (tu0 << FIXP16_SHIFT );

                      vr                         = dvdyr * dyr + (tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = m_min_clip_y;

 

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

 

                           irestart           = INTERP_RHS;

 

                      }

                  }

                  else

                      if ( y0 < m_min_clip_y )

                      {

                           //垂直计算Y坐标差值

                           //左侧

                           dyl                             = ( y1 - y0 );

 

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

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

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

 

                           //右侧

                           dyr                             = ( y2 - y0 );

 

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

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

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

 

                           //垂直计算Y坐标差值

                           dy                              = ( m_min_clip_y - y0 );

 

                           //计算第一条扫描线起点的各种值

                           xl                              = dxdyl * dy + (x0 << FIXP16_SHIFT );

                           ul                              = dudyl * dy + (tu0 << FIXP16_SHIFT );

                           vl                              = dvdyl * dy + (tv0 << FIXP16_SHIFT );

 

                           //计算第一条扫描线终点的各种值

                           xr                              = dxdyr * dy + (x0 << FIXP16_SHIFT );

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

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

 

                           //计算第一条扫描线的Y坐标

                           ystart                          = m_min_clip_y;

 

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

 

                                irestart           = INTERP_RHS;

 

                           }

                      }

                      else

                      {

                           dyl                             = ( y1 - y0 );

 

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

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

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

 

                           //右侧

                           dyr                             = ( y2 - y0 );

 

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

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

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

 

                           xl                              = ( x0 << FIXP16_SHIFT );

                           ul                              = ( tu0 << FIXP16_SHIFT );

                           vl                              = ( tv0 << FIXP16_SHIFT );

 

                           xr                              = ( x0 << FIXP16_SHIFT );

                           ur                              = ( tu0 << FIXP16_SHIFT );

                           vr                              = ( tv0 << FIXP16_SHIFT );

 

                           ystart                          = y0;

 

 

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

 

                                irestart           = INTERP_RHS;

                           }

 

 

                      }

                      //水平裁剪测试

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

                      {

                           //裁剪版本

                           //让指screen_ptr指向第一条扫描线起点在缓存的位置

                           screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                           for ( yi =ystart; yi <=yend; yi++ )

                           {

                                //计算扫描线起点和终点的X坐标

                                xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                                xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                                //计算扫描线起点和终点的坐标

                                ui                         = ul + FIXP16_ROUND_UP;

                                vi                         = vl + FIXP16_ROUND_UP;

 

                                //计算扫描线上的RGB梯度

                                if ( ( dx = (xend - xstart )) > 0 )

                                {

                                    du                     = ( ur - ul ) /dx;

                                    dv                     = ( vr - vl ) /dx;

 

                                }

                                else

                                {

                                    du                     = ( ur - ul );

                                    dv                     = ( vr - vl );

 

                                }

                                //扫描线起点水平裁剪测试

                                if ( xstart <m_min_clip_x )

                                {

                                    //计算起点移动距离

                                    dx                     = m_min_clip_x - xstart;

                                    //重新计算扫描线起点的RGB

                                    ui                     += dx * du;

                                    vi                     += dx * dv;

 

                                    //重新设置循环起始条件

                                    xstart                 = m_min_clip_x;

                                }

 

                                //终点水平测试

                                if ( xend >m_max_clip_x )

                                {

                                    xend               = m_max_clip_x;

                                }

 

                                //绘制扫描线

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

                                {

                                    //绘制像素,假设格式为.6.5

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

 

                                    //计算下一个像素的uv

                                    ui                     += du;

                                    vi                     += dv;

                                }

 

                                //计算下一条扫描线起点和终点的x坐标和RGB

                                xl                         += dxdyl;

                                ul                         += dudyl;

                                vl                         += dvdyl;

 

                                xr                         += dxdyr;

                                ur                         += dudyr;

                                vr                         += dvdyr;

 

                                //让指针screen_ptr指向视频缓存的下一行

                                screen_ptr                 += mem_pitch;

 

                                if ( yi ==yrestart )

                                {

                                    if ( irestart ==INTERP_LHS )

                                     {

                                         dyl                = ( y2 - y1 );

 

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

                                         dudyl              = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;

                                         dvdyl              = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;

 

                                         xl                 = ( xl << FIXP16_SHIFT );

                                         ul                 = ( tu1 << FIXP16_SHIFT );

                                         vl                 = ( tv1 << FIXP16_SHIFT );

 

                                         xl                 += dxdyl;

                                         ul                 += dudyl;

                                         vl                 += dvdyl;

 

                                    }

                                    else

                                    {

                                         dyr                = ( y1 - y2 );

 

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

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

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

 

                                         xr                 = ( x2 << FIXP16_SHIFT );

                                         ur                 = ( tu2 << FIXP16_SHIFT );

                                         vr                 = ( tv2 << FIXP16_SHIFT );

 

                                         xr                 += dxdyr;

                                         ur                 += dudyr;

                                         vr                 += dvdyr;

 

                                    }

                                }

 

                           }

 

                      }

                      else

                      {

                           //裁剪版本

                           //让指screen_ptr指向第一条扫描线起点在缓存的位置

                           screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                           for ( yi =ystart; yi <=yend; yi++ )

                           {

                                //计算扫描线起点和终点的X坐标

                                xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                                xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                                //计算扫描线起点和终点的坐标

                                ui                         = ul + FIXP16_ROUND_UP;

                                vi                         = vl + FIXP16_ROUND_UP;

                                //计算扫描线上的RGB梯度

                                if ( ( dx = (xend - xstart )) > 0 )

                                {

                                    du                     = ( ur - ul ) /dx;

                                    dv                     = ( vr - vl ) /dx;

                                }

                                else

                                {

                                    du                     = ( ur - ul );

                                    dv                     = ( vr - vl );

                                }

 

 

                                //绘制扫描线

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

                                {

                                    //绘制像素,

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

 

                                    //计算下一个像素的RGB

                                    ui                     += du;

                                    vi                     += dv;

                                }

 

                                //计算下一条扫描线起点和终点的x坐标和RGB

                                xl                         += dxdyl;

                                ul                         += dudyl;

                                vl                         += dvdyl;

 

                                xr                         += dxdyr;

                                ur                         += dudyr;

                                vr                         += dvdyr;

 

                                //让指针screen_ptr指向视频缓存的下一行

                                screen_ptr                 += mem_pitch;

 

                                if ( yi ==yrestart )

                                {

                                    if ( irestart ==INTERP_LHS )

                                    {

                                         dyl                = ( y2 - y1 );

 

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

                                         dudyl              = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;

                                         dvdyl              = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;

 

                                         xl                 = ( xl << FIXP16_SHIFT );

                                         ul                 = ( tu1 << FIXP16_SHIFT );

                                         vl                 = ( tv1 << FIXP16_SHIFT );

 

                                         xl                 += dxdyl;

                                         ul                += dudyl;

                                         vl                 += dvdyl;

 

                                    }

                                    else

                                    {

                                         dyr                = ( y1 - y2 );

 

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

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

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

 

                                         xr                 = ( x2 << FIXP16_SHIFT );

                                         ur                 = ( tu2 << FIXP16_SHIFT );

                                         vr                 = ( tv2 << FIXP16_SHIFT );

 

                                         xr                 += dxdyr;

                                         ur                 += dudyr;

                                         vr                 += dvdyr;

 

                                    }

                                }

 

                           }

                      }

             }

 

}

 

一个类似的函数

 

 

 

voidddraw_math::Draw_Textured_TriangleFS16(POLYF4DV2_PTR face,UCHAR * _dest_buffer,int mem_pitch )

{

    int                    v0 = 0, v1 = 1,v2 = 2, temp = 0,tri_type = TRI_TYPE_NONE,irestartINTERP_LHS;

 

    int                    dx, dy, dyl, dyr,      //存储差值

        u, v,                 //UV

        du, dv

        xi, yi,                    //当前的xy坐标

        ui,vi,                //当前的UV

        index_x, index_y,     //循环变量

        x, y,                      //存储一般性XY坐标

        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, //顶点的初始颜色

        x1, y1,tu1, tv1,

        x2, y2,tu2, tv2

 

    USHORT        *       screen_ptr                      = NULL,

        *        screen_line                     = NULL,

        *        textmap                         = NULL,

        *        dest_buffer                     = (USHORT * )_dest_buffer;

 

    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,

 

    };

 

 

    //提取纹理图

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

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

 

    //将内存跨距的单位调整为字

    mem_pitch                                >>= 1;

 

    //判断三角形是否在屏幕内

    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;

    }

 

    //判断三角形是否退化为直线

    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;

    }

 

    //对顶点进行排序

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

    }

 

 

    //判断三角形是否平顶

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

    {

        //设置三角形类型

        tri_type                        = TRI_TYPE_FLAT_TOP;

        //将顶点从左到右的顺序排列

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

        {

             SWAP( v0,v1, temp );

        }

    }

    else

        //判断三角形是否平底

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

        {

             //设置三角形类型

             tri_type                        = TRI_TYPE_FLAT_BOTTOM;

             //将顶点从左到右的顺序排列

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

             {

                  SWAP( v1,v2, temp );

             }

        }

        else

             //肯定是常规三角形

        {

             tri_type                        = TRI_TYPE_GENERAL;

        }

 

 

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

 

 

        //提取各个顶点的坐标值和RGB

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

 

        //设置斜率转折点

        yrestart                            = y1;

 

        //判断三角形类型

        if ( tri_type &TRI_TYPE_FLAT_MASK )

        {

             if ( tri_type ==TRI_TYPE_FLAT_TOP )

             {

                  //计算各种差值

                  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;

 

                  //垂直裁剪测试

                  if ( y0 <m_min_clip_y )

                  {

                      //垂直计算Y坐标差值

                      dy                         = ( m_min_clip_y - y0 );

                      //计算第一条扫描线起点的各种值

                      xl                         = dxdyl * dy + (x0 << FIXP16_SHIFT );

                      ul                         = dudyl * dy + (tu0 << FIXP16_SHIFT );

                      vl                         = dvdyl * dy + (tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线终点的各种值

                      xr                         = dxdyr * dy + (x1 << FIXP16_SHIFT );

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

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

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = m_min_clip_y;

                  }

                  else

                  {

                      //不用裁剪

                      //设置第一条扫描线起点和终点的各种值

                      xl                         = ( x0 << FIXP16_SHIFT );

                      ul                         = ( tu0 << FIXP16_SHIFT );

                      vl                         = ( tv0 << FIXP16_SHIFT );

 

                      xr                         = ( x1 << FIXP16_SHIFT );

                      ur                         = ( tu1 << FIXP16_SHIFT );

                      vr                         = ( tv1 << FIXP16_SHIFT );

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = y0;

 

                  }

 

             }

             else   //肯定是平底三角形

             {

                  //计算各种差值

                  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;

 

                  //垂直裁剪测试

                  if ( y0 <m_min_clip_y )

                  {

                      //垂直计算Y坐标差值

                      dy                         = ( m_min_clip_y - y0 );

                      //计算第一条扫描线起点的各种值

                      xl                         = dxdyl * dy + (x0 << FIXP16_SHIFT );

                      ul                         = dudyl * dy + (tu0 << FIXP16_SHIFT );

                       vl                         = dvdyl * dy + (tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线终点的各种值

                      xr                         = dxdyr * dy + (x0 << FIXP16_SHIFT );

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

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

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = m_min_clip_y;

                  }

                  else

                  {

                      //不用裁剪

                      //设置第一条扫描线起点和终点的各种值

                      xl                         = ( x0 << FIXP16_SHIFT );

                      ul                         = ( tu0 << FIXP16_SHIFT );

                      vl                         = ( tv0 << FIXP16_SHIFT );

 

                      xr                         = ( x0 << FIXP16_SHIFT );

                      ur                          = ( tu0 << FIXP16_SHIFT );

                      vr                         = ( tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = y0;

 

                  }

 

             }

 

             //总是检测三角形最下面的部分是否会被裁剪掉

             if (( yend =y2 ) > m_max_clip_y )

             {

                  yend                       = m_max_clip_y;

             }

 

             //水平裁剪测试

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

             {

                  //裁剪版本

                  //让指screen_ptr指向第一条扫描线起点在缓存的位置

                  screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                  for ( yi =ystart; yi <=yend; yi++ )

                  {

                      //计算扫描线起点和终点的X坐标

                      xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                      xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                      //计算扫描线起点和终点的坐标

                      ui                         = ul + FIXP16_ROUND_UP;

                      vi                         = vl + FIXP16_ROUND_UP;

                      //计算扫描线上的RGB梯度

                      if ( ( dx = (xend - xstart )) > 0 )

                      {

                           du                     = ( ur - ul ) /dx;

                           dv                     = ( vr - vl ) /dx;

 

                      }

                      else

                      {

                           du                     = ( ur - ul );

                           dv                     = ( vr - vl );

 

                      }

                      //扫描线起点水平裁剪测试

                      if ( xstart <m_min_clip_x )

                      {

                           //计算起点移动距离

                           dx                     = m_min_clip_x - xstart;

                           //重新计算扫描线起点的RGB

                           ui                     += dx * du;

                           vi                     += dx * dv;

 

                           //重新设置循环起始条件

                           xstart                 = m_min_clip_x;

                      }

 

                      //终点水平测试

                      if ( xend >m_max_clip_x )

                      {

                           xend               = m_max_clip_x;

                      }

 

                      //绘制扫描线

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

                      {

                           //绘制像素,假设格式为.6.5

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

 

                           r_textel           = ( ( textel >> 11 );

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

                           b_textel           = ( textel & 0x1f );

 

                           r_textel           *= r_base;

                           g_textel           *= g_base;

                           b_textel           *= b_base;

 

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

 

 

 

                           //计算下一个像素的UV

                           ui                     += du;

                           vi                     += dv;

                      }

 

                      //计算下一条扫描线起点和终点的x坐标和RGB

                      xl                         += dxdyl;

                      ul                         += dudyl;

                      vl                         += dvdyl;

 

                       xr                         += dxdyr;

                      ur                         += dudyr;

                      vr                         += dvdyr;

 

                      //让指针screen_ptr指向视频缓存的下一行

                      screen_ptr                 += mem_pitch;

 

                  }

 

             }

 

             //三角形没有被裁剪时的绘制代码

             else

             {

                  screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                  for ( yi =ystart; yi <=yend; yi++ )

                  {

                      //计算扫描线起点和终点的X坐标

                      xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                      xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                      //计算扫描线起点和终点的坐标

                      ui                         = ul + FIXP16_ROUND_UP;

                      vi                         = vl + FIXP16_ROUND_UP;

 

                      //计算扫描线上的RGB梯度

                      if ( ( dx = (xend - xstart )) > 0 )

                      {

                           du                     = ( ur - ul ) /dx;

                           dv                     = ( vr - vl ) /dx;

 

                      }

                      else

                      {

                           du                     = ( ur - ul );

                           dv                     = ( vr - vl );

 

                      }

 

 

                      //绘制扫描线

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

                      {

                           //绘制像素,

 

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

 

                           r_textel           = ( ( textel >> 11 ) );

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

                           b_textel          = ( textel & 0x1f );

 

                           r_textel           *= r_base;

                           g_textel           *= g_base;

                           b_textel           *= b_base;

 

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

                           //计算下一个像素的RGB

                           ui                    += du;

                           vi                     += dv;

                      }

 

                      //计算下一条扫描线起点和终点的x坐标和RGB

                      xl                         += dxdyl;

                      ul                         += dudyl;

                      vl                         += dvdyl;

 

                      xr                         += dxdyr;

                      ur                         += dudyr;

                      vr                         += dvdyr;

 

                      //让指针screen_ptr指向视频缓存的下一行

                      screen_ptr                  += mem_pitch;

 

                  }

             }

 

        }

        else

             //绘制常规三角形

             if ( tri_type ==TRI_TYPE_GENERAL )

             {

                  if (( yend =y2 ) > m_max_clip_y )

                  {

                      yend                       = m_max_clip_y;

                  }

                  if ( y1 <m_min_clip_y )

                  {

                      //垂直计算Y坐标差值

                      //左侧

                      dyl                        = ( y2 - y1 );

 

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

                      dudyl                           = ( ( tu2 - tu1 ) << FIXP16_SHIFT ) / dyl;

                      dvdyl                           = ( ( tv2 - tv1 ) << FIXP16_SHIFT ) / dyl;

 

                      //右侧

                      dyr                             = ( y2 - y0 );

 

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

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

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

 

 

                      //垂直计算Y坐标差值

                      dyr                             = ( m_min_clip_y - y0 );

                      dyl                             = ( m_min_clip_y - y1 ) ;

                       //计算第一条扫描线起点的各种值

                      xl                         = dxdyl * dyl + (xl << FIXP16_SHIFT );

                      ul                         = dudyl * dyl + (tu1 << FIXP16_SHIFT );

                      vl                         = dvdyl * dyl + (tv1 << FIXP16_SHIFT );

 

                      //计算第一条扫描线终点的各种值

                      xr                         = dxdyr * dyr + (x0 << FIXP16_SHIFT );

                       ur                         = dudyr * dyr + (tu0 << FIXP16_SHIFT );

                      vr                         = dvdyr * dyr + (tv0 << FIXP16_SHIFT );

 

                      //计算第一条扫描线的Y坐标

                      ystart                     = m_min_clip_y;

 

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

 

                           irestart           = INTERP_RHS;

 

                      }

                  }

                  else

                      if ( y0 <m_min_clip_y )

                      {

                           //垂直计算Y坐标差值

                           //左侧

                           dyl                             = ( y1 - y0 );

 

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

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

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

 

                           //右侧

                           dyr                             = ( y2 - y0 );

 

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

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

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

 

                           //垂直计算Y坐标差值

                           dy                              = ( m_min_clip_y - y0 );

 

                           //计算第一条扫描线起点的各种值

                           xl                              = dxdyl * dy + (x0 << FIXP16_SHIFT );

                           ul                              = dudyl * dy + (tu0 << FIXP16_SHIFT );

                           vl                              = dvdyl * dy + (tv0 << FIXP16_SHIFT );

 

                           //计算第一条扫描线终点的各种值

                           xr                              = dxdyr * dy + (x0 << FIXP16_SHIFT );

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

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

 

                           //计算第一条扫描线的Y坐标

                           ystart                          = m_min_clip_y;

 

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

 

                                irestart           = INTERP_RHS;

 

                           }

                      }

                      else

                      {

                           dyl                             = ( y1 - y0 );

 

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

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

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

 

                           //右侧

                           dyr                             = ( y2 - y0 );

 

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

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

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

 

                           xl                              = ( x0 << FIXP16_SHIFT );

                           ul                              = ( tu0 << FIXP16_SHIFT );

                           vl                              = ( tv0 << FIXP16_SHIFT );

 

                           xr                              = ( x0 << FIXP16_SHIFT );

                           ur                              = ( tu0 << FIXP16_SHIFT );

                           vr                              = ( tv0 << FIXP16_SHIFT );

 

                           ystart                          = y0;

 

 

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

 

                                irestart           = INTERP_RHS;

                           }

 

 

                      }

                      //水平裁剪测试

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

                      {

                           //裁剪版本

                           //让指screen_ptr指向第一条扫描线起点在缓存的位置

                           screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                           for ( yi =ystart; yi <=yend; yi++ )

                           {

                                //计算扫描线起点和终点的X坐标

                                xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                                xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                                //计算扫描线起点和终点的坐标

                                ui                         = ul + FIXP16_ROUND_UP;

                                vi                         = vl + FIXP16_ROUND_UP;

 

                                //计算扫描线上的RGB梯度

                                if ( ( dx = (xend - xstart )) > 0 )

                                {

                                    du                     = ( ur - ul ) /dx;

                                    dv                     = ( vr - vl ) /dx;

 

                                }

                                else

                                {

                                    du                     = ( ur - ul );

                                    dv                     = ( vr - vl );

 

                                }

                                //扫描线起点水平裁剪测试

                                if ( xstart <m_min_clip_x )

                                {

                                    //计算起点移动距离

                                    dx                     = m_min_clip_x - xstart;

                                    //重新计算扫描线起点的RGB

                                    ui                     += dx * du;

                                    vi                     += dx * dv;

 

                                    //重新设置循环起始条件

                                    xstart                 = m_min_clip_x;

                                }

 

                                //终点水平测试

                                if ( xend >m_max_clip_x )

                                {

                                    xend               = m_max_clip_x;

                                }

 

                                //绘制扫描线

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

                                {

                                    //绘制像素,假设格式为.6.5

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

 

                                    r_textel           = ( ( textel >> 11 );

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

                                    b_textel           = ( textel & 0x1f );

 

                                    r_textel           *= r_base;

                                    g_textel           *= g_base;

                                    b_textel           *= b_base;

 

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

 

                                    //计算下一个像素的uv

                                    ui                     += du;

                                    vi                     += dv;

                                }

 

                                //计算下一条扫描线起点和终点的x坐标和RGB

                                xl                         += dxdyl;

                                ul                         += dudyl;

                                vl                         += dvdyl;

 

                                xr                         += dxdyr;

                                ur                         += dudyr;

                                vr                         += dvdyr;

 

                                //让指针screen_ptr指向视频缓存的下一行

                                screen_ptr                 += mem_pitch;

 

                                if ( yi ==yrestart )

                                {

                                    if ( irestart ==INTERP_LHS )

                                    {

                                         dyl                = ( y2 - y1 );

 

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

                                         dudyl              = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;

                                         dvdyl              = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;

 

                                         xl                 = ( xl << FIXP16_SHIFT );

                                         ul                 = ( tu1 << FIXP16_SHIFT );

                                         vl                 = ( tv1 << FIXP16_SHIFT );

 

                                         xl                 += dxdyl;

                                         ul                 += dudyl;

                                         vl                += dvdyl;

 

                                    }

                                    else

                                    {

                                         dyr                = ( y1 - y2 );

 

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

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

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

 

                                         xr                 = ( x2 << FIXP16_SHIFT );

                                         ur                 = ( tu2 << FIXP16_SHIFT );

                                         vr                 = ( tv2 << FIXP16_SHIFT );

 

                                         xr                 += dxdyr;

                                         ur                 += dudyr;

                                         vr                 += dvdyr;

 

                                    }

                                }

 

                           }

 

                      }

                      else

                      {

                           //裁剪版本

                           //让指screen_ptr指向第一条扫描线起点在缓存的位置

                           screen_ptr                      = dest_buffer + ( ystart * mem_pitch );

                           for ( yi =ystart; yi <=yend; yi++ )

                           {

                                //计算扫描线起点和终点的X坐标

                                xstart                     = ( ( xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT );

                                xend                   = ( ( xr + FIXP16_ROUND_UP) >>FIXP16_SHIFT );

                                //计算扫描线起点和终点的坐标

                                ui                         = ul + FIXP16_ROUND_UP;

                                vi                         = vl + FIXP16_ROUND_UP;

                                //计算扫描线上的RGB梯度

                                if ( ( dx = (xend - xstart )) > 0 )

                                {

                                    du                     = ( ur - ul ) /dx;

                                    dv                     = ( vr - vl ) /dx;

                                }

                                else

                                {

                                    du                     = ( ur - ul );

                                    dv                     = ( vr - vl );

                                }

 

 

                                //绘制扫描线

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

                                {

                                    //绘制像素,

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

 

                                    r_textel           = ( ( textel >> 11 );

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

                                    b_textel           = ( textel & 0x1f );

 

                                    r_textel           *= r_base;

                                    g_textel          *= g_base;

                                    b_textel           *= b_base;

 

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

 

                                    //计算下一个像素的RGB

                                    ui                     += du;

                                    vi                     += dv;

                                }

 

                                //计算下一条扫描线起点和终点的x坐标和RGB

                                xl                         += dxdyl;

                                ul                         += dudyl;

                                vl                         += dvdyl;

 

                                xr                         += dxdyr;

                                ur                         += dudyr;

                                vr                         += dvdyr;

 

                                //让指针screen_ptr指向视频缓存的下一行

                                screen_ptr                 += mem_pitch;

 

                                if ( yi ==yrestart )

                                {

                                    if ( irestart ==INTERP_LHS )

                                    {

                                         dyl                = ( y2 - y1 );

 

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

                                         dudyl              = ( ( tu2 - tu1 ) <<FIXP16_SHIFT ) / dyl;

                                         dvdyl              = ( ( tv2 - tv1 ) <<FIXP16_SHIFT ) / dyl;

 

                                         xl                 = ( xl << FIXP16_SHIFT );

                                         ul                 = ( tu1 << FIXP16_SHIFT );

                                         vl                 = ( tv1 << FIXP16_SHIFT );

 

                                         xl                 += dxdyl;

                                         ul                 += dudyl;

                                         vl                 += dvdyl;

 

                                    }

                                    else

                                    {

                                         dyr                = ( y1 - y2 );

 

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

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

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

 

                                         xr                 = ( x2 << FIXP16_SHIFT );

                                         ur                 = ( tu2 << FIXP16_SHIFT );

                                         vr                 = ( tv2 << FIXP16_SHIFT );

 

                                         xr                 += dxdyr;

                                         ur                 += dudyr;

                                         vr                 += dvdyr;

 

                                    }

                                }

 

                           }

                      }

             }

 

}

总的绘制列表

voidDDRAW_LIUSHUIXIAN_TEXTURE::Draw_RENDERLIST4DV2_Solid16(ddraw_mathmath2, RENDERLIST4DV2_PTRrend_list, UCHAR *video_buffer,int lpitch)

{

    POLYF4DV2              face;

 

    for( int poly = 0; poly < rend_list->num_polys; poly++ )

    {

        //获得当前多边形

        POLYF4DV2_PTR      curr_poly              =rend_list->poly_ptrs[poly];

 

 

        //当且仅当多边形没有被剔除或者裁剪掉,同时处于活动状态且可见时,才对其进行变换)

        if( !( curr_poly->state &POLY4DV2_STATE_ACTIVE ) ||

             ( curr_poly->state &POLY4DV2_STATE_CLIPPED ) ||

             ( curr_poly->state &POLY4DV2_STATE_BACKFACE ) )

             continue; //进入下一个多边形

 

        //先测试纹理,

        if( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_TEXTURE )

        {

             face.tvlist[0].x                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].x;

             face.tvlist[0].y                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].y;

             face.tvlist[0].u0                   = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].u0;

             face.tvlist[0].v0                   = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].v0;

 

             face.tvlist[1].x                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].x;

             face.tvlist[1].y                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].y;

             face.tvlist[1].u0                   = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].u0;

             face.tvlist[1].v0                   = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].v0;

 

             face.tvlist[2].x                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].x;

             face.tvlist[2].y                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].y;

             face.tvlist[2].u0                   = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].u0;

             face.tvlist[2].v0                   = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].v0;

 

             face.texture                        = rend_list->poly_ptrs[poly]->texture;

 

             if( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_CONSTANT )

             {

                  math2.Draw_Textured_Triangle16( &face, video_buffer,lpitch );

             }

             else

             {

                  face.lit_color[0]               = rend_list->poly_ptrs[poly]->lit_color[0];

 

                  math2.Draw_Textured_TriangleFS16( &face, video_buffer,lpitch );

             }

 

        }

        else

             if( ( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_FLAT )

                  || ( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_CONSTANT ) )

             {

                  math2.Draw_Triangle_2D2_16(rend_list->poly_ptrs[poly]->tvlist[0].x,

                      rend_list->poly_ptrs[poly]->tvlist[0].y,

                      rend_list->poly_ptrs[poly]->tvlist[1].x,

                      rend_list->poly_ptrs[poly]->tvlist[1].y,

                      rend_list->poly_ptrs[poly]->tvlist[2].x,

                      rend_list->poly_ptrs[poly]->tvlist[2].y,

                      rend_list->poly_ptrs[poly]->lit_color[0],

                      video_buffer, lpitch );

             }

             else

                  if( rend_list->poly_ptrs[poly]->attr &POLY4DV2_ATTR_SHADE_MODE_GOURAUD )

                  {

                      face.tvlist[0].x                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].x;

                      face.tvlist[0].y                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[0].y;

                      face.lit_color[0]                   =  rend_list->poly_ptrs[poly]->lit_color[0];

 

                      face.tvlist[1].x                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].x;

                      face.tvlist[1].y                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[1].y;

                      face.lit_color[1]                   =  rend_list->poly_ptrs[poly]->lit_color[1];

 

                      face.tvlist[2].x                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].x;

                      face.tvlist[2].y                    = ( int ) rend_list->poly_ptrs[poly]->tvlist[2].y;

                      face.lit_color[2]                   =  rend_list->poly_ptrs[poly]->lit_color[2];

 

                      math2.Draw_Gouraud_Triangle16( &face, video_buffer,lpitch );

                  }

 

 

    

 

    }

 

 

}

进行一些修正后,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值