Getting a constant from a GLSL shader

I have a shader written in GLSL with an array of structures for storing light data. I use a constant to declare the size of the array, as a good practice. Let's say this variable is declared as

const int NUM_POINT_LIGHTS = 100;

      

How can I use C ++ to output this data from the shader so that my C ++ program knows exactly how many lights are available to it? I tried to declare it as

const uniform int NUM_POINT_LIGHTS = 100;

      

As expected, it didn't work (although, oddly enough, it looks like the uniform spec is just overriding the const spec, since OpenGL complained that I initialized the array with a non-const value). I have also tried

const int NUM_POINT_LIGHTS = 100;
uniform numPointLights = NUM_POINT_LIGHTS;

      

This will work, except for the fact that GLSL optimizes unused forms, so I have to keep track of glsl, thinking that the uniform is being used in some way to be able to get the data. I have not been able to find any other method for asking the program to get a constant value. Does anyone have any ideas how I could pull the constant out of the shader so that my program gets information that is functionally encoded in the shader to use it?

+3


source to share


2 answers


I don't think you can get the value of the constant directly. However, I suppose you should use the constant value, most likely as the size of a homogeneous array. In this case, you can get the size of a homogeneous array, which indirectly gets the value of the constant.

Say your shader contains something like this:

const int NUM_POINT_LIGHTS = 100;
uniform vec3 LightPositions[NUM_POINT_LIGHTS];

      

Then you can get the index of that uniform first:

const GLchar* uniformName = "LightPositions";
GLuint uniformIdx = 0;
glGetUniformIndices(program, 1, &uniformName, &uniformIdx);

      



Using this index, you can get the attributes of this uniform:

const int nameLen = strlen("LightPositions") + 1;
const GLchar name[nameLen];
GLint uniformSize = 0;
GLenum uniformType = GL_NONE;
glGetActiveUniform(program, uniformIdx, nameLen, NULL,
                   &uniformSize, &uniformType, name);

      

uniformSize

must be the value of a constant NUM_POINT_LIGHTS

. Note that I have not tried this, but hope I got the arguments right based on the documentation.

A somewhat ugly, but possibly very practical solution, of course, is to parse the value from the shader source code. Since you need to read it anyway before you pass it to glShaderSource()

, choosing a constant value should be fairly straightforward.

Another option, if your main goal is not to have a constant in multiple places, is to define it in your C ++ code and dynamically add the constant definition to the shader code after reading in the shader code and before going through it goes glShaderSource()

.

+8


source


You cannot simply request a constant from a GLSL program. There is no such concept in the GLSL specification.



Unified buffer objects can be a way to get around the uniform optimization problem. https://www.opengl.org/wiki/Uniform_Buffer_Object

0


source







All Articles