2014年3月8日星期六(DEMO8-5恒定着色)

2023-11-18

恒定着色是在多边形由一种材质构成。多边形的每个点的面法线都相同,因此,只需对一个顶点的像素的光照情况对整个多边形进行着色。

     对于平面组成的物体,是可行的,但是如果对曲面组成的物体,会导致物体看起来由多边形组成。

     在16位着色下,光照步骤为

1,  计算面法线

2,  对于光源列表中的每个光源,计算其光照强度

3,  将所有光照强度相加

4,  将结果写入到多边形颜色变量的前16位中

 

这里暂不考虑材质,只考虑光照。

按照代码逐步进行。

先定义几种光照的索引

 

#define                              AMBIENT_LIGHT_INDEX    0

#define                              INFINITE_LIGHT_INDEX   1

#define                              POINT_LIGHT_INDEX  2

#define                              SPOT_LIGHT_INDEX   3

 

在GAME_INIT()中,重置光源

首先,要加个RGBA的结构体

 

typedef struct RGBAV1_TYPE

{

 

     union

     {

 

         int      rgba;         //压缩格式

         UCHAR    rgba_M[4];    //数组格式

         struct

         {

              UCHAR    a, b, g, r;        //显式名称格式

         };

     };

}RGBAV1, * RGBAV1_PTR;

 

接下来,加上光照结构体

 

typedef struct LIGHTV1_TYP

{

     int                state;             //光照状态

     int                id;                //光源ID

     int                attr;              //光源类型及其他属性

 

     RGBAV1             c_ambient;         //环境光强度

     RGBAV1             c_diffuse;         //散射光强度

     RGBAV1             c_specular;        //镜面反射光强度

     POINT4D            pos;          //光源位置

     VECTOR4D      dir;          //光源方向

     float              kc,kl,kq;     //衰减因子

     float              spot_inner;        //聚光灯内锥角

     float              sport_outer//聚光灯外锥角

     float              pf;                //聚光灯指数因子

 

}LIGHTV1, * LIGHTV1_PTR;

下面重置光源

先设定最多灯数为8

#define                MAX_LIGHTS         8

int ddraw_liushuixian::Reset_Lights_LIGHTV1( LIGHTV1_PTR lights, int num_lights )

{

     static int             first_time                  = 1;

     memset( lights, 0, MAX_LIGHTS * sizeof( LIGHTV1));

 

     //重置光源数

     num_lights                                         = 0;

     first_time                                         = 0;

     return ( 1 );

}

再设置两个全局变量

 

LIGHTV1            lights[MAX_LIGHTS];

int                num_lights                  = 0;

就可以在Game_Init()中调用了

     liushuixian.Reset_Lights_LIGHTV1( lights, num_lights );

继续往下走,

定义个8.8.8.a(alpha占8位)格式的32位颜色值

#define _RGBA32BIT(r,g,b,a)                    ((a) + ((b) << 8) + ((g) << 16) + ((r) << 24))

 

设置几个颜色

RGBAV1             white, gray, black, red, green, blue;

 

     white.rgba                                = _RGBA32BIT( 255, 255, 255, 0 );

     gray.rgba                            = _RGBA32BIT( 100, 100, 100, 0 );

     black.rgba                                = _RGBA32BIT( 0, 0, 0, 0 );

     red.rgba                             = _RGBA32BIT( 255, 0, 0, 0 );

     green.rgba                                = _RGBA32BIT( 0, 255, 0, 0 );

     blue.rgba                             = _RGBA32BIT( 0, 0, 255, 0 );

接下来设置环境光的初始化(通过传递参数)

 

int ddraw_liushuixian::Init_Light_LIGHTV1ddraw_math * math2, LIGHTV1_PTR lights, int index, int _state, int _attr, RGBAV1 _c_ambient, RGBAV1 _c_diffuse, RGBAV1 _c_specular, POINT4D_PTR _pos, VECTOR4D_PTR _dir, float kc, float kl, float kq, float _spot_inner, float _spot_outer, float _pf )

