I have a uniform block like this:
layout(shared) uniform ProjectionMatrices {
mat4 model_camera_xform;
mat4 camera_clip_xform;
};
I would like to query the size and offset of the uniforms in this block. To do this, I first need to get the indices of its members, using the glGetUniformIndices
function, but I can't figure out how to use it.
Here is my attempt:
import ctypes as c
from OpenGL import GL
import numpy
name_array = c.c_char_p * len(uniform_names)
c_uniform_names = name_array(*[c.c_char_p(name.encode()) for name in uniform_names])
c_uniform_names = c.cast(c_uniform_names, c.POINTER(c.POINTER(c.c_char)))
uniform_indices = numpy.zeros(len(uniform_names), dtype='int32')
uniform_indices += 42
r = GL.glGetUniformIndices(program, len(uniform_names), c_uniform_names, uniform_indices)
err = GL.glGetError()
However, the result of this is that:
>>> print(uniform_names) # looks good.
['ProjectionMatrices.model_camera_xform', 'ProjectionMatrices.camera_clip_xform']
>>> print(err == GL.GL_NO_ERROR) # No error occurred
True
>>> print(r) # GL.GL_INVALID_INDEX, not sure what this refers to
4294967295
>>> print(uniform_indices) # Nothing has been set
[42 42]
To resolve the problem of uniform_indices
not being set, they had to be uint32
, which can be done in a few ways:
uniform_indices = numpy.zeros(len(uniform_names), dtype='uint32')
uniform_indices = numpy.zeros(len(uniform_names), dtype=OpenGL.constants.GLuint)
uniform_indices = (OpenGL.constants.GLuint * len(uniform_names))()
After this, uniform_indices
was set to GL_INVALID_INDEX
. This was fixed by changing uniform_names
to use the unqualified names:
uniform_names = ['model_camera_xform', 'camera_clip_xform']
The relevant section of the OpenGL 4.4 specification is 4.3.9 Interface Blocks:
Outside the shading language (i.e., in the API), members are similarly identified except the block name is always used in place of the instance name (API accesses are to shader interfaces, not to shaders). If there is no instance name, then the API does not use the block name to access a member, just the member name.