【D3D Review】3

来源:互联网 发布:淘宝店铺大码模特招聘 编辑:程序博客网 时间:2024/05/29 11:05
色彩:
D3D中存储颜色的数据结构:
1.D3DCOLOR:
定义: typedef DWORD D3DCOLOR;
就是说D3DCOLOR就是一个DWORD;所以要用宏把颜色分量转化成DWORD。
例如:
  1. D3DCOLOR brightRed = D3DCOLOR_ARGB(255, 255, 0, 0);
  2. D3DCOLOR someColor = D3DCOLOR_ARGB(255, 144, 87, 201);
而D3DCOLOR_XRGB宏就是把高字节设为ff:
  1. #define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b)
2.D3DCOLORVALUE:
定义:
  1. typedef struct _D3DCOLORVALUE {
  2. float r; // the red component, range 0.0-1.0
  3. float g; // the green component, range 0.0-1.0
  4. float b; // the blue component, range 0.0-1.0
  5. float a; // the alpha component, range 0.0-1.0
  6. } D3DCOLORVALUE;
可见能够表示的颜色数更多了,而每个颜色的数据量也大了,4个字,是D3DCOLOR的4倍。

3.D3DXCOLOR:
增加了运算,用起来更为方便。
定义:
  1. typedef struct D3DXCOLOR
  2. {
  3.     #ifdef __cplusplus
  4.     public:
  5.     D3DXCOLOR() {}
  6.     D3DXCOLOR( DWORD argb );
  7.     D3DXCOLOR( CONST FLOAT * );
  8.     D3DXCOLOR( CONST D3DXFLOAT16 * );
  9.     D3DXCOLOR( CONST D3DCOLORVALUE& );
  10.     D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a );
  11.     // casting
  12.     operator DWORD () const;
  13.     operator FLOAT* ();
  14.     operator CONST FLOAT* () const;
  15.     operator D3DCOLORVALUE* ();
  16.     operator CONST D3DCOLORVALUE* () const;
  17.     operator D3DCOLORVALUE& ();
  18.     operator CONST D3DCOLORVALUE& () const;
  19.     // assignment operators
  20.     D3DXCOLOR& operator += ( CONST D3DXCOLOR& );
  21.     D3DXCOLOR& operator -= ( CONST D3DXCOLOR& );
  22.     D3DXCOLOR& operator *= ( FLOAT );
  23.     D3DXCOLOR& operator /= ( FLOAT );
  24.     // unary operators
  25.     D3DXCOLOR operator + () const;
  26.     D3DXCOLOR operator - () const;
  27.     // binary operators
  28.     D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const;
  29.     D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const;
  30.     D3DXCOLOR operator * ( FLOAT ) const;
  31.     D3DXCOLOR operator / ( FLOAT ) const;
  32.     friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR& );
  33.     BOOL operator == ( CONST D3DXCOLOR& ) const;
  34.     BOOL operator != ( CONST D3DXCOLOR& ) const;
  35.     #endif //__cplusplus
  36.     FLOAT r, g, b, a;
  37. } D3DXCOLOR, *LPD3DXCOLOR;
注意:顶点颜色只能是D3DCOLOR(固定管线),D3DXCOLOR不允许进行点积和叉积运算。

光:
D3D中有三种光:
1.Ambient Light【环境光】
2.Diffuse Light【漫射光】
3.Specular Light【镜面光】
  1. // 打开镜面光
  2. Device->SetRenderState(D3DRS_SPECULARENABLE, true);
光用D3DCOLORVALUE或D3DXCOLOR结构来描述:
  1. D3DXCOLOR redAmbient(1.0f, 0.0f, 0.0f, 1.0f);
  2. D3DXCOLOR blueDiffuse(0.0f, 0.0f, 1.0f, 1.0f);
  3. D3DXCOLOR whiteSpecular(1.0f, 1.0f, 1.0f, 1.0f);
D3DXCOLOR用于描述光时,alpha值是忽略的。

材质:
  1. typedef struct _D3DMATERIAL9 {
  2.   D3DCOLORVALUE Diffuse, Ambient, Specular, Emissive;
  3.   float Power;
  4. } D3DMATERIAL9;
Diffuse:指定表面反射漫射光的数量;
Ambient:指定表面反射环境光的数量;
Specular:指定表面反射镜面光的数量;
Emissive:This component is used to add to the overall color of the surface, making it appear brighter like its giving off its own light.
Power:指定镜面高光的锐利程度,值越大高光越锐利。

