CREATING A VERTEX SHADER INTERFACE DECLARATION

In order to let the driver know the format of the data, you have to create a vertex shader interface declaration, which is somewhat confusingly called just the vertex shader declaration in the DirectX documentation. The vertex shader declaration declares the mapping between input data streams and vertex buffers. This should be the same layout as your vertex elements, along with any "extra" space you might want to allocate for your own purposes (indicated in the stride of the vertex stream). In DirectX 8, the vertex shader and the vertex stream declarations are related, which places some restriction on the vertex stream format when using the FFP. So you can't use extra space in the stream when using the FFP. These restrictions were removed with DirectX 9.

If you want to use the FFP in DirectX 8, then you are restricted to using the flexible vertex types. Your declaration would consist of a union of flexible vertex format (FVF) bit masks. If you don't need any types other than those provided by an FVF format and you don't mind the input registers being mapped to default values, then you can use FVFs for your vertex shaders as well. The declaration for our example would look like the following code:

 // use FVF to define the declaration const unsigned int D3DFVF_MYCUSTOMVERTEX =       ( D3DFVF_XYZ | D3DFVF_NORMAL |         D3DFVF_DIFFUSE | D3DFVF_SPECULAR ) 

When you use FVF code, the vertex shader registers are mapped for you. Table 5.1 lists the FVF codes and the corresponding vertex shader input registers.

Table 5.1: FFP Vertex Shader Register Mapping

FVF

NAME

VERTEX SHADER

D3DFVF_XYZ

D3DVSDE_POSITION

v0

D3DFVF_XYZRHW

D3DVSDE_BLENDWEIGHT

v1

D3DFVF_XYZBI-5

D3DVSDE_BLENDINDICES

v2

D3DFVF_NORMAL

D3DVSDE_NORMAL

v3

D3DFVF_PSIZE

D3DVSDE_PSIZE

v4

D3DFVF_DIFFUSE

D3DVSDE_DIFFUSE

v5

D3DFVF_SPECULAR

D3DVSDE_SPECULAR

v6

D3DFVF_TEX1-8

D3DVSDE_TEXCOORDO-7

v7-v14

 

D3DVSDE_POSITION2

v15

 

D3DVSDE_NORMAL2

v16

Thus for our example, the position, normal, diffuse and specular colors would show up in our vertex shader as register v1, v3, v5, and v6, respectively. Only stream 0 can be used when using an FVF format.

If you decide to use your own format, you specify the shader interface declaration without using a FVF, but rather through using your own custom register declaration. You'll need to create a token/element-size array and associate it with a vertex stream. In DirectX 8, tokens are DWORDs. In DirectX 9, tokens are D3DVERTEXELEMENT9 structures.

You'll use the vertex shader declarator macros to help you create the token array. Typically, you'll give the stream number and the stream elements in order. You'll give a register number and a size for each element in the stream. This will then take data out of the stream and place it into the vertex shader register indicated in the macro. You don't have to declare the registers in any order. The following declarations, when used with the previous vertex element format, take the data from stream 0 and place the position in v1, the normal in v6, the two colors in v3 and v4, respectively.

 // DirectX 8! DWORD MyVertexDeclarator[] = { D3DVSD_STREAM(0),         D3DVSD_REG( 0, D3DVSDT_FLOAT3),         D3DVSD_REG( 6, D3DVSDT_FLOAT3),         D3DVSD_REG( 3, D3DVSDT_D3DCOLOR),         D3DVSD_REG( 4, D3DVSDT_D3DCOLOR),      D3DVSD_END() }; 

It's possible to specify more than one stream in the declaration. The next example takes the format we used in the preceding example and adds two additional streams. In stream 1, we are providing a series of single floating point values (perhaps a blend weight) to show up in register v1, and stream 2 has two floating point values (perhaps texture coordinates) that'll show up in register v2.

 // DirectX 8! DWORD MyOtherVertexDeclarator[] = {      D3DVSD_STREAM(0),         D3DVSD_REG( 0, D3DVSDT_FLOAT3),         D3DVSD_REG( 6, D3DVSDT_FLOAT3),         D3DVSD_REG( 3, D3DVSDT_D3DCOLOR),         D3DVSD_REG( 4, D3DVSDT_D3DCOLOR),      D3DVSD_STREAM(1),         D3DVSD_REG( 1, D3DVSDT_FLOAT1),      D3DVSD_STREAM(2),         D3DVSD_REG( 2, D3DVSDT_FLOAT2),      D3DVSD_END() }; 

In DirectX 9, things are a little different since the vertical pipeline is being prepared for tessellation processing. In addition to the stream and size of the data, you also specify the offset in the stream (it's no longer order dependent), a tessel-lating method, the usage, and the usage index. Once you have the structure, you create the declaration using CreateVertexDeclaration() and then set it using SetVertexDeclaration().

 // DirectX 9! D3DVERTEXELEMENT9 MyDecl[] = {   // stream, offset, type   { 0, 0, D3DDECLTYPE_FLOAT3,      // method, usage, usage index      D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},   { 0, 12, D3DDECLTYPE_FLOAT3,      D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},   { 0, 24, D3DDECLTYPE_FLOAT2,       D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},     // Second stream is second mesh   { 1, 0, D3DDECLTYPE_FLOAT3,       D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1},   { 1, 12, D3DDECLTYPE_FLOAT3,       D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 1}, D3DDECL_END() }; // and to validate and create the tokenized version IDirect3DVDec19* pDecl; g_pD3DDevice->CreateVertexDeclaration( MyDecl, & pDecl ); // Set the declaration g_pD3DDevice->SetVertexDeclaration( pDecl ); 

Once you've decided the format of your vertex data and the mapping to the stream, you're ready to fill your stream.



Real-Time Shader Programming(c) Covering Directx 9. 0
Real-Time Shader Programming (The Morgan Kaufmann Series in Computer Graphics)
ISBN: 1558608532
EAN: 2147483647
Year: 2005
Pages: 104
Authors: Ron Fosner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net