{

     if ( index < 0 || index >= MAX_LIGHTS )

     {

         return ( 0 );

     }

 

     //初始化光源

     lights[index].state                                = _state;

     lights[index].id                               = index;

     lights[index].attr                             = _attr;

     lights[index].c_ambient                        = _c_ambient;

     lights[index].c_diffuse                        = _c_diffuse;

     lights[index].c_specular                       = _c_specular;

     lights[index].kc                               = kc;

     lights[index].kl                               = kl;

     lights[index].kq                               = kq;

     if ( _pos )

     {

         math2->VECTOR4D_COPY(_& lights[index].pos, _pos );      //光源位置

        

     }

     if ( _dir )

     {

         math2->VECTOR4D_COPY( & lights[index].dir, _dir );      //光源方向

         //归一化

         math2->VECTOR4D_Normalize( & lights[index].dir );

 

     }

 

     lights[index].spot_inner                       = _spot_inner;

     lights[index].sport_outer                      = _spot_outer;

     lights[index].pf                               = _pf;

 

     //返回光源索引

     return index;

}

 

下面定义了光源的几个常量

 

#define                LIGHTV1_ATTR_AMBIENT                 0x0001        //环境光源

#define                LIGHTV1_ATTR_INFINITE                0x0002        //无穷远光源

#define                LIGHTV1_ATTR_POINT                   0x0004        //点光源

#define                LIGHTV1_ATTR_SPOTLIGHT1              0x0008        //1类(简单)聚光灯

#define                LIGHTV1_ATTR_SPOTLIGHT2              0x0010        //2类(复杂)聚光灯

 

#define                LIGHTV1_STATE_ON                     1             //光源打开

#define                 LIGHTV1_STATE_OFF                    0             //光源关闭

突然感觉应该加个ddraw_light类,把灯光加上去。

调整后,头文件改为

#pragma once

#include "common.h"

#include "ddraw_math.h"

 

#define                LIGHTV1_ATTR_AMBIENT                 0x0001        //环境光源

#define                LIGHTV1_ATTR_INFINITE                0x0002        //无穷远光源

#define                LIGHTV1_ATTR_POINT                   0x0004        //点光源

#define                LIGHTV1_ATTR_SPOTLIGHT1              0x0008        //1类(简单)聚光灯

#define                LIGHTV1_ATTR_SPOTLIGHT2              0x0010        //2类(复杂)聚光灯

 

#define                LIGHTV1_STATE_ON                     1             //光源打开

#define                LIGHTV1_STATE_OFF                    0             //光源关闭

 

#define                MAX_LIGHTS                                8

 

 

typedef struct RGBAV1_TYPE

{

 

     union

     {

 

         int      rgba;         //压缩格式

         UCHAR    rgba_M[4];    //数组格式

         struct

         {

              UCHAR    a, b, g, r;        //显式名称格式

         };

     };

}RGBAV1, * RGBAV1_PTR;

 

typedef struct LIGHTV1_TYP

{

     int                state;             //光照状态

     int                id;                //光源ID

     int                attr;              //光源类型及其他属性

 

     RGBAV1             c_ambient;         //环境光强度

     RGBAV1             c_diffuse;         //散射光强度

     RGBAV1             c_specular;        //镜面反射光强度

     POINT4D            pos;          //光源位置

     VECTOR4D      dir;          //光源方向

     float              kc,kl,kq;     //衰减因子

     float              spot_inner;        //聚光灯内锥角

     float              sport_outer//聚光灯外锥角

     float              pf;                //聚光灯指数因子

 

}LIGHTV1, * LIGHTV1_PTR;

 

 

class DDRAW_LIGHT

{

public:

     DDRAW_LIGHT(void);

     ~DDRAW_LIGHT(void);

 

public:

     int      Init_Light_LIGHTV1(

         ddraw_math    *    math2,

         LIGHTV1_PTR        lights,

         int                index,                 //要创建的光源的索引(到MAX_LIGHTS-1)

         int                _state,                //光源状态

         int                _attr,                 //光源类型及其他属性

         RGBAV1             _c_ambient,            //环境光强度

         RGBAV1             _c_diffuse,            //散射光强度

         RGBAV1             _c_specular,       //镜面反射光强度

         POINT4D_PTR        _pos,                  //光源位置

         VECTOR4D_PTR  _dir,                  //光源方向

         float              kc,

         float              kl,

         float              kq,                //衰减因子

         float              _spot_inner,       //聚光灯内锥角

         float              _spot_outer,       //聚光灯外锥角

         float              _pf                    //聚光灯指数因子                                                     

         );

