public void ExtractUniforms(int programObject,
GpuProgramParameters.GpuConstantDefinitionMap vertexConstantDefs,
GpuProgramParameters.GpuConstantDefinitionMap geometryConstantDefs,
GpuProgramParameters.GpuConstantDefinitionMap fragmentConstantDefs,
GLSLLinkProgram.UniformReferenceList list)
{
// scan through the active uniforms and add them to the reference list
// get the number of active uniforms
int uniformCount;
const int BUFFERSIZE = 200;
Gl.glGetObjectParameterivARB(programObject, Gl.GL_OBJECT_ACTIVE_UNIFORMS_ARB,
out uniformCount);
// Loop over each of the active uniforms, and add them to the reference container
// only do this for user defined uniforms, ignore built in gl state uniforms
for (var index = 0; index < uniformCount; index++)
{
// important for Axiom: dont pull this var to the outer scope
// because UniformReference is by value (class)
// if we'd share the instance we would push the same instance
// to the result list each iteration
var newGLUniformReference = new GLSLLinkProgram.UniformReference();
var uniformName = new StringBuilder();
int arraySize;
int glType;
Gl.glGetActiveUniformARB(programObject, index, BUFFERSIZE, null,
out arraySize, out glType, uniformName);
newGLUniformReference.Location = Gl.glGetUniformLocationARB(programObject, uniformName.ToString());
if (newGLUniformReference.Location >= 0)
{
// user defined uniform found, add it to the reference list
var paramName = uniformName.ToString();
// currant ATI drivers (Catalyst 7.2 and earlier) and older NVidia drivers will include all array elements as uniforms but we only want the root array name and location
// Also note that ATI Catalyst 6.8 to 7.2 there is a bug with glUniform that does not allow you to update a uniform array past the first uniform array element
// ie you can't start updating an array starting at element 1, must always be element 0.
// if the uniform name has a "[" in it then its an array element uniform.
var arrayStart = paramName.IndexOf( '[' );
if (arrayStart != -1)
{
// if not the first array element then skip it and continue to the next uniform
if (paramName.Substring(arrayStart, paramName.Length - 1) != "[0]")
continue;
paramName = paramName.Substring(0, arrayStart);
}
// find out which params object this comes from
var foundSource = CompleteParamSource( paramName, vertexConstantDefs, geometryConstantDefs,
fragmentConstantDefs, newGLUniformReference );
// only add this parameter if we found the source
if (foundSource)
{
Debug.Assert( arraySize == newGLUniformReference.ConstantDef.ArraySize,
"GL doesn't agree with our array size!" );
list.Add(newGLUniformReference);
}
// Don't bother adding individual array params, they will be
// picked up in the 'parent' parameter can copied all at once
// anyway, individual indexes are only needed for lookup from
// user params
} // end if
} // end for
}