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

来源:互联网 发布:淘宝买家具哪个品牌好 编辑:程序博客网 时间:2024/06/18 03:54

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_mathmath,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结构

 

 

typedefstructRENDERLIST4DV2_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_mathmath,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_PTRobj )

{

    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_PTRmt,          //变换矩阵

                                                             intcoord_select,

                                                             inttransform_basis,

                                                             intall_frames,

                                                             ddraw_mathmath2 )              //指定要变换的坐标

{

    if( !all_frames )

    {

 

        switch( coord_select )

        {

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

 

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

 

        caseTRANSFORM_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

    {

        switch( coord_select )

        {

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

 

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

 

        caseTRANSFORM_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_PTRobj, ddraw_mathmath2,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 )

{

    unsignedintbase_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 (intpoly=0; poly <rend_list->num_polys;poly++)

    {

        // acquire polygon

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

        }

 

 

 

        VECTOR4Du,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

        VECTOR4Dview;

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

 

        // and finally, compute the dot product

        floatdp =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_mathmath2,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 )

    {

    caseSORT_POLYLIST_AVGZ:

        {

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

        }

        break;

    caseSORT_POLYLIST_NEARZ:

        {

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

        }

        break;

    caseSORT_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_PTRface,UCHAR *_dest_buffer,intmem_pitch )

{

    int                   v0 = 0, v1 = 1,v2 = 2,temp = 0,tri_type =TRI_TYPE_NONE,irestart = INTERP_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;

 

    UCHARlogbase2ofx[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_PTRface,UCHAR *_dest_buffer,intmem_pitch )

{

    int                   v0 = 0, v1 = 1,v2 = 2,temp = 0,tri_type =TRI_TYPE_NONE,irestart = INTERP_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;

 

    UCHARlogbase2ofx[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,intlpitch)

{

    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
原创粉丝点击