Jump to content
  • Advertisement
Sign in to follow this  
steviedisco

OpenGL DX10 - Accessing members of a constant buffer

This topic is 2467 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

I'm working on a multi-API rendering framework. I started off with OpenGL, then added DirectX9 and am now in the process of converting that to DirectX 10. I will add DirectX 11 when that is done.

Today, I've come across the constant buffer concept. In DirectX 9, when I wanted to pass uniform constants to my shader I would call ->SetFloatArray() or similar on the constant table.

In the SDK samples (HLSLWithoutFX10), the equivalent method requires a constant buffer declaration as below:

struct VS_CONSTANT_BUFFER
{
D3DXMATRIX mWorldViewProj; //mWorldViewProj will probably be global to all shaders in a project.
//It's a good idea not to move it around between shaders.
D3DXVECTOR4 vSomeVectorThatMayBeNeededByASpecificShader;
float fSomeFloatThatMayBeNeededByASpecificShader;
float fTime; //fTime may also be global to all shaders in a project.
float fSomeFloatThatMayBeNeededByASpecificShader2;
float fSomeFloatThatMayBeNeededByASpecificShader3;
};


This can be accessed by calling ->map and then setting the values.

What do I do if I don't know what the format of the constant buffer is going to be? I don't particularly want to hard-code in a declaration into the source, as all my shaders have different constants and I don't know what I'm going to be adding in the future.

I'm not using the effects capabilities, but am compiling using D3DX10CompileFromMemory (I realise this is deprecated so intend to change this later).

Is there no way to access the constant buffer properties by name without using the effects functions? I currently store all my shaders in separate .vp (vertex) and .fp (fragment) files. I was hoping that I wouldn't need to change anything in these between DX9 and 10.

I'm in the really early stages of all this and am nowhere near thinking about optimizing by reducing the number of draw calls, constant changes etc. It really is just a simple framework at the moment, not an engine as such.

Having read all that, you'll probably tell me not to bother with DX10 anymore but for the sake of argument, I'm really just using it as a learning exercise.

Many thanks in advance all you genius gurus smile.png

Share this post


Link to post
Share on other sites
Advertisement
Well,the easy answer is no. If you try to create some frame work to allow you to do what you want to do, you will basically be making your own effect style interface, so you are better off using the existing effect framework.

If you want to avoid hard coding many different constant buffers, than create a standard for your shaders, ie:

for all your vertex shaders:

struct CBperObject
{
D3DXMatrix WorldMat;
}

struct CBperFrame
{
D3DXMatrix ViewMat;
D3DXMatrix ProjMat;
}


So now, you know that every vertex shader is going to need these.

Share this post


Link to post
Share on other sites
You can use the reflection API's to get all of the information you need about a constant buffer declared in a shader. Take a look at ID3D10ShaderReflection for the relevent documentaiton. Just be aware that if you want the best performance than you're going to have to move away from the idea of just arbitrarily setting the values of individual constants. The real power of constant buffers is that you can group them by how often then need to be updated, and to take advantage of this you'll need to partition constants into different constant buffers and be careful about how you set the values in them. However the reflection API's can still help you if you want to avoid just hard-coding structures to match constant buffer layouts.

Share this post


Link to post
Share on other sites
Thanks guys. I'm not ready to optimize yet, I really just want to get it working.

I think I've figured out a way of doing it - just declare a pointer to a char[] of arbitrary size (say 1024), then pass the values in and increase the pointer by the relevant size (ie Matrix4x4 or Vector4). I *should* have the same memory layout as though I declared a hard-coded unique struct. The only caveat is I have to pass the arguments into the shader in the same order as they are declared in the shader itself.

This might not work, I haven't got as far as testing it yet - I'm not so good at this memory manipulation stuff coming from C#.

If it doesn't work, I'll have a look at the Reflection APIs. That looks like what I'm after.

Thanks all :)

Share this post


Link to post
Share on other sites
I've ended up using Reflection. I still haven't got it working (I'm just trying to draw a triangle), but I'm confident my problem now lies elsewhere. I found the documentation lacking but I had a brainwave - I had a look through the OGRE source and they do pretty much the same thing so I pilfered a bit from there.

It's a bit messy at the moment, but I'll tidy it up when I come to making a generic solution for it all.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!