D3D里面最基本的就是頂點了,雖說一直在用,可是卻也是自己比較模糊的一個點,知道其中的意思,卻不是很清楚,今天就總結一下,掃一下這個盲區:
D3D中的頂點緩沖區的聲明:
LPDIRECT3DVERTEXBUFFER9 g_pVB??????? = NULL;??? //頂點緩沖區對象
通常都是用LPDIRECT3DVERTEXBUFFER9 來聲明頂點緩沖區,它其實就是IDirect3DVertexBuffer9的指針類型,這兩個起到的效果是一樣的。用LPDIRECT3DVERTEXBUFFER9 聲明之后,只是鎮定了一個緩沖區的指針,下面還需要開辟一個緩沖區給這個指針。
在開辟真正的內存之前,我們先看一下頂點格式的定義,D3D里面是采用的靈活頂點格式,這點大家應該都是知道的,下面就來總結一下這些靈活頂點格式都具體有哪些,有什么用處。
一般定義頂點結構的時候都是用一個結構體,當然用類去定義也可以,但是一般沒有那個必要。
struct CUSTOMVERTEX
{
??? FLOAT x, y, z, rhw;
??? DWORD color;
};
在還需要定義一個宏,來向D3D說明一下,自己定義的頂點的格式到底有哪些。
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)? //頂點格式
上面這一句話的意思就是,定義的頂點結構包含:位置變換信息(D3DFVF_XYZRHW)和漫反射顏色信息(D3DFVF_DIFFUSE);
那么,一共都有哪些類型可以定義呢,都有什么樣的用呢。
?
---------------------------------------------------------------------------------------------------------------------------------------
?
Vertex Data Flags
#define | Description | Data order and type |
---|---|---|
D3DFVF_DIFFUSE | Vertex format includes a diffuse color component. | DWORD in ARGB order. See D3DCOLOR_ARGB. |
D3DFVF_NORMAL | Vertex format includes a vertex normal vector. This flag cannot be used with the D3DFVF_XYZRHW flag. | float, float, float |
D3DFVF_PSIZE | Vertex format specified in point size. This size is expressed in camera space units for vertices that are not transformed and lit, and in device-space units for transformed and lit vertices. | float |
D3DFVF_SPECULAR | Vertex format includes a specular color component. | DWORD in ARGB order. See D3DCOLOR_ARGB. |
D3DFVF_XYZ | Vertex format includes the position of an untransformed vertex. This flag cannot be used with the D3DFVF_XYZRHW flag. | float, float, float. |
D3DFVF_XYZRHW | Vertex format includes the position of a transformed vertex. This flag cannot be used with the D3DFVF_XYZ or D3DFVF_NORMAL flags. | float, float, float, float. |
D3DFVF_XYZB1 through D3DFVF_XYZB5 | Vertex format contains position data, and a corresponding number of weighting (beta) values to use for multimatrix vertex blending operations. Currently, Direct3D can blend with up to three weighting values and four blending matrices. For more information about using blending matrices, see Indexed Vertex Blending (Direct3D 9). | 1, 2, or 3 floats. When D3DFVF_LASTBETA_UBYTE4 is used, the last blending weight is treated as a DWORD. |
D3DFVF_XYZW | Vertex format contains transformed and clipped (x, y, z, w) data. ProcessVertices does not invoke the clipper, instead outputting data in clip coordinates. This constant is designed for, and can only be used with, the programmable vertex pipeline. | float, float, float, float |
?
Texture Flags
?
#define | Description |
---|---|
D3DFVF_TEX0 - D3DFVF_TEX8 | Number of texture coordinate sets for this vertex. The actual values for these flags are not sequential. |
D3DFVF_TEXCOORDSIZEN(coordIndex) | Define a texture coordinate data set. n indicates the dimension of the texture coordinates. coordIndex indicates texture coordinate index number. See D3DFVF_TEXCOORDSIZEN and Texture coordinates and Texture Stages. |
?
Mask Flags
?
#define | Description |
---|---|
D3DFVF_POSITION_MASK | Mask for position bits. |
D3DFVF_RESERVED0, D3DFVF_RESERVED2 | Mask values for reserved bits in the FVF. Do not use. |
D3DFVF_TEXCOUNT_MASK | Mask value for texture flag bits. |
?
Miscellaneous Flags
?
#define | Description |
---|---|
D3DFVF_LASTBETA_D3DCOLOR | The last beta field in the vertex position data will be of type D3DCOLOR. The data in the beta fields are used with matrix palette skinning to specify matrix indices. |
D3DFVF_LASTBETA_UBYTE4 | The last beta field in the vertex position data will be of type UBYTE4. The data in the beta fields are used with matrix palette skinning to specify matrix indices. // Given the following vertex data definition:
struct VERTEXPOSITION
{float pos[3];union {float beta[5];struct{float weights[4];DWORD MatrixIndices; // Used as UBYTEs}}
};
Given the FVF is declared as: D3DFVF_XYZB5 | D3DFVF_LASTBETA_UBYTE4. Weight and MatrixIndices are included in beta[5], where D3DFVF_LASTBETA_UBYTE4 says to interpret the last DWORD in beta[5] as type UBYTE4. |
D3DFVF_TEXCOUNT_SHIFT | The number of bits by which to shift an integer value that identifies the number of texture coordinates for a vertex. This value might be used as shown below. DWORD dwNumTextures = 1; // Vertex has only one set of coordinates.// Shift the value for use when creating a
// flexible vertex format (FVF) combination.
dwFVF = dwNumTextures << D3DFVF_TEXCOUNT_SHIFT;// Now, create an FVF combination using the shifted value. |
?
Examples
The following examples show other common flag combinations.
// Untransformed vertex for lit, untextured, Gouraud-shaded content.
dwFVF = ( D3DFVF_XYZ | D3DFVF_DIFFUSE );
// Untransformed vertex for unlit, untextured, Gouraud-shaded
// content with diffuse material color specified per vertex.
dwFVF = ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE );
// Untransformed vertex for light-map-based lighting.
dwFVF = ( D3DFVF_XYZ | D3DFVF_TEX2 );
// Transformed vertex for light-map-based lighting with shared rhw.
dwFVF = ( D3DFVF_XYZRHW | D3DFVF_TEX2 );
// Heavyweight vertex for unlit, colored content with two
// sets of texture coordinates.
dwFVF = ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX2 );
?
------------------------------------------------------------------------------------------------------------------
?
?
在頂點結構體中沒有RHW時,Direct3D將執行視、投影、世界等變換以及進行光線計算,之后你才能在窗口中得到你所繪制的物體。當頂點結構體中有RHW時,就像上面那段英文所述,告知Direct3D使用的頂點已經在屏幕坐標系中了,不再執行視圖、投影、世界等變換和光線計算,因為D3DFVF_XYZRHW標志告訴它頂點已經經過了這些處理,并直接將頂點進行光柵操作,任何用SetTransform進行的轉換都對其無效。不過這時的原點就在客戶區的左上角了,其中x向右為正,y向下為正,而z的意義已經變為z-buffer的象素深度。
??? 值得注意的是,D3DFVF_XYZRHW和D3DFVF_XYZ、D3DFVF_NORMAL不能共存,因為后兩個標志與前一個矛盾。在使用這種頂點時,系統需要頂點的位置已經經過變換了,也就是說x、y必須在屏幕坐標系中,z必須是z-buffer中的象素深度,取值范圍:0.0-1.0,離觀察者最近的地方為0.0,觀察范圍內最遠可見的地方為1.0。(不過我測試的時候似乎z值不起作用。)引自:http://www.cppblog.com/lovedday/archive/2009/03/22/48507.html
在定義完頂點格式以后,就要開辟一塊頂點緩沖區:
g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
????????????????????????????????????????????????? 0, D3DFVF_CUSTOMVERTEX,
????????????????????????????????????????????????? D3DPOOL_DEFAULT, &g_pVB, NULL )
開辟緩沖區后,就需要對這個緩沖區進行填寫,那么填寫的數據呢,也需要先指定出來:
CUSTOMVERTEX vertices[] =
??? {
{ 100.0f, 400.0f, 0.5f, 1.0f, 0xffff0000, },
??????? { 300.0f,? 50.0f, 0.5f, 1.0f, 0xff00ff00, },
??????? { 500.0f, 400.0f, 0.5f, 1.0f, 0xff0000ff, },
??? };
然后將數據寫入緩沖區:
VOID* pVertices;
??? if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
??????? return E_FAIL;
??? memcpy( pVertices, vertices, sizeof(vertices) );
??? g_pVB->Unlock();
?