分享
 
 
 

Direct3D9游戏编程中的颜色

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

4. 颜色

本文译自《Introduction to 3D Game Programming with DirectX 9.0》第四章“Color”,敬请斧正。

本章讨论场景中对象的颜色渲染。通过本章的学习,可以达到如下目标:

l 在Direct3D中如何描述颜色

l 理解颜色是如何被渲染的

4.1. 颜色的表现

在Direct3D中颜色使用RGB表示,也就是说,需要指定红、绿、蓝三原色的值,这三个分量的混合颜色就是最终的颜色。

我们使用两种结构表示RGB数据。第一种是D3DCOLOR类型,其实就是DWORD类型。该类型被分成4个8-bit的部分,分别用于存储颜色的分量。

每种颜色分量都是使用1个字节表示,所以每种颜色分量的亮度范围为0~~255。关于上图中的Alpha分量,目前可以不用理会,在讲述alpha混合时再详细讨论。

正确的填写D3DCOLOR结构中的各个分量需要进行位操作。为此,D3D提供了一个宏D3DCOLOR_ARGB,每个分量需要在0~~255之内。

D3DCOLOR brightRed = D3DCOLOR_ARGB(255, 255, 0, 0);

D3DCOLOR someColor = D3DCOLOR_ARGB(255, 144, 87, 201);

另外,还有一个宏D3DCOLOR_XRGB,它与上面的宏相似,但是不需要提供alpha参数值,而是将其设定为0xFF。

#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b)

在Direct3D中表示颜色的另一种结构是D3DCOLORVALUE。该结构使用浮点数表示颜色的各个分量的值,范围为0.0~~1.0。

typedef struct _D3DCOLORVALUE {

float r; // the red component, range 0.0-1.0

float g; // the green component, range 0.0-1.0

float b; // the blue component, range 0.0-1.0

float a; // the alpha component, range 0.0-1.0

} D3DCOLORVALUE;

有时,还使用D3DXCOLOR结构,它包含与D3DCOLORVALUE相同的数据成员,还有很多有用的构造函数和重载的操作符,这使很多颜色操作十分方便。因这两种数据结构具有相同的数据成员,故很容易在二者之间转换。D3DXCOLOR的定义如下:

typedef struct D3DXCOLOR

{

#ifdef __cplusplus

public:

D3DXCOLOR() {}

D3DXCOLOR( DWORD argb );

D3DXCOLOR( CONST FLOAT * );

D3DXCOLOR( CONST D3DXFLOAT16 * );

D3DXCOLOR( CONST D3DCOLORVALUE& );

D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a );

// casting

operator DWORD () const;

operator FLOAT* ();

operator CONST FLOAT* () const;

operator D3DCOLORVALUE* ();

operator CONST D3DCOLORVALUE* () const;

operator D3DCOLORVALUE& ();

operator CONST D3DCOLORVALUE& () const;

// assignment operators

D3DXCOLOR& operator += ( CONST D3DXCOLOR& );

D3DXCOLOR& operator -= ( CONST D3DXCOLOR& );

D3DXCOLOR& operator *= ( FLOAT );

D3DXCOLOR& operator /= ( FLOAT );

// unary operators

D3DXCOLOR operator + () const;

D3DXCOLOR operator - () const;

// binary operators

D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const;

D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const;

D3DXCOLOR operator * ( FLOAT ) const;

D3DXCOLOR operator / ( FLOAT ) const;

friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR& );

BOOL operator == ( CONST D3DXCOLOR& ) const;

BOOL operator != ( CONST D3DXCOLOR& ) const;

#endif //__cplusplus

FLOAT r, g, b, a;

} D3DXCOLOR, *LPD3DXCOLOR;

显然,结构D3DXCOLOR和D3DCOLORVALUE包含四个浮点数成员,所以可以将颜色看作一个4元向量(r,g,b,a)。颜色向量可以像普通的向量一样进行加、减、乘运算。另外,点积和叉积对颜色向量是没有含义的,而分量相乘却是有意义的。结构D3DXCOLOR定义的颜色与颜色相乘就是颜色分量的相乘,使用符号X表示:

(c1, c2, c3, c4) X (k1, k2, k3, k4) = (c1k1, c2k2, c3k3, c4k4)

4.2. 顶点颜色

几何体的颜色由组成它的顶点的颜色决定。因此,可以我们必须向顶点数据结构中添加颜色成员。在这里,没有采用D3DCOLORVALUE结构描述颜色,因为Direct3D希望使用32-bit的整型数表示颜色。另外,当使用顶点着色器(Vertex Shader)时,将会使用四元向量描述顶点颜色,这是一个128-bit的颜色。到讨论顶点着色器时会详细说明。