         int                                  Reset_Lights_LIGHTV1( LIGHTV1_PTR lights, int num_lights );

 

};

 

然后,初始化几个灯,并归入数组中,

环境光

 

     light.Init_Light_LIGHTV1( math, lights, AMBIENT_LIGHT_INDEX, LIGHTV1_STATE_ON, LIGHTV1_ATTR_AMBIENT, gray, black, black, NULL, NULL, 0, 0, 0, 0, 0, 0 );

VECTOR4D      dlight_dir             = { -1, 0, -1, 0 };

     //方向光

     light.Init_Light_LIGHTV1( math, lights, INFINITE_LIGHT_INDEX, LIGHTV1_STATE_ON, LIGHTV1_ATTR_INFINITE, gray, black, black, NULL, &dlight_dir, 0, 0, 0, 0, 0, 0 );

//点光源

     VECTOR4D      plight_pos             = { 0, 200, 0, 0 };

     light.Init_Light_LIGHTV1( math, lights, POINT_LIGHT_INDEX, LIGHTV1_STATE_ON, LIGHTV1_ATTR_POINT, black,green, black, &plight_pos, NULL, 0, 0.001, 0, 0, 0, 1 );

     //聚光灯

     VECTOR4D      slight_pos             =  { 0, 200, 0, 0 };

     VECTOR4D      slight_dir             = { -1, 0, -1, 0 };

     light.Init_Light_LIGHTV1( math, lights, SPOT_LIGHT_INDEX, LIGHTV1_STATE_ON, LIGHTV1_ATTR_SPOTLIGHT2, black,red, black, &slight_pos, &slight_dir, 0, 0.001, 0, 0, 0, 1 );

 

 

下面是RGB共24位如何进行映射到8位模式下的着色方法,昨天看得云里雾里,今天终于看明白了。

其实就是说,2的24次方,相当于4G空间,8位着色是256种颜色,这样每种颜色用最小平方法查找距离最相近的,将会很大。那怎么办呢?先改为16位模式,再查找相近的,2的16次方是64KB,16位有5.5.5和5.6.5两种格式,转换方法就是,5.6.5就是R>>3,G>>2,B>>3;5.5.5就是都>>3

先设定一个查找表和调色板,

先设置一个返回

LPPALETTEENTRY DDRAW_Interface::getPalette()

{

     return palette;

}

一个全局查找表

UCHAR              rgblookup              = ( UCHAR * ) malloc(65536);

 

int DDRAW_Interface::RGB_16_8_IndexedRGB_Table_Builder( int rgb_format, UCHAR * rgblookup )

{

     if ( ! palette || ! rgblookup )

     {

         return -1;

     }

 

     if ( rgb_format == DD_PIXEL_FORMAT565)

     {

         for ( int rgbindex = 0; rgbindex < 65536; rgbindex ++)

         {

              int           curr_index         = -1;

              long     curr_error         = INT_MAX;

              for( int color_index = 0; color_index < 256; color_index++)

              {

                   int      r                  = ( rgbindex >> 11 ) << 3;

                   int      g                  = ( ( rgbindex >> 5 ) & 0x3f ) << 2;

                   int      b                  = ( rgbindex & 0x1f ) << 3;

 

                   long delta_red     = abs( palette[color_index].peRed - r );

                   long delta_green        = abs( palette[color_index].peGreen - g );

                   long delta_blue         = abs( palette[color_index].peBlue - b );

                   long error              = ( delta_red * delta_red ) + ( delta_green * delta_green ) + ( delta_blue * delta_blue );

 

                   //是否更近?

                   if ( error < curr_error)

                   {

                       curr_index             = color_index;

                       curr_error             = error;

                   }

 

              }

              //找到最近的索引后,将其存储到存储表中

              rgblookup[rgbindex]              = curr_index;

         }

     }

     else

 

         if ( rgb_format == DD_PIXEL_FORMAT555)

         {

              for ( int rgbindex = 0; rgbindex < 32768; rgbindex ++)

              {

                   int           curr_index         = -1;

                   long     curr_error         = INT_MAX;

                   for( int color_index = 0; color_index < 256; color_index++)

                   {

                       int      r                  = ( rgbindex >> 10 ) << 3;

                       int      g                  = ( ( rgbindex >> 5 ) & 0x3f ) << 2;

                       int      b                  = ( rgbindex & 0x1f ) << 3;

 

                       long delta_red     = abs( palette[color_index].peRed - r );

                       long delta_green        = abs( palette[color_index].peGreen - g );

                       long delta_blue         = abs( palette[color_index].peBlue - b );

                       long error              = ( delta_red * delta_red ) + ( delta_green * delta_green ) + ( delta_blue * delta_blue );

 

                       //是否更近?

                       if ( error < curr_error)

                       {

                            curr_index             = color_index;

                            curr_error             = error;

                       }

 

                   }

                   //找到最近的索引后,将其存储到存储表中

                   rgblookup[rgbindex]              = curr_index;

              }

         }

 

}

 

