Reputation: 346
I am trying to get the size of uniform parameter in already compiled glsl shader program. I have found some functions to do it for default-typed uniforms only. But is there a way to do it for uniform parameters with custom type?
For example:
struct Sphere
{
vec3 position;
float raduis;
};
#define SPHERES 10
uniform Sphere spheres[SPHERES];
Upvotes: 0
Views: 1103
Reputation: 26197
I'm assuming that your end goal basically is spheres.length
and the result being 10
.
The most optimal way would be to have that length stored elsewhere, as it isn't possible to change the size after the shader has been compiled anyways.
There's no simple way to get the length of the array. Because there isn't any array per se. When compiled each element of the array (as well as each element of the struct) ends up becoming their own individual uniform. Which is evident by the need of doing:
glGetUniformLocation(program, "spheres[4].position")
The thing is that if your shader only uses spheres[4].position
and spheres[8].position
then all the other spheres[x].position
are likely to be optimized away and thus won't exist.
So how do you get the uniform array length?
You could accomplish this by utilizing glGetActiveUniform()
and regex or sscanf()
. Say you want to check how many spheres[x].position
is available, then you could do:
GLint count;
glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count);
const GLsizei NAME_MAX_LENGTH = 64
GLint location, size;
GLenum type;
GLchar name[NAME_MAX_LENGTH];
GLsizei nameLength;
int index, charsRead;
for (GLint i = 0; i < count; ++i)
{
glGetActiveUniform(program, (GLuint)i, NAME_MAX_LENGTH, &nameLength, &size, &type, name);
if (sscanf(name, "spheres[%d].position%n", &index, &charsRead) && (charsRead == nameLength))
{
// Now we know spheres[index].position is available
}
}
You can additionally compare type
to GL_FLOAT
or GL_FLOAT_VEC3
to figure out which data type it is.
Remember that if you add an int count
and increment it for each match. Then even if count
is 3
at the end. That doesn't mean it's element 0, 1, 2
that's available. It could easily be element 0, 5, 8
.
Additional notes:
name
is a null terminated string%n
is the number of characters read so farUpvotes: 1