可用于一个红色物体的材质:
  1. D3DMATERIAL9 red;
  2. ::ZeroMemory(&red, sizeof(red));
  3. red.Diffuse = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f); // red
  4. red.Ambient = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f); // red
  5. red.Specular = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f); // red
  6. red.Emissive = D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f); // no emission
  7. red.Power = 5.0f;
通过设置材质的值来控制反射每种灯光的数量来表现物体的颜色。

固定管线的顶点没有材质属性,需要调用IDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9* pMaterial)方法来设置顶点的材质。
  1. D3DMATERIAL9 blueMaterial, redMaterial;
  2. ...// set up material structures
  3. Device->SetMaterial(&blueMaterial);
  4. drawSphere(); // blue sphere
  5. Device->SetMaterial(&redMaterial);
  6. drawSphere(); // red sphere
类似OpenGL的状态机

顶点法线:

带法线的顶点结构示例:
  1. struct Vertex
  2. {
  3.    float _x, _y, _z;
  4.    float _nx, _ny, _nz;
  5.    static const DWORD FVF;
  6. }
  7. const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL;
单一多边形可以用面法线来代替顶点法线,下面是计算面法线的示例函数:
  1. void ComputeNormal(D3DXVECTOR3* p0,
  2.                     D3DXVECTOR3* p1,
  3.                     D3DXVECTOR3* p2,
  4.                     D3DXVECTOR3* out)
  5. {
  6.     D3DXVECTOR3 u = *p1 - *p0;
  7.     D3DXVECTOR3 v = *p2 - *p0;
  8.     D3DXVec3Cross(out, &u, &v);
  9.     D3DXVec3Normalize(outout);
  10. }
如果一个顶点被多个多边形共享,那么就不可以简单的用其中一个多边形的面法线来代替顶点法线,可以用所有面法线的均值来近似:
Vn = (n0 +n1 + n2+ ...+n(m-1))/m

光源:

点光源:
方向光源:
聚光灯:内外两个光锥,

  1. typedef struct _D3DLIGHT9 {
  2.         D3DLIGHTTYPE Type;          // 指定光源类型,D3DLIGHT_POINT, D3DLIGHT_SPOT,
  3.                                     // D3DLIGHT_DIRECTIONAL
  4.         D3DCOLORVALUE Diffuse;      // 此光源发出的漫射光颜色
  5.         D3DCOLORVALUE Specular;
  6.         D3DCOLORVALUE Ambient;      // 此光源发出的环境光颜色
  7.         D3DVECTOR Position;         // 光源坐标,对方向光无意义
  8.         D3DVECTOR Direction;        // 光源在世界坐标系的照射方向,对点光源无意义
  9.         float Range;                // 照射的距离,对方向光无意义
  10.         float Falloff;              // 只用于聚光灯,内锥到外锥的强度衰减,通常为1.0f
  11.         float Attenuation0;         // 常量衰减,光强的传播距离衰减,不适用于方向光
  12.         float Attenuation1;         // 线性衰减                    
  13.         float Attenuation2;         // 二次衰减        
  14.         float Theta;                // 内锥角度,单位弧度
  15.         float Phi;                  // 外锥角度,单位弧度
  16. } D3DLIGHT9;
D3D中初始化光源的方法:
  1. namespace d3d
  2. {
  3. .
  4. .
  5. .
  6. D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction,D3DXCOLOR* color);
  7. D3DLIGHT9 InitPointLight(D3DXVECTOR3* position,D3DXCOLOR* color);
  8. D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position,D3DXVECTOR3* direction,D3DXCOLOR* color);
  9. }
创建一个平行于x轴正向的方向光
  1. D3DXVECTOR3 dir(1.0f, 0.0f, 0.0f);
  2. D3DXCOLOR c = d3d::WHITE;
  3. D3DLIGHT9 dirLight = d3d::InitDirectionalLight(&dir, &c);
  1. Device->SetLight(
  2.                 0, // element in the light list to set, range is 0-maxlights
  3.                 &light);// address of the D3DLIGHT9 structure to set
  4. Device->LightEnable(
  5.                     0, // the element in the light list to enable/disable
  6.                     true); // true = enable, false = disable