在GAME_INIT()建立索引表

     ddraw->RGB_16_8_IndexedRGB_Table_Builder( DD_PIXEL_FORMAT565, rgblookup );

在GAME_main()中,每帧设定几个模式

static   int      wireframe_mode         = -1;

     static   int      backface_mode      = 1;

     static   int      light_mode             = 1;

     static   int      help_mode          = 1;

设定光的运动

点光源和聚光灯的运动

     static float  plight_ang                       = 0, slight_ang    = 0;

     lights[POINT_LIGHT_INDEX].pos.x                = 4000 * cosf( plight_ang );

     lights[POINT_LIGHT_INDEX].pos.y                = 200;

     lights[POINT_LIGHT_INDEX].pos.z                = 4000 * sinf( plight_ang );

 

     if ( ( plight_ang += 3) > 360 )

     {

         plight_ang                                     = 0;

     }

     lights[SPOT_LIGHT_INDEX].pos.x                 = 2000 * cosf( slight_ang );

     lights[SPOT_LIGHT_INDEX].pos.y                 = 200;

     lights[SPOT_LIGHT_INDEX].pos.z                 = 2000 * sinf( slight_ang );

 

     if ( ( slight_ang -= 5) > 0 )

     {

         slight_ang                                     = 0;

     }

 

下面进行本DEMO的核心,处理光照了。

函数代码虽然长,但是很好理解,固定着色就直接赋值;恒定着色按照各种光照公式

 

 

