🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

(Legacy, DX9) GetConstantByName always returning a null handle

Started by
3 comments, last by 21st Century Moose 3 years, 3 months ago

Hi all, I'm new here... I hope you can help!

I've been tasked with making an OpenGL framework use DirectX. I'm limited to DirectX9 and v2.0 of the shaders.

Although each version (DX or GL) of the framework will have their own shaders, I'm trying to make portable functions and methods to DEAL with the shaders (i.e. a portable CompileShader, a portable SetUniform, etc).

So the issue I'm running into is, I'm not able to retrieve a handle to the shader variables in DirectX. If I use them as registers, I can do it that way, but for compatibility with GL, I would like to fetch them by name.

Here is my vertex shader code (very simple shader, just trying to figure out what's what right now):

float4x4 gMyMatrix;
struct VS_OUTPUT
{
   float4 xyz : POSITION;
   float4 diffuse : COLOR0;
   float2 uv : TEXCOORD0;
};

VS_OUTPUT main(in float4 xyz : POSITION, in float4 diffuse : COLOR0, in float2 uv : TEXCOORD0)
{
   VS_OUTPUT Output;
   Output.xyz = mul(xyz,gMyMatrix);
   Output.diffuse=diffuse;
   Output.uv=uv;
   return Output;
}

I'm compiling the shader like this, to get the Constants table:

LPD3DXBUFFER aVShaderCode=NULL;
ID3DXConstantTable* aConstants=NULL;
LPD3DXBUFFER aErrorList=NULL;
D3DXCompileShader(ShaderString,strlen(ShaderString),NULL,NULL,"main","vs_2_0",&aVShaderCode,&aErrors,&aConstants);

It compiles okay... but I want to get a handle to gMyMatrix in the same way you'd get a handle to a uniform variable in OpenGL... so I tried this:

D3DXHANDLE aHandle=aConstants->GetConstantByName(NULL,"gMyMatrix");

My problem is, the handle always returns a null handle, no matter what I do. Can anyone see anything what I'm doing wrong here? Some improper initialization? Some way of tagging that variable so that it's accessible through the constant table?

Any help or suggestions appreciated!

Advertisement

It's been forever since I did any D3D9, so my memory is pretty fuzzy on this stuff. If you call GetDesc on the ID3DXConstantTable, does it report a non-zero value for the Constants field that indicates the number of constants in the table?

If all else fails, you can always explicitly assign constant registers to your variables, and then pass the appropriate StartRegister to IDirect3DDevice9::SetVertexShaderConstantF. Each register is the size of a float4, so in the case of a matrix you would assign a starting register and the full matrix would occupy 4 consecutive registers. The syntax looks like this:

float4x4 gMyMatrix: register(c0)

Hi, thanks for replying.

Yeah, if I do it all via registers, it all works fine. But what I would like to do is make it compatible with OpenGL (where you query for name) so that even though the shader language will be different between the two systems, the calling convention won't be.

So a funny thing: When I try to enumerate through GetDesc, it tells me the correct number of constants, but crashes if I try to fetch the descriptions of them, or do ANYTHING with them. Anyone know what that's about?

I don't think it's unreasonable to just use registers and forget about modelling this around how OpenGL works. There are already significant API differences here anyway - uniforms are program state in GL, global state in D3D; bind to modify in GL but not in D3D; monolithic program objects in GL vs separate shaders in D3D; vertex attribs in GL vs vertex declarations in D3D - that trying to squeeze both into a single interface just seems like a game of whack-a-mole you're not going to win.

More reasonable approaches might include going even higher-level with the D3D stuff and using Effects (but just pretend that Techniques and Passes don't exist) which provide an abstraction closer to GL.

I know this doesn't answer your question, and maybe you'd still like to understand why it's not working, but in terms of getting something that works I think you're going in the wrong direction.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement