/// <summary>
        ///		Updates program object uniforms using data from GpuProgramParameters.
        ///		normally called by GLSLGpuProgram.BindParameters() just before rendering occurs.
        /// </summary>
        /// <param name="parameters">GPU Parameters to use to update the uniforms params.</param>
        public void UpdateUniforms(GpuProgramParameters parameters)
        {
            for(int i = 0; i < uniformReferences.Count; i++) {
                UniformReference uniformRef = (UniformReference)uniformReferences[i];

                GpuProgramParameters.FloatConstantEntry currentFloatEntry = null;
                GpuProgramParameters.IntConstantEntry currentIntEntry = null;

                if(uniformRef.isFloat) {
                    currentFloatEntry = parameters.GetNamedFloatConstant(uniformRef.name);

                    if(currentFloatEntry != null) {
                        if(currentFloatEntry.isSet) {
                            switch(uniformRef.elementCount) {
                                case 1:
                                    Gl.glUniform1fvARB(uniformRef.location, 1, currentFloatEntry.val);
                                    break;

                                case 2:
                                    Gl.glUniform2fvARB(uniformRef.location, 1, currentFloatEntry.val);
                                    break;

                                case 3:
                                    Gl.glUniform3fvARB(uniformRef.location, 1, currentFloatEntry.val);
                                    break;

                                case 4:
                                    Gl.glUniform4fvARB(uniformRef.location, 1, currentFloatEntry.val);
                                    break;
                            } // end switch
                        }
                    }
                }
                else {
                    currentIntEntry = parameters.GetNamedIntConstant(uniformRef.name);

                    if(currentIntEntry != null) {
                        if(currentIntEntry.isSet) {
                            switch(uniformRef.elementCount) {
                                case 1:
                                    Gl.glUniform1ivARB(uniformRef.location, 1, currentIntEntry.val);
                                    break;

                                case 2:
                                    Gl.glUniform2ivARB(uniformRef.location, 1, currentIntEntry.val);
                                    break;

                                case 3:
                                    Gl.glUniform3ivARB(uniformRef.location, 1, currentIntEntry.val);
                                    break;

                                case 4:
                                    Gl.glUniform4ivARB(uniformRef.location, 1, currentIntEntry.val);
                                    break;
                            } // end switch
                        }
                    }
                }
            }
        }
        /// <summary>
        ///		Build uniform references from active named uniforms.
        /// </summary>
        private void BuildUniformReferences()
        {
            if(!uniformRefsBuilt) {
                // scane through the active uniforms and add them to the reference list
                int uniformCount;
                int size = 0;
                const int BufferSize = 100;
                string uniformName;

                // get the count of active uniforms
                Gl.glGetObjectParameterivARB(glHandle, 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(int i = 0; i < uniformCount; i++) {
                    UniformReference newUniformReference = new UniformReference();

                    // get the info for the current uniform
                    System.Text.StringBuilder uniformNameBuilder = new System.Text.StringBuilder(BufferSize);
                    int test;
                    Gl.glGetActiveUniformARB(glHandle, i, BufferSize, out test, out size, out newUniformReference.type, uniformNameBuilder);

                    uniformName = uniformNameBuilder.ToString();

                    // don't add built in uniforms
                    newUniformReference.location = Gl.glGetUniformLocationARB(glHandle, uniformName);

                    if(newUniformReference.location >= 0) {
                        // user defined uniform found, add it to the reference list
                        newUniformReference.name = uniformName;

                        // decode uniform size and type
                        switch(newUniformReference.type) {
                            case Gl.GL_FLOAT:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 1;
                                break;

                            case Gl.GL_FLOAT_VEC2_ARB:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 2;
                                break;

                            case Gl.GL_FLOAT_VEC3_ARB:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 3;
                                break;

                            case Gl.GL_FLOAT_VEC4_ARB:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 4;
                                break;

                            case Gl.GL_INT:
                            case Gl.GL_SAMPLER_1D_ARB:
                            case Gl.GL_SAMPLER_2D_ARB:
                            case Gl.GL_SAMPLER_3D_ARB:
                            case Gl.GL_SAMPLER_CUBE_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 1;
                                break;

                            case Gl.GL_INT_VEC2_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 2;
                                break;

                            case Gl.GL_INT_VEC3_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 3;
                                break;

                            case Gl.GL_INT_VEC4_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 4;
                                break;
                        } // end switch

                        uniformReferences.Add(newUniformReference);
                    } // end if
                } // end for

                uniformRefsBuilt = true;
            }
        }
        /// <summary>
        ///		Build uniform references from active named uniforms.
        /// </summary>
        private void BuildUniformReferences()
        {
            if(!uniformRefsBuilt) {
                // scane through the active uniforms and add them to the reference list
                int uniformCount;
                int size = 0;
                const int BufferSize = 100;
                string uniformName;

                // get the count of active uniforms
                Gl.glGetObjectParameterivARB(glHandle, 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(int i = 0; i < uniformCount; i++) {
                    UniformReference newUniformReference = new UniformReference();

                    // get the info for the current uniform
                    System.Text.StringBuilder uniformNameBuilder = new System.Text.StringBuilder(BufferSize);
                    int test;
                    Gl.glGetActiveUniformARB(glHandle, i, BufferSize, out test, out size, out newUniformReference.type, uniformNameBuilder);

                    uniformName = uniformNameBuilder.ToString();

                    // don't add built in uniforms
                    newUniformReference.location = Gl.glGetUniformLocationARB(glHandle, uniformName);

                    if(newUniformReference.location >= 0) {
                        // user defined uniform found, add it to the reference list
                        newUniformReference.name = uniformName;

                        // decode uniform size and type
                        switch(newUniformReference.type) {
                            case Gl.GL_FLOAT:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 1;
                                break;

                            case Gl.GL_FLOAT_VEC2_ARB:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 2;
                                break;

                            case Gl.GL_FLOAT_VEC3_ARB:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 3;
                                break;

                            case Gl.GL_FLOAT_VEC4_ARB:
                                newUniformReference.isFloat = true;
                                newUniformReference.elementCount = 4;
                                break;

                            case Gl.GL_INT:
                            case Gl.GL_SAMPLER_1D_ARB:
                            case Gl.GL_SAMPLER_2D_ARB:
                            case Gl.GL_SAMPLER_3D_ARB:
                            case Gl.GL_SAMPLER_CUBE_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 1;
                                break;

                            case Gl.GL_INT_VEC2_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 2;
                                break;

                            case Gl.GL_INT_VEC3_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 3;
                                break;

                            case Gl.GL_INT_VEC4_ARB:
                                newUniformReference.isFloat = false;
                                newUniformReference.elementCount = 4;
                                break;
                        } // end switch

                        uniformReferences.Add(newUniformReference);
                    } // end if
                } // end for

                uniformRefsBuilt = true;
            }
        }