int ddraw_liushuixian::Light_OBJECT4DV1_World16( ddraw_math math, int rgb_format, OBJECT4DV1_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,             //全部光源的总体光照效果

                                          shaded_color;                    //最后的颜色

     float                                dp,                                  //点积

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

                                          i,                                   //强度

                                          nl,                                  //法线长度

                                          atten;                               //衰减计算结果

 

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

         ( obj-> state & OBJECT4DV1_STATE_CULLED ) ||

         ! ( obj->state & OBJECT4DV1_STATE_VISIBLE))

     {

         return ( 0 );

     }

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

     {

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

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

              ( curr_poly->state & POLY4DV1_STATE_CLIPPED) ||

              ( curr_poly->state & POLY4DV1_STATE_BACKFACE ))

 

         {

              continue;

         }

 

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

         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 & POLY4DV1_ATTR_SHADE_MODE_FLAT ||

              curr_poly->attr & POLY4DV1_ATTR_SHADE_MODE_GOURAUD )

         {

              //提取多边形颜色的RGB

              if ( rgb_format == DD_PIXEL_FORMAT565 )

              {

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

                   //转换成.8.8格式

                   r_base                                    <<= 3;

                   g_base                                    <<= 2;

                   b_base                                    <<= 3;

              }

              else

              {

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

                   //转换成.8.8格式

                   r_base                                    <<= 3;

                   g_base                                    <<= 3;

                   b_base                                    <<= 3;

              }

 

              //初始化总体光照颜色

              r_sum                                          = 0;

              g_sum                                          = 0;

              b_sum                                          = 0;

 

              //遍历光照

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

              {

                   //光源是否被打开

                   if ( lights[curr_light].state)

                   {

                        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 )

                   {

                       VECTOR4D u, v, n;

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

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

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

 

                       nl                                   = math.VECTOR4D_length(&n);

 

                       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 )

                       {

                            VECTOR4D u, v, n, l;

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

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

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

 

                            nl                                   = math.VECTOR4D_length(&n);

 

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

                            math.VECTOR4D_Build( & obj->vlist_trans[vindex_0], & 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 )

                            {

                                 VECTOR4D u, v, n, l;

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

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

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

 

                                 nl                                   = math.VECTOR4D_length(&n);

 

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

                                 math.VECTOR4D_Build( & obj->vlist_trans[vindex_0], & 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 )

                                 {

                                     VECTOR4D u, v, n, d, s;

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

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

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

 

                                     nl                                   = math.VECTOR4D_length(&n);

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

 

                                     if ( dp > 0 )

                                     {

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

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

                                          dist                        = math.VECTOR4D_length( &s);

 

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

 

                                          if ( dpsl > 0)

                                          {

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

                                               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;

 

              }

 

              //写入颜色

              if ( rgb_format == DD_PIXEL_FORMAT565 )

              {

             

                   shaded_color                                       = _RGB16BIT565( r_sum, g_sum, b_sum );

              }

              else

              if ( rgb_format == DD_PIXEL_FORMAT555 )

              {

                   shaded_color                                       = _RGB16BIT555( r_sum, g_sum, b_sum );

              }

              curr_poly->color                                        = ( int ) ( ( shaded_color << 16 ) | curr_poly->color );

         }

         else

         {

              curr_poly->color                                        = ( int ) ( ( curr_poly->color << 16 ) | curr_poly->color );

 

         }

 

     }

}

                                                 

 

再插入列表前,判断是否光照处理

if ( light_mode == 1)

     {

         liushuixian.Light_OBJECT4DV1_World16( *math, ddraw->getPixelFormat(), &obj_player, &cam, lights, 4 );

                                              }

同样各坦克也是

              if ( light_mode == 1)

                   {

                       liushuixian.Light_OBJECT4DV1_World16(* math, ddraw->getPixelFormat(), &obj_tank, &cam, lights, 4 );

                                                        }

 

塔:

              if ( light_mode == 1)

              {

                   liushuixian.Light_OBJECT4DV1_World16(* math, ddraw->getPixelFormat(), &obj_tower, &cam, lights, 4 );

                                                   }

同样地面也一样

              if ( light_mode == 1)

                   {

                       liushuixian.Light_OBJECT4DV1_World16(* math, ddraw->getPixelFormat(), &obj_marker, &cam, lights, 4 );

                                                        }

发现一片漆黑。

弄个文本ambient.txt,发现正确

 

后来发现开关相反,改正后OK了

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2014年3月8日星期六(DEMO8-5恒定着色) 的相关文章

随机推荐

  • 国内DNS首选

    配置最快的DNS 为了提高网页的访问打开速度我们可以配置一些解析速度较快的dns 下面作者搜集了一些常用的DNS地址 可以根据自己所在地区可以选择不同的dns 首先可以在我们的客户端打开终端命令行工具测试一些 去ping 一下下面的这些dn
  • java图片上传服务器返回访问地址

    application xml 单个数据的大小 multipart maxFileSize 10Mb 总数据的大小 multipart maxRequestSize 10Mb 文件上传目录 window是d e f盘 linux是 注意Li
  • Ubuntu 64位编译32位程序

    title Ubuntu 64位编译32位程序 背景 一般情况下 一个平台上只能编译当前平台对应的应用程序 比如 64位平台编译64位应用程序 但是随着64位平台的普及 多数采用了64位操作系统 而有时又基于某些原因需要编译出32位的应用程
  • 数学公式公式获取工具 Mathpix snipping Tool

    先上下载地址 链接 https pan baidu com s 1Ac9 f9vdeuLGD hUburYgg 提取码 6e3z 使用 ctrl alt m 截取公式 如图 复制LaTeX 然后要用上Typora 下载地址 Typora 下
  • Android开发中遇到mBluetoothAdapter.startDiscovery()搜索不到任何蓝牙设备

    最近在更新开发公司的APP应用程序 版本已经都开发完成了 准备做发布的时候 突然我们的一个程序员反馈 在他的手机上测试 APP程序无法搜索到任何的蓝牙设备 于是我就懵逼了 因为APP程序已经在Android 6 0 9 0的几台真机上都测试
  • 冒泡排序(Bubble Sort)(代码+动画)

    重复地走访过要排序的数列 一次比较两个元素 如果它们的顺序错误就把它们交换过来 1 1 算法描述 比较相邻的元素 如果第一个比第二个大 就交换它们两个 每次排完 最后的元素应该会是最大的数 总共比较数组长度 1次 1 2 动画演示 1 3代
  • VSCode Docker linux环境开发 for Windows 10

    本文利用vscode Remote Containers插件与Docker在windos平台实现linux环境开发 Docker 1 下载 Docker Desktop Docker Desktop for Windows 2 安装Dock
  • 机器人传感器网络的覆盖优化和空间负载均衡

    qquad 文中主要研究具有区域约束的机器人网络执行静态最优覆盖 给定密度函数描述事件发生的概率 执行函数 p e r f o r
  • maven 打包时动态替换properties,xml资源文件中的配置值

    pom build节点下面添加resource配置 html view plain copy
  • Qt GlobalColor 颜色、及其显示

    Qt Namespace The Qt namespace contains miscellaneous identifiers used throughout the Qt library More Header include
  • Matlab下地形图绘图包m_map绘图包绘制高分辨率海岸线、国界线与河流

    1 前言 之前说了m map的下载 安装与基本使用 Matlab下地形图绘图包m map安装与使用 以及晕渲地形图的绘制 m map绘制晕渲 shaded relief 地形图 现在再说一下高分辨率海岸线 国界线与河流的绘制 2 安装 高分
  • ubuntu软件更新源,更改,可提高更新的速度,移动端app开发

    6 安装系统更新 打开 系统 gt 系统管理 gt 更新管理器 安装更新 完成后若系统提示重新启动 请重新启动系统 如果你是校园网用户 请查看 Ubuntu11 04教育网源 下面是Ubuntu 11 04一些常见的源 Ubuntu官方源
  • 毕业设计 stm32人脸识别系统 - 单片机 物联网 嵌入式 机器视觉

    文章目录 0 前言 1 简介 2 主要器件 3 实现效果 4 设计原理 K210实现人脸识别 5 部分核心代码 6 最后 0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这
  • docker清理磁盘占用

    我的个人博客 逐步前行STEP 1 docker system df 查看docker磁盘占用 2 docker system prune Docker 的 docker system prune 命令可以删除那些已停止的容器 dangli
  • 关于uart串口接收端乱码问题

    问题 在给gd32f303单片机封装串口驱动时 发现接收端乱码 解决 经排查发现是系统时钟不准 经过调整内部时钟后成功解决问题 注 异步通信协议uart依赖双方时钟的准确 任一方时钟不准都会导致乱码问题 其他导致串口出问题的原因 1 分开的
  • Java毕设项目二手交易市场整站源码 校园转转二手市场源码

    本篇为大家带来的是Java开源项目 校园二手交易平台 可以用来做实战演练 也可以用来做毕业设计 校园转转二手市场源码分享 Java写的应用 改成本毕设啥还是挺不错的 mybatis plus 和 Hibernate随心用 基于 Java 开
  • Android 更新UI方法的深度解析

    1 Handler public class SecondActivity extends Activity private static final int MSG WHAT 101 TextView tv Button btn priv
  • Unity 制作动画 - Animation 的使用

    1 unity 顶部导航栏点击 Window gt Animation 打开 Animation 窗口 通过这个窗口可以创建 编辑动画 也可以查看导入的动画 Animation 窗口同一时间只能查看 编辑同一段Clip中的动画 2 选中 H
  • MySQL的auto_increment使用

    说明 总结自 mysql技术内幕 第5版 创建auto increment列要遵循如下规则 每个表只能有一个列具有auto increment属性 且必须为整数数据类型 当然 也支持浮点类型 但强烈不建议 该列必须建立索引 最常见的就是使用
  • 2014年3月8日星期六(DEMO8-5恒定着色)

    恒定着色是在多边形由一种材质构成 多边形的每个点的面法线都相同 因此 只需对一个顶点的像素的光照情况对整个多边形进行着色 对于平面组成的物体 是可行的 但是如果对曲面组成的物体 会导致物体看起来由多边形组成 在16位着色下 光照步骤为 1