在Direct3D中颜色用RGB三元组来表示,RGB数据可用俩种不同的结构来保存,第一种是D3DCOLOR,它实际上与DWORD类型完全相同,共有32位,D3DCOLOR类型种的各位被分成四个8位项,每项存储了一种颜色分量的亮度值。
由于每种颜色分量占一个字节,所以每个分量的亮度值范围在[0,255]区间内,接近0的值表示低亮度,接近255的值表示高亮度。
可以使用D3DCOLOR_XRGB和D3DCOLOR_ARGB来为D3DCOLOR赋值,二者的区别是前者不接收Alpha参数,其实前者试讲Alpha分量设为0xff(255)。
#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b)
D3DCOLOR brightRed = D3DCOLOR_ARGB(255,155,0,0);
在Direct3D中存储颜色的另一种结构是D3DCOLORVALUE,在该结构中我们用单精度浮点数来度量每个颜色分量的亮度值,亮度值的取值范围为0~1(0表示没有亮度,1表示亮度最大)
typedef struct D3DCOLORVALUE {
float r;
float g;
float b;
float a;
} D3DCOLORVALUE;
我们也可以用结构D3DXCOLOR替代D3DCOLORVALUE,前者不但包含了后者相同的数据成员,而且还提供了一组有用的构造函数和重载运算符,为颜色的运算提供了便利,这俩种类型可以相互转换
着色
在光栅化过程中,需要对多边形进行着色,着色规定了如何利用顶点的颜色来计算构成图元的像素的颜色,目前使用平面着色和Gouraud着色。如果使用平面着色,每个图元的每个像素都被一直地赋予该图元的第一个顶点所指定的颜色。
平面着色容易使物体呈现出“块状”,这是因为各颜色之间没有平滑地过渡,一种更好的着色模式是Gouraud着色(平滑着色),在该模式下各顶点的颜色经线性插值得到。
如同Direct3D中的许多其他状态量一样,着色模式由Direct3D状态机控制
//设置平面着色
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
//设置平滑着色
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
着色例程
bool SetUpTriangle()
{
Device->CreateVertexBuffer(3 * sizeof(ColorVertex), D3DUSAGE_WRITEONLY, ColorVertex::FVF, D3DPOOL_MANAGED, &Triangle, 0);
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();
D3DXMATRIX proj;
D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI*0.5, (float)Width / (float)Height, 1.0f, 1000.0f);
Device->SetTransform(D3DTS_PROJECTION, &proj);
return true;
}
bool DisplayTriangle(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));
D3DXMatrixTranslation(&WorldMatrix, -1.25f, 0.0f, 0.0f);
Device->SetTransform(D3DTS_WORLD, &WorldMatrix);
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
D3DXMatrixTranslation(&WorldMatrix, 1.25f, 0.0f, 0.0f);
Device->SetTransform(D3DTS_WORLD, &WorldMatrix);
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
Device->EndScene();
Device->Present(0, 0, 0, 0);
}
return true;
}