欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

D3D9学习笔记之颜色

程序员文章站 2022-07-02 11:38:15
...

学习目标:

  • 掌握 Direct3D 中颜色的描述方式
  • 理解三角形单元的着色模式

颜色的表示:
在 Direct3D 中,颜色用 RGB 三元组来表示。将颜色分解为红色(Red),绿色(Green),蓝色(Blue),这三个分量的加性混合决定了最终的颜色。我们可用该三个分量的不同组合来表示上百万种颜色。
RGB数据可用两种不同的结构来保存
第一种是结构是 D3DCOLOR,它实际上与 DWORD(unsigned long )类型完全相同,共32位。D3DCOLOR类型中的各位被分成4个8位项,每项存储了一种颜色分量的亮度值。
分配顺序从左至右是 8位给Aloha——8位给红色——8位给绿色——8位给蓝色。
由于每种颜色的分量均占用一个字节,所以每个分量的亮度值范围在0-255区间内,接近0的值表示亮度低,接近255的值表示亮度高。
占用:关于 Alpha分量暂时不理解,以后再做补充。

颜色宏:

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

要指定每个颜色分量的值,并将其插入到 D3DCOLOR 类型的恰当位置上,需要借助位运算。Direct3D 提供了 D3DCOLOR_ARGB 宏帮助我们完成这样的工作。该宏中,前3个参数分别对应3种颜色分量,第4个参数对应 Alpha分量,每个参数必须在0-255区间取值,其调用方法如下:

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

也可以用宏 D3DCOLOR_XRGB 来代替 D3DCOLOR_ARGB,二者很相似,前者总是将 Alpha参数设为255,所以前者不接受 Alpha 参数,调用方法如下:

D3DCOLOR xrgb = D3DCOLOR_XRGB(255,255,10);

第二种结构是 D3DCOLORVALUE 在该结构中,用单精度浮点型数来度量每个颜色的亮度值,亮度值的取值范围为0~1,0表示没有亮度,1表示最大亮度。
我们可以用结构 D3DXCOLOR 代替 D3DCOLORVALUE,前者不但包含了与后者相同的数据成员,而且还提供了一组有用的构造函数和重载运算符,为颜色的运算提供了便利。此外,因为这两种结构所包含的数据成员相同,所以这两种结构可以相互转换。
提示:D3DCOLORVALUE 和 D3DXCOLOR 结构都有4个浮点型成员,这样可以将颜色表达成一个4D向量,标记为(r,g,b,a)。颜色向量的加法,减法以及比例运算与常规的向量完全相同,而颜色向量的点积和叉积没有实际意义,但是对应分量相乘确是有意义的。所以在类 D3DXCOLOR 中,颜色的乘法定义为对应分量分别相乘。

顶点颜色:
图元的颜色由构成该图元的顶点颜色所决定。所以,我们必须为顶点数据结构添加一个表示颜色的数据成员。注意,此处无法使用 D3DCOLORVALUE 结构,因为 Direct3D 希望用一个32位的值来描述顶点的颜色。

struct ColorVertex{
	float x,y,z;						//3D顶点
	D3DCOLOR color;						//颜色
	static const DWORD FVF;				//自定义顶点结构类型
}
const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE;			//初始化顶点结构构型成员

着色:
在光栅化过程中,需要对多边形进行着色。着色规定了如何利用顶点的颜色来计算构成图元的像素颜色。
两种着色模式:平面着色 和 平滑着色
平面着色:每个图元的每个像素都被一致的赋予该图元的第一个顶点所指定的颜色。所以,由3个顶点构成的三角形将是红色的,原因是第一个顶点是红色的。使用平面着色模式时,第二个和第三个顶点的颜色都将被忽略。
平面着色容易使物体出现块状,这是因为各颜色之间没有平滑的过渡。一种更好的着色模式是 Gouraud着色,也称平滑着色,在平滑着色模式下,图元中各像素的颜色值由各顶点的颜色经线性插值得到。
着色模式由 Direct3D 的状态机控制

//设置为平面着色模式,三角形单元的颜色由第一个顶点决定
Device->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_FLAT);
//设置为平滑着色模式,线性插值着色
Device->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD);

在着色模式下应将灯光关闭,因为你没有设置灯光,如果有可以忽略

device->SetRenderState(D3DRS_LIGHTING, false);//true为开,false为关