Trying to use HLSL without D3DX datatypes...

Started by
3 comments, last by JasonBlochowiak 17 years, 4 months ago
More specifically, I'm dealing with the issue of interfacing HLSL support with my platform-independent engine. I've heard that using functions like SetVertexShaderConstantF() to modify constants in HLSL shaders is deprecated and that constant tables are the only way to get full use out of the shaders. While I would love to be proven wrong on that account, the use of constant tables presents another problem. Constant tables are purely of the D3DX library, and therefore all of it's functions use D3DX datatypes, like D3DXMATRIX. Given that my engine is intended to be platform-independent, I have my own matrix library. The only way I can see to use both is to manually convert between the two types of matrices, one value at a time, and then feeding the new temporary D3DXMATRIX into the constant table. Which feels ridiculous to have to do. Is there an alternative? I may not get to bypass the constant table completely, but is there a way to get it to play nice with my custom matrices and vertices?
Advertisement
There is nothing in D3DX that you couldn't write yourself, given the time, knowledge, and inclination. You CAN use SetVertexShaderConstantF to bypass using ID3DXConstantTable. The easiest way to do this is to specify explicit register bindings for all of your uniform variables in your shader. For example:
float4x4 cWorldViewProj : register(c0);sampler sDiffuse : register(s0); 
These bindings instruct HLSL how to lay out your constants and samplers. Now, since you know exactly where they all will be, it should be easy to use SetVertexShaderConstantF to update your constants.

As far as converting from your matrix class to D3DXMATRIX: Assuming that your class stores the matrix values in exactly the same order as D3DXMATRIX, you can simply cast it:
*(D3DXMATRIX*) &myCustomMatrix
xyzzy
Quote:Original post by xyzzy00
There is nothing in D3DX that you couldn't write yourself, given the time, knowledge, and inclination. You CAN use SetVertexShaderConstantF to bypass using ID3DXConstantTable. The easiest way to do this is to specify explicit register bindings for all of your uniform variables in your shader. For example:
float4x4 cWorldViewProj : register(c0);sampler sDiffuse : register(s0); 
These bindings instruct HLSL how to lay out your constants and samplers. Now, since you know exactly where they all will be, it should be easy to use SetVertexShaderConstantF to update your constants.

Doesn't hardcoding the registers interfere with the compiler efficiency?

Quote:Original post by xyzzy00
As far as converting from your matrix class to D3DXMATRIX: Assuming that your class stores the matrix values in exactly the same order as D3DXMATRIX, you can simply cast it:
*(D3DXMATRIX*) &myCustomMatrix
xyzzy

So, even with all of the extra code and overloaders and differently-named variables, as long as the specific sequence of data types is the same, it can be cast away? And just assume it works?
Quote:Original post by Nairou
Doesn't hardcoding the registers interfere with the compiler efficiency?
Nope. Just pack them nicely so that you are setting the fewest number of constants with each call to SetVertexShaderConstantF.

Quote:Original post by Nairou
So, even with all of the extra code and overloaders and differently-named variables, as long as the specific sequence of data types is the same, it can be cast away? And just assume it works?
Correct. If the layout of the data is the same, how you interpret it is up to you. Just make sure that your matrix class has the same layout, and has no virtual methods.

xyzzy
I also have hard-bound my shader constants to specific registers. This lets me set them once when the C++ side value changes, as opposed to potentially needing to set them for each shader.

This topic is closed to new replies.

Advertisement