I'd like to get a list of all the uniforms & attribs used by a shader program object. glGetAttribLocation()
& glGetUniformLocation()
can be used to map a string to a location, but what I would really like is the list of strings without having to parse the glsl code.
Note: In OpenGL 2.0 glGetObjectParameteriv()
is replaced by glGetProgramiv()
. And the enum is GL_ACTIVE_UNIFORMS
& GL_ACTIVE_ATTRIBUTES
.
There has been a change in how this sort of thing is done in OpenGL. So let's present the old way and the new way.
Old Way
Linked shaders have the concept of a number of active uniforms and active attributes (vertex shader stage inputs). These are the uniforms/attributes that are in use by that shader. The number of these (as well as quite a few other things) can be queried with glGetProgramiv:
You can query active uniform blocks, transform feedback varyings, atomic counters, and similar things in this way.
Once you have the number of active attributes/uniforms, you can start querying information about them. To get info about an attribute, you use
glGetActiveAttrib
; to get info about a uniform, you useglGetActiveUniform
. As an example, extended from the above:Something similar can be done for uniforms. However, the
GL_ACTIVE_UNIFORM_MAX_LENGTH
trick can be buggy on some drivers. So I would suggest this:Also, for uniforms, there's
glGetActiveUniforms
, which can query all of the name lengths for every uniform all at once (as well as all of the types, array sizes, strides, and other parameters).New Way
This way lets you access pretty much everything about active variables in a successfully linked program (except for regular globals). The ARB_program_interface_query extension is not widely available yet, but it'll get there.
It starts with a call to
glGetProgramInterfaceiv
, to query the number of active attributes/uniforms. Or whatever else you may want.Attributes are just vertex shader inputs;
GL_PROGRAM_INPUT
means the inputs to the first program in the program object.You can then loop over the number of active resources, asking for info on each one in turn, from
glGetProgramResourceiv
andglGetProgramResourceName
:The exact same code would work for
GL_UNIFORM
; just swapnumActiveAttribs
withnumActiveUniforms
.Here is the corresponding code in python for getting the uniforms:
Apparently the 'new way' mentioned by Nicol Bolas does not work in python.
For anyone out there that finds this question looking to do this in WebGL, here's the WebGL equivalent:
Variables shared between both examples:
Attributes
Uniforms
OpenGL Documentation / Variable Types
The various macros representing variable types can be found in the docs. Such as
GL_FLOAT
,GL_FLOAT_VEC3
,GL_FLOAT_MAT4
, etc.