Skip to main content
GameDev.net gamedev.net
🔒 Locked

[D3D] Converting d3d9 vertex declaration to d3d8 version

Started by yanuart Mar 30, 2007 at 4:54 PM 2 replies 2.6k views
Original Post
yanuart
yanuart
Hi, I'm currently dealing with porting some graphic code made in D3D9 to make it work in D3D8 (arghhh). I'm currently having some trouble porting the vertex declaration used in vertex shader. In d3d9 you just use CreateVertexDeclaration based on the d3dvertexelement9 to get the interface and use it to create vertex shader, while in d3d8 you need to actually write them by yourself. I was wondering if someone knows how to make d3d8 vertex declaration based on the d3d9vertexelement declaration ?
Ride the thrill of your life
Play Motorama
Namethatnobodyelsetook
Namethatnobodyelsetook
The "types" in DX8 declarations mean nothing. In fact the documentation was mismatched with the .h file making it hard to use. They're just register numbers, and you don't need to follow the documented values at all, as long as your declaration and shader's expectations match.

The declaration starts life as an array of DWORDs filled in with macros. Unlike DX9, you don't specify a stream for each entry. Unlike DX9, you don't specify a offset, it's implied by the datatype of REGs and/or the SKIP count. Unlike DX9, there is no semantic type, just a register number.

1. Start with a D3DVSD_STREAM token

2. Follow it by as many D3DVSD_REG and/or D3DVSD_SKIP as needed. If you vertex contains data you don't want to use in the shader, you can use SKIP. If you want data in the shader, use REG to indicate the shader register and the data type. It may be (it *is*) easier to simply use REG for everything and pick a standard set of registers for your data (ie: position = 0, normal = 1, diffuse = 2, etc.).

3. Repeat 1-2 for other streams as needed.

4. End with a D3DVSD_END

This is then passed into the shader assembler.


Other differences from DX9:

Limited to SM1.1

Declaration is tied to the shader. If you have meshes in 3 vertex formats that all need to use a shader you actually have to compile/assemble the shader 3 times, one for each declaration. I actually had a vertexformat class which had a cache of shaders inside it.

In the shader, you don't declare which register maps to which semantic. The register numbers are in the declaration.
yanuart
yanuart
One thin that I noticed is that the most difficult part in converting the vertex declaration is the lack of vertex type in d3d8. Occasionally I'll encounter something like this that I need to convert to d3d8 vs declaration.

D3DVERTEXELEMENT9 dwVertexDecl[] =
{
{0, 0, D3DDECLTYPE_SHORT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
};

D3DDECLTYPE_SHORT2 (unsigned short 16 bit) doesn't have a proper mapping in d3d8. Is there a way to get around this ?
Ride the thrill of your life
Play Motorama
Namethatnobodyelsetook
Namethatnobodyelsetook
I see a short2 here. I know UBYTE4 isn't supported by nVidia's cards, I'm not sure if any of the other types are optional. You're missing things like USHORT2, and SHORT2N which divides by 32767.

You can get byte data in via D3DCOLOR, short data via SHORT2/SHORT4, and float data in via FLOAT1-4, then scale/bias the data as needed.

You'll need to take your USHORT data and remap it to the range used by signed short data (subtract 32768). Next tell the shader it's signed SHORT2 in the declaration, then in the shader add 32768 back to the number to get your expected range. It's a pain, but it's doable, assuming you have a few instruction slots and constants still free.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.