2

I'm working on a graphics api that has to run on both directx9 and opengl (2.1 and no uniform buffer support) I don't want to write two versions of the shaders and need to convert between hlsl and glsl (Cg is not an option) I've solved most problems, using lua to script parts of the shader (creating dummy main on glsl to support vertex in and out structs and such) but I'm having a hard time getting the constants right. In hlsl I can write:

float4x4 WorldViewProjection : register( c0 );
float4   ColorTint           : register( c5 );
float3   UVOffset_Time       : register( c6 );

and then set all of these using:

SetVertexShaderConstantF( 0, pData, 6 )

Alternatively SetPixelShaderConstantF. pData points to a struct with the same setup (ie 4x4 float matrix, 4 float vector, 3 float vector)

the only solution I've come up with in glsl is:

uniform vec4 UNIFORM0[ 6 ];
#define WorldViewProjection mat4( UNIFORM0[0], UNIFORM0[1], UNIFORM0[2], UNIFORM0[3] )
#define ColorTint UNIFORM0[4]
#define UVOffset_Time vec3( UNIFORM0[5].xyz )

and then I get the location of "UNIFORM0" from opengl and set the array using glUniform4fvARB However using #defines to get my constants into the shaders is pretty ugly.

Is there a way for me to set constants in a similar way to hlsl and what extensions would I need for it?

Can I use some kind of reference/typedef/handle to do something similar to the define solution without using an actual define, ie:

const mat4 WorldViewProjection = mat4( UNIFORM0[0], UNIFORM0[1], UNIFORM0[2], UNIFORM0[3] );

1 Answer 1

2

Is there a way for me to set constants in a similar way to hlsl and what extensions would I need for it?

OpenGL 4.3/ARB_explicit_uniform_location provides a way to specify uniform locations in the shader itself. You can qualify your uniforms with layout(location = #), so you don't have to query uniform locations.

Without this functionality, you can't do that. So in lieu of this, it would be easier to do things GLSL-style (query the shader for uniform locations, use those locations to set values) than to do it HLSL-style. After all, with HLSL-style, you're just querying things you already know. You're doing it more than you need to, but it's easier to add additional, unnecessary queries to one API than to try to remove queries from one that requires them.

Sign up to request clarification or add additional context in comments.

4 Comments

With HLSL I don't query at all and I don't want to since it's not needed. I can almost get around the problem on GLSL with just having to query some set uniform float array. But it's pretty ugly having to use defines to get the actual constants.
@Birken: Well GLSL needs queries. And if you have two APIs, one that needs queries and one that doesn't, the easiest way of abstracting them is to do queries with both, rather than trying to finagle a way to do queries with neither.
Querying on strings is just not good enough. The api works with constant buffers (to work with dx11). I don't want to do more ogl or dx calls than necessary.
@Birken: "Querying on strings is just not good enough." That is the only option OpenGL gives you, period. If that's not good enough for you, then you have a choice to make. Cross-platform development is always going to be sub-optimal for some platform. It's up to you to decide which one. The easiest in this case is to add a few more D3D calls. Anyway, if you're using D3D constant buffers, then why aren't you using uniform buffers in OpenGL? You can set their locations one time as part of program linking.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.