Axiom.RenderSystems.OpenGL.GLSL.GLSLLinkProgramManager.ExtractUniforms C# (CSharp) Method

ExtractUniforms() public method

Populate a list of uniforms based on a program object.
public ExtractUniforms ( int programObject, GpuProgramParameters vertexConstantDefs, GpuProgramParameters geometryConstantDefs, GpuProgramParameters fragmentConstantDefs, Axiom.RenderSystems.OpenGL.GLSL.GLSLLinkProgram list ) : void
programObject int Handle to the program object to query
vertexConstantDefs Axiom.Graphics.GpuProgramParameters Definition of the constants extracted from the /// vertex program, used to match up physical buffer indexes with program /// uniforms. May be null if there is no vertex program.
geometryConstantDefs Axiom.Graphics.GpuProgramParameters Definition of the constants extracted from the /// geometry program, used to match up physical buffer indexes with program /// uniforms. May be null if there is no geometry program.
fragmentConstantDefs Axiom.Graphics.GpuProgramParameters Definition of the constants extracted from the /// fragment program, used to match up physical buffer indexes with program /// uniforms. May be null if there is no fragment program.
list Axiom.RenderSystems.OpenGL.GLSL.GLSLLinkProgram The list to populate (will not be cleared before adding, clear /// it yourself before calling this if that's what you want).
return void
        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
        }