struct ColorVertex

{

float _x, _y, _z;

D3DCOLOR _color;

static const DWORD FVF;

}

const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;

4.3. 着色模式

着色发生在光栅化和通过顶点颜色计算像素颜色时。目前常用的有两种着色模式:平坦模式和高洛德模式。

在平坦模式下,像素的颜色一律取组成几何体的第一个顶点的颜色。所以,由下面三个顶点构成的三角形是红色的,因为第一个顶点的颜色是红色,令外两个顶点的颜色会被忽略。

ColorVertex t[3];

t[0]._color = D3DCOLOR_XRGB(255, 0, 0);

t[1]._color = D3DCOLOR_XRGB(0, 255, 0);

t[2]._color = D3DCOLOR_XRGB(0, 0, 255);

平坦模式往往是几何体看起来菱角分明,颜色间缺少平滑的过渡。另外一种较自然的着色模式就是高洛德模式,也叫平滑模式,在这种模式下,顶点的颜色以线形插值方式渲染表面。

在Direct3D中可以使用如下方法设置着色模式:

// set flat shading

Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);

// set Gouraud shading

Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);

4.4. 应用举例:彩色三角形

这个例子用以说明怎样使用平坦模式和高洛德模式渲染彩色三角形。首先,声明如下全局变量:

D3DXMATRIX World;

IDirect3DVertexBuffer9* Triangle = 0;

这里,World是三角形的世界坐标系转换矩阵,Triangle是存储三角形顶点数据的顶点缓冲区指针。这里只存储一个三角形的顶点信息,我们将使用World矩阵在坐标系中不同的位置多次渲染该三角形。

函数setup创建顶点缓冲区,并且填充三角形的顶点数据,最后禁用光照。例子中使用上面所声明的顶点结构ColorVertex,代码如下:

bool Setup()

{

// create vertex buffer

Device->CreateVertexBuffer(

3 * sizeof(ColorVertex),

D3DUSAGE_WRITEONLY,

ColorVertex::FVF,

D3DPOOL_MANAGED,

&Triangle,

0);

// fill the buffers with the triangle data

ColorVertex* v;

Triangle->Lock(0, 0, (void**)&v, 0);

v[0] = ColorVertex(-1.0f, 0.0f, 2.0f, D3DCOLOR_XRGB(255, 0, 0));

v[1] = ColorVertex( 0.0f, 1.0f, 2.0f, D3DCOLOR_XRGB( 0, 255, 0));

v[2] = ColorVertex( 1.0f, 0.0f, 2.0f, D3DCOLOR_XRGB( 0, 0, 255));

Triangle->Unlock();

// set projection matrix

D3DXMATRIX proj;

D3DXMatrixPerspectiveFovLH(

&proj,

D3DX_PI * 0.5f, // 90 - degree

(float)Width / (float)Height,

1.0f,

1000.0f);

Device->SetTransform(D3DTS_PROJECTION, &proj);

// set the render states

Device->SetRenderState(D3DRS_LIGHTING, false);

return true;

}

函数Display使用不同的着色模式在不同的位置渲染该三角形两次,其位置由World矩阵控制:

bool Display(float timeDelta)

{

if( Device )

{

Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);

Device->BeginScene();

Device->SetFVF(ColorVertex::FVF);

Device->SetStreamSource(0, Triangle, 0, sizeof(ColorVertex));

// draw the triangle to the left with flat shading

D3DXMatrixTranslation(&World, -1.25f, 0.0f, 0.0f);

Device->SetTransform(D3DTS_WORLD, &World);

Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);

Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

// draw the triangle to the right with gouraud shading

D3DXMatrixTranslation(&World, 1.25f, 0.0f, 0.0f);

Device->SetTransform(D3DTS_WORLD, &World);

Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);

Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

Device->EndScene();

Device->Present(0, 0, 0, 0);

}

return true;

}

4.5. 总结

l 颜色使用红、绿、蓝三原色的强度描述。在Direct3D中可以使用D3DCOLOR、D3DCOLORVALUE、D3DXCOLOR结构描述颜色。

l 有时将颜色看成四元向量(r,g,b,a)。颜色向量可以像普通向量一样进行加、减、放大操作。另外,颜色向量间的点积和叉积是没有含义的,但是分量间相乘却很有用。

l 可以为顶点指定颜色,然后Direct3D根据当前的着色模式决定如何将顶点的颜色转换到像素。

l 平坦着色模式取第一个顶点的颜色作为几何体像素的颜色;高洛德模式则通过线形插值法计算像素的颜色。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有