At the moment i just do:
someuniform1 = glGetUniformLocation(MyShaderName, "someuniform1");
someattribute1 = glGetAttribLocation(MyShaderName, "someattribute1");
But this method seems annoyingly repetitive, so i thought of using std::map:
Shaders[MyShaderName].Uniforms["someuniform1"] = glGetUniformLocation(MyShaderName, "someuniform1");
Shaders[MyShaderName].Attributes["someattribute1"] = glGetAttribLocation(MyShaderName, "someattribute1");
// i could add a function to remove the repetition of the two strings at both sides.
Is there any smarter/faster way of doing this? (to reduce repetition as much as possible).
--
Edit: I was thinking more about this idea, and i thought, wouldnt it be great if i just read the glsl source files, parse the uniform/attributes and set to my map automatically, without me need to write anything else than the glsl source!? Is this how the big boys do it?
Edit2: I am now parsing the GLSL shader files successfully, and using the std::map
method, i use single function call with one string param to get the address for uniforms/attributes at current enabled shader. in case i need more performance, i will cache the std::map
calls to other variables. But i would like to know if i am on the right track here... so please, any comments appreciated.
Enumerate shader program's uniforms by GetActiveUniform
, then store them in your map.
Edit: The purpose.
glGetProgramiv
, glGetActiveUniform
and glGetActiveAttrib
can be used to get information about the used uniforms in a shader program. The information can be retrieved at any time after the program has been linked, glLinkProgram
:
glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxUniformNameLen )
returns the length of the longest
active uniform variable name (including the null termination character)
glGetProgramiv( MyShaderName, GL_ACTIVE_UNIFORMS, &noOfUniforms )
returns the number of active uniform variables.
glGetActiveUniform
returns information about an active uniform variable inclluding the name of the uniform.
glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribNameLen )
returns the length of the longest vetex attribute name (including the null termination character)
glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTES, &noOfAttributes )
returns the number of the active attributes.
glGetActiveAttrib
returns information about an active vetrtex attribute inclluding the name of the attribute.
Use the information from the functions above to find all uniform and attribute names within a program. Ask each uniform for its location and each attribute for its index, by their names. See the code snippet below:
GLint maxUniformNameLen, noOfUniforms;
glGetProgramiv( MyShaderName, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformNameLen );
glGetProgramiv( MyShaderName, GL_ACTIVE_UNIFORMS, &noOfUniforms );
GLint maxAttribNameLen, noOfAttributes;
glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribNameLen );
glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTES, &noOfAttributes );
GLint read, size;
GLenum type;
std::vector< GLchar >unifN( maxUniformNameLen, 0 );
for ( GLint i = 0; i < noOfUniforms; ++ i )
{
glGetActiveUniform(Object(), i, maxUniformNameLen, &read, &size, &type, unifN.data());
Shaders[ MyShaderName ].Uniforms[ unifN.data() ] =
glGetUniformLocation( MyShaderName, unifN.data() );
}
std::vector< GLchar >attrN( maxAttribNameLen, 0 );
for ( GLint i = 0; i < noOfAttributes; ++ i )
{
glGetActiveAttrib(Object(), i, maxAttribNameLen, &read, &size, &type, attrN.data());
Shaders[ MyShaderName ].Attributes[ attrN.data() ] =
glGetAttribLocation( MyShaderName, attrN.data() );
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With