Matrix Palette Skinning in HLSL
I am working on skinning in my engine, but am having trouble implementing and setting my array of bone matrices in my shader. In ASM, I just set the specific constants per register number, but in HLSL, I have to look up based on the constant name. In my shader, I have this:
static const int _MAX_BONES = 25;
float4x4 C_BONES[_MAX_BONES];
In my C code, my shader is compiled via the D3DX call D3DXCompileShader, which gives me a pointer to a ID3DXConstantTable interface. I tried calling GetConstantByName(NULL, "C_BONES"), but it returns NULL. For regular constants (non arrays), this works, and I can pass that handle to SetMatrix (or SetVector) through my constants interface. Why doesn't this work for arrays? Do I need to declare them differently or set them differently when setting the constants?
I tried looking over the example in the D3D SDK, but it's handled differently (through FX files and interfaces, which I am not using), so it hasn't been overly helpful.
Try doing a command-line compile of your shader using fxc.exe and specifying /Cc /Fc "shader.html" as additional parameters. You can then open the file in your favourite browser to see what it generates. The trick being that it'll print the constant table as a comment at the top of the HTML page.
I've found that useful when it comes to "hooking up" HLSL shader variables in pure shaders. Especially when you unexpectedly optimize away a variable.
Failing that you can always run-time inspect the shader via the various ID3DXConstantTable enumerations. Using ::GetDesc() and looping through the ::GetConstant() and ::GetConstantDesc() functions should give you the same information.
hth
Jack
I've found that useful when it comes to "hooking up" HLSL shader variables in pure shaders. Especially when you unexpectedly optimize away a variable.
Failing that you can always run-time inspect the shader via the various ID3DXConstantTable enumerations. Using ::GetDesc() and looping through the ::GetConstant() and ::GetConstantDesc() functions should give you the same information.
hth
Jack
I have this in my .fx file:
uniform extern float4x4 g_BonePalette[40];
And do this in my program:
LPD3DXEFFECT mEffect;
D3DXHANDLE mHTbl;
mHTbl = mEffect->GetParameterByName(0, "g_BonePalette");
uniform extern float4x4 g_BonePalette[40];
And do this in my program:
LPD3DXEFFECT mEffect;
D3DXHANDLE mHTbl;
mHTbl = mEffect->GetParameterByName(0, "g_BonePalette");
Aha, I ended up doing something similar inside the program itself. When I was trying to compile or set constants, I would log all the constants from the table for the current shader. I discovered my error was with my shader management rather then the table itself. I wasn't accessing the correct table for the shader I was trying to use. : )
Hi,
Regarding the "setting" of matrices: I've always used SetMatrixArray() for this. It just accepts an array of matrices. The 3rd argument specifies how much matrices are being sent over.
Hope it's of some use :)
Regarding the "setting" of matrices: I've always used SetMatrixArray() for this. It just accepts an array of matrices. The 3rd argument specifies how much matrices are being sent over.
Hope it's of some use :)
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement