Direct3D中的顏色表示
顏色在Direct3D中占據比較重要的位置,所有的操作無論是光照還是紋理貼圖,其結果最終都歸結到如何影響每個頂點或像素的顏色。
1、用DWORD定義顏色
struct sCustomVertex
{
float x, y, z, rhw;
DWORD color;
};
用DWORD類型定義的參數color的取值是一個32位無符號長整數。這32位每8位一組,從左至右分為4組,第一組表示透明度,第二組表示顏色中的紅色成分,第三組表示綠色成分,第四組表示藍色成分。四組數按圖形學中三原色原理組合決定一個頂點的顏色。每組數的取值范圍是0~255。這些數值通常用16進制表示,例如:
sCustomVertex vertices[] =
{
{ 100.0f, 650.0f, 0.5f, 1.0f, 0xffff0000, }, // 不透明,紅色
{ 500.0f, 100.0f, 0.5f, 1.0f, 0xff00ff00, }, // 不透明,綠色
{ 900.0f, 650.0f, 0.5f, 1.0f, 0xff0000ff, }, // 不透明,藍色
};
2、用D3DCOLOR定義顏色
D3DCOLOR是Direct3D中定義的一個表示顏色的變量類型,事實上,它和DWORD顏色類型本質是一樣的,在Direct3D中D3DCOLOR類型的定義為:
typedef DWORD D3DCOLOR;
由于DWORD和D3DCOLOR都使用一個32位無符號長整數定義一個顏色,使用不便,所以在Direct3D中定義了許多宏來方便地指定顏色,常見的有D3DCOLOR_ARGB,它的定義為:
// maps unsigned 8 bits/channel to
D3DCOLOR
#define D3DCOLOR_ARGB(a,r,g,b) \
((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
在這種顏色類型中,用透明度、紅色成分、綠色成分、藍色成分來初始化一個顏色值。其中參數a表示顏色的透明度,參數r表示紅色成分,參數g表示綠色成分,參數b表示藍色成分。各個參數的取值范圍都是0~255。
類似的還有宏D3DCOLOR_RGBA和D3DCOLOR_XGBA,它們的定義為:
#define D3DCOLOR_RGBA(r,g,b,a)
D3DCOLOR_ARGB(a,r,g,b)
#define D3DCOLOR_XRGB(r,g,b) D3DCOLOR_ARGB(0xff,r,g,b)
需要注意的是,宏D3DCOLOR_XGBA中不包含a,即不指定透明度,而默認完全不透明。
3、用D3DCOLORVALUE定義顏色
可以使用結構體D3DCOLORVALUE來定義Direct3D中的顏色,這種顏色類型多用于指定燈光和材質的顏色,結構體D3DCOLORVALUE的定義如下:
typedef struct _D3DCOLORVALUE {
float r;
float g;
float b;
float a;
} D3DCOLORVALUE;
結構體中的各個成員都是浮點型,其取值范圍是0.0~1.0,當全部取0.0時為黑色。其中,r表示顏色的紅色成分,g表示顏色的綠色成分,b表示顏色的藍色成分,a表示顏色的alpha成分,即透明度。
需要注意的是,可以使結構體成員不在0~1之間取值以產生一些特殊效果,當取值大于1時的效果是強光,幾乎沖掉一個場景;取值為負數時產生弱光,好像從場景中撤掉燈光一樣。
4、用D3DXCOLOR定義顏色
在Direct3D中,還可以使用結構體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;
在Direct3D中,該結構體已經進行了擴展,可以進行賦值、加減、乘除等多項運算。
資源的概念
Direct3D資源是指用來渲染一個場景的紋理或緩沖區。應用程序需要創建、加載、復制、使用資源。Direct3D所有的資源,包括幾何數據資源IDirect3DIndexBuffer9、IDirect3DVertexBuffer9等,都繼承于接口IDirect3DResource9。紋理資源IDirect3DCubeTexture9,IDirect3DTexture9和IDirect3DVolumeTextre9是從接口IDirect3DResource9的子接口IDirect3DBaseTexture9中繼承而來的。
1、資源屬性
所有資源具有下列屬性:
- 用法(usage):資源的使用方法,例如,作為一種紋理或一個渲染目標使用。
- 格式(format):數據的格式,例如一個二維表面的像素格式。
- 內存池(pool):資源所申請的內存存儲空間的類型。
- 類型(type):資源的類型,例如一個頂點緩沖區或一個渲染目標。
(1)資源用法
資源的使用是強制的。在應用程序中,要以特定的操作使用資源,則在創建該資源時就必須指定使用方法。Direct3D定義了一系列的常量(以D3DUSAGE開發的大寫表示符),用來表示資源使用方法,詳細情況請參考DirectX幫助文檔。例如D3DUSAGE_RTPATCHES,D3DUSAGE_NPATCHES和D3DUSAGE_POINTS表示的資源使用方法,通知驅動程序,在緩沖區內的數據將可能用于渲染高序元(high-order
primitives)、網格patches、N-patches和點精靈(point
scripts)。提供這些標志是為了防止沒有主操作(host processing)時硬件不能執行這些操作。因此,驅動將在系統內存中分配這些表面,使CPU可以操作它們。如果驅動完全可以通過硬件實現這些操作,那么就能在顯存中申請這些表面從而避免一次內存復制,這樣至少能提高運行性能兩倍。需要指出的是這些標志提供的信息不是絕對必須的。驅動能檢測到這些將要對數據的操作,并將緩沖區數據移動到系統內存,進行下一幀內容的繪制。
(2)資源格式
有關資源表面格式的詳細內容,可以參考DirectX幫助文檔中枚舉類型D3DFORMAT。
(3)內存池
資源緩沖區所占內存的類型稱為內存池。內存池的值由枚舉類型D3DPOOL指定,該類型定義如下:
typedef enum _D3DPOOL {
D3DPOOL_DEFAULT = 0,
D3DPOOL_MANAGED = 1,
D3DPOOL_SYSTEMMEM = 2,
D3DPOOL_SCRATCH = 3,
D3DPOOL_FORCE_DWORD = 0x7fffffff
} D3DPOOL;
如果在創建資源時使用D3DPOOL_DEFAULT內存池,則Direct3D通常會將資源保存到顯存或AGP內存中,以得到更高的性能,但是,Direct3D設備丟失后,在調用IDirect3DDevice9::Reset()恢復設備前,必須釋放用D3DPOOL_DEFAULT創建的資源,并且在恢復設備后必須重新創建這些資源。
使用D3DPOOL_MANAGED標志創建的資源稱為托管資源。對于托管資源,Direct3D會自動在系統內存中進行備份,當設備丟失時,Direct3D將自動釋放這類資源;恢復設備時也不需要重新創建,Direct3D會自動從系統內存恢復這些資源。
對于那些設備不經常訪問的資源,通常使用D3DPOOL_SYSTEMMEM內存池標志創建。這些資源將常駐系統內存,所以在設備丟失后,這類資源不會丟失,恢復設備時也不需要重新創建。
D3DPOOL_DEFAULT和D3DPOOL_MANAGED資源是最常使用的兩種資源,要牢記這兩種資源在設備丟失和恢復時的區別。不能為同一個對象使用多種內存池,當為一個資源選定一個內存池后,該內存池就不能再改變了。
(4)資源類型
當應用程序調用一個資源創建函數如CreateCubeTexture()時,需要指定資源類型。資源類型由枚舉類型D3DRESOURCETYPE指定,其枚舉類型定義如下:
Defines resource types.
typedef enum D3DRESOURCETYPE
{
D3DRTYPE_SURFACE = 1,
D3DRTYPE_VOLUME = 2,
D3DRTYPE_TEXTURE = 3,
D3DRTYPE_VOLUMETEXTURE = 4,
D3DRTYPE_CubeTexture = 5,
D3DRTYPE_VERTEXBUFFER = 6,
D3DRTYPE_INDEXBUFFER = 7,
D3DRTYPE_FORCE_DWORD = 0x7fffffff,
} D3DRESOURCETYPE, *LPD3DRESOURCETYPE;
Constants
- D3DRTYPE_SURFACE
- Surface resource.
- D3DRTYPE_VOLUME
- Volume resource.
- D3DRTYPE_TEXTURE
- Texture resource.
- D3DRTYPE_VOLUMETEXTURE
- Volume texture resource.
- D3DRTYPE_CubeTexture
- Cube texture resource.
- D3DRTYPE_VERTEXBUFFER
- Vertex buffer resource.
- D3DRTYPE_INDEXBUFFER
- Index buffer resource.
- D3DRTYPE_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in
size. Without this value, some compilers would allow this enumeration to
compile to a size other than 32 bits. This value is not used.
2、管理資源
資源的管理工作涉及兩方面,即將資源從系統內存存儲區提升到設備可用存儲區和將資源從設備可用存儲中拋棄兩個方面。以“最近最少使用”優先原則為基礎,Direct3D建立了自己的管理算法。當資源數量多于在設備可用存儲區中可以同時存在的資源數量,即多于作用于同一幀時的資源時(也就是說,這些資源處于函數調用IDirect3DDevice9::BeginScene()和IDirect3DDevice9::EndScene()之間),Direct3D轉而采用“最近最多使用”優先原則。
不是所有的類型和用法都支持托管資源。例如,用標志D3DUSAGE_RENDERTARGET創建的對象就不支持。另外,對于那些內容頻繁改變的對象,推薦不使用托管資源。例如,一個托管類型的頂點緩沖區資源的每一幀的內容都是不同的,這對于一些硬件來說,會大大降低其運行效率。但是,這對于紋理資源卻不成問題。