DirectX9:基础篇 第六章 颜色
一.D3DXCOLOR(颜色结构体)
//全局颜色常量
namespace d3d{
...
const D3DXCOLOR WHITE(D3DCOLOR_XRGB(255,255,255));
const D3DXCOLOR BLACK(D3DCOLOR_XRGB(0,0,0));
const D3DXCOLOR RED(D3DCOLOR_XRGB(255,0,0));
const D3DXCOLOR GREEN(D3DCOLOR_XRGB(0,255,0));
const D3DXCOLOR BLUE(D3DCOLOR_XRGB(0,0,255));
const D3DXCOLOR YELLOW(D3DCOLOR_XRGB(255,255,0));
const D3DXCOLOR CYAN(D3DCOLOR_XRGB(0,255,255));
const D3DXCOLOR MAGENTA(D3DXCOLOR_XRGB(255,0,255));
}
D3DCOLOR color=D3DCOLOR_ARGB(255,255,0); D3DCOLOR_XRGB();
二.D3DCOLORVALUE(颜色类)
D3DCOLORVALUE相比D3DXCOLOR,不仅拥有相同的数据成员,还提供了一组有用的构造函数和重载运算符,为颜色的运算提供了便利.
typedef struct D3DXCOLOR{ #ifdef __cplusplus public: D3DXCOLOR(){} D3DXCOLOR(DWORD argb); D3DXCOLOR(CONST FLOAT* ); D3DXCOLOR(CONST D3DXFLOAT16* ); D3DXCOLOR(CONST D3DXCOLORVALUE& ); 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; D3DXCOLOR& operator += (CONST D3DXCOLOR& ); D3DXCOLOR& operator -= (CONST D3DXCOLOR& ); D3DXCOLOR& operator *= (FLOAT); D3DXCOLOR& operator /= (FLOAT); D3DXCOLOR operator + () const; D3DXCOLOR operator - () const; 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;
三.像素格式
typedef enum _D3DFORMAT { D3DFMT_UNKNOWN = 0, D3DFMT_R8G8B8 = 20, D3DFMT_A8R8G8B8 = 21, D3DFMT_X8R8G8B8 = 22, D3DFMT_R5G6B5 = 23, D3DFMT_X1R5G5B5 = 24, D3DFMT_A1R5G5B5 = 25, D3DFMT_A4R4G4B4 = 26, D3DFMT_R3G3B2 = 27, D3DFMT_A8 = 28, D3DFMT_A8R3G3B2 = 29, D3DFMT_X4R4G4B4 = 30, D3DFMT_A2B10G10R10 = 31, D3DFMT_A8B8G8R8 = 32, D3DFMT_X8B8G8R8 = 33, D3DFMT_G16R16 = 34, D3DFMT_A2R10G10B10 = 35, D3DFMT_A16B16G16R16 = 36, D3DFMT_A8P8 = 40, D3DFMT_P8 = 41, D3DFMT_L8 = 50, D3DFMT_A8L8 = 51, D3DFMT_A4L4 = 52, D3DFMT_V8U8 = 60, D3DFMT_L6V5U5 = 61, D3DFMT_X8L8V8U8 = 62, D3DFMT_Q8W8V8U8 = 63, D3DFMT_V16U16 = 64, D3DFMT_A2W10V10U10 = 67, D3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), D3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), D3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), D3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), D3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), D3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), D3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), D3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), D3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), D3DFMT_D16_LOCKABLE = 70, D3DFMT_D32 = 71, D3DFMT_D15S1 = 73, D3DFMT_D24S8 = 75, D3DFMT_D24X8 = 77, D3DFMT_D24X4S4 = 79, D3DFMT_D16 = 80, D3DFMT_D32F_LOCKABLE = 82, D3DFMT_D24FS8 = 83, D3DFMT_L16 = 81, D3DFMT_VERTEXDATA =100, D3DFMT_INDEX16 =101, D3DFMT_INDEX32 =102, D3DFMT_Q16W16V16U16 =110, D3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M','E','T','1'), // Floating point surface formats // s10e5 formats (16-bits per channel) D3DFMT_R16F = 111, D3DFMT_G16R16F = 112, D3DFMT_A16B16G16R16F = 113, // IEEE s23e8 formats (32-bits per channel) D3DFMT_R32F = 114, D3DFMT_G32R32F = 115, D3DFMT_A32B32G32R32F = 116, D3DFMT_CxV8U8 = 117, D3DFMT_FORCE_DWORD =0x7fffffff } D3DFORMAT;
四.着色处理
着色处理发生在光栅化和指定图元上的顶点颜色计算成像素颜色
1.平面着色(flat shading)
平面着色的像素颜色是均匀的,就是指定图元第一个顶点的颜色,这样第二个和第三个顶点也都是相同的颜色
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
2.高洛德着色(Gouraud shading)
高洛德着色也成为平滑着色,指定是图元表面的颜色是由每个顶点通过线性插值来赋予的
Device->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
五.例子
#include "d3dUtility.h" IDirect3DDevice9* Device = 0; const int Width = 640; const int Height = 480; D3DXMATRIX WorldMatrix; IDirect3DVertexBuffer9* Triangle = 0; struct ColorVertex { ColorVertex(){} ColorVertex(float x, float y, float z, D3DCOLOR c) { _x = x; _y = y; _z = z; _color = c; } float _x, _y, _z; D3DCOLOR _color; static const DWORD FVF; }; const DWORD ColorVertex::FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE; bool Setup() { // // 只有一个三角形顶点缓存 // 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.5f, // 90 - degree (float)Width / (float)Height, 1.0f, 1000.0f); Device->SetTransform(D3DTS_PROJECTION, &proj); // // 关闭灯光 // Device->SetRenderState(D3DRS_LIGHTING, false); return true; } void Cleanup() { d3d::Release<IDirect3DVertexBuffer9*>(Triangle); } 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)); // // 画第一个三角形 // 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; } // // WndProc // LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch( msg ) { case WM_DESTROY: ::PostQuitMessage(0); break; case WM_KEYDOWN: if( wParam == VK_ESCAPE ) ::DestroyWindow(hwnd); break; } return ::DefWindowProc(hwnd, msg, wParam, lParam); } // // WinMain // int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE prevInstance, PSTR cmdLine, int showCmd) { if(!d3d::InitD3D(hinstance, Width, Height, true, D3DDEVTYPE_HAL, &Device)) { ::MessageBox(0, "InitD3D() - FAILED", 0, 0); return 0; } if(!Setup()) { ::MessageBox(0, "Setup() - FAILED", 0, 0); return 0; } d3d::EnterMsgLoop( Display ); Cleanup(); Device->Release(); return 0; }