///<summary>
		///  Populate a list of uniforms based on a program object
		///</summary>
		///<param name="programObject"> Handle to the program object to query </param>
		///<param name="vertexConstantDefs"> vertexConstantDefs 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. </param>
		///<param name="fragmentConstantDefs"> fragmentConstantDefs 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. </param>
		///<param name="list"> The list to populate (will not be cleared before adding, clear it yourself before calling this if that's what you want). </param>
		public void ExtractUniforms( int programObject, Graphics.GpuProgramParameters.GpuConstantDefinitionMap vertexConstantDefs, Graphics.GpuProgramParameters.GpuConstantDefinitionMap fragmentConstantDefs, List<GLUniformReference> list )
		{
			//Scan through the active uniforms and add them to the reference list
			int uniformCount = 0;
			int maxLength = 0;
			string uniformName = string.Empty;

			GL.GetProgram( programObject, GLenum.ActiveUniformMaxLength, ref maxLength );
			GLES2Config.GlCheckError( this );

			//If the max length of active uniforms is 0, then there are 0 active.
			//There won't be any to extract so we can return
			if ( maxLength == 0 )
			{
				return;
			}

			GLUniformReference newGLUniformReference;

			//Get the number of active uniforms
			GL.GetProgram( programObject, GLenum.ActiveUniforms, ref uniformCount );
			GLES2Config.GlCheckError( this );

			//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 index = 0; index < uniformCount; index++ )
			{
				int arraySize = 0;
				GLenum glType = GLenum.None;
				int tmp = 0;
				GL.GetActiveUniform( programObject, index, maxLength, ref tmp, ref arraySize, ref glType, uniformName );
				GLES2Config.GlCheckError( this );

				//don't add built in uniforms
				newGLUniformReference = new GLUniformReference();
				newGLUniformReference.Location = GL.GetUniformLocation( programObject, uniformName );
				GLES2Config.GlCheckError( this );
				if ( newGLUniformReference.Location >= 0 )
				{
					//User defined uniform found, add it to the reference list
					string paramName = uniformName;

					//If the uniform name has a '[' in it then its an array element uniform.
					int arrayStart = -1;
					for ( int i = 0; i < paramName.Length; i++ )
					{
						if ( paramName[ i ] == '[' )
						{
							arrayStart = i;
							break;
						}
					}
					if ( arrayStart != -1 )
					{
						//If not the first array element then skip it and continue to the next uniform
						string sub = paramName.Substring( arrayStart, paramName.Length - 1 );
						if ( sub == "[0]" )
						{
							continue;
						}

						paramName = paramName.Substring( 0, arrayStart );
					}

					//Find out which params object this comes from
					bool foundSource = this.CompleteParamSource( paramName, vertexConstantDefs, fragmentConstantDefs, newGLUniformReference );

					//Only add this param if we found the source
					if ( foundSource )
					{
						list.Add( newGLUniformReference );
					}
				}
			}

			if ( uniformName != string.Empty )
			{
				uniformName = string.Empty;
			}
		}
        ///<summary>
        ///  Populate a list of uniforms based on a program object
        ///</summary>
        ///<param name="programObject"> Handle to the program object to query </param>
        ///<param name="vertexConstantDefs"> vertexConstantDefs 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. </param>
        ///<param name="fragmentConstantDefs"> fragmentConstantDefs 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. </param>
        ///<param name="list"> The list to populate (will not be cleared before adding, clear it yourself before calling this if that's what you want). </param>
        public void ExtractUniforms(int programObject, Graphics.GpuProgramParameters.GpuConstantDefinitionMap vertexConstantDefs, Graphics.GpuProgramParameters.GpuConstantDefinitionMap fragmentConstantDefs, List <GLUniformReference> list)
        {
            //Scan through the active uniforms and add them to the reference list
            int    uniformCount = 0;
            int    maxLength    = 0;
            string uniformName  = string.Empty;

            GL.GetProgram(programObject, GLenum.ActiveUniformMaxLength, ref maxLength);
            GLES2Config.GlCheckError(this);

            //If the max length of active uniforms is 0, then there are 0 active.
            //There won't be any to extract so we can return
            if (maxLength == 0)
            {
                return;
            }

            GLUniformReference newGLUniformReference;

            //Get the number of active uniforms
            GL.GetProgram(programObject, GLenum.ActiveUniforms, ref uniformCount);
            GLES2Config.GlCheckError(this);

            //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 index = 0; index < uniformCount; index++)
            {
                int    arraySize = 0;
                GLenum glType    = GLenum.None;
                int    tmp       = 0;
                GL.GetActiveUniform(programObject, index, maxLength, ref tmp, ref arraySize, ref glType, uniformName);
                GLES2Config.GlCheckError(this);

                //don't add built in uniforms
                newGLUniformReference          = new GLUniformReference();
                newGLUniformReference.Location = GL.GetUniformLocation(programObject, uniformName);
                GLES2Config.GlCheckError(this);
                if (newGLUniformReference.Location >= 0)
                {
                    //User defined uniform found, add it to the reference list
                    string paramName = uniformName;

                    //If the uniform name has a '[' in it then its an array element uniform.
                    int arrayStart = -1;
                    for (int i = 0; i < paramName.Length; i++)
                    {
                        if (paramName[i] == '[')
                        {
                            arrayStart = i;
                            break;
                        }
                    }
                    if (arrayStart != -1)
                    {
                        //If not the first array element then skip it and continue to the next uniform
                        string sub = paramName.Substring(arrayStart, paramName.Length - 1);
                        if (sub == "[0]")
                        {
                            continue;
                        }

                        paramName = paramName.Substring(0, arrayStart);
                    }

                    //Find out which params object this comes from
                    bool foundSource = this.CompleteParamSource(paramName, vertexConstantDefs, fragmentConstantDefs, newGLUniformReference);

                    //Only add this param if we found the source
                    if (foundSource)
                    {
                        list.Add(newGLUniformReference);
                    }
                }
            }

            if (uniformName != string.Empty)
            {
                uniformName = string.Empty;
            }
        }
		protected bool CompleteParamSource( string paramName, Graphics.GpuProgramParameters.GpuConstantDefinitionMap vertexConstantDefs, Graphics.GpuProgramParameters.GpuConstantDefinitionMap fragmentConstantDefs, GLUniformReference refToUpdate )
		{
			if ( vertexConstantDefs != null )
			{
				if ( vertexConstantDefs.ContainsKey( paramName ) )
				{
					var parami = vertexConstantDefs[ paramName ];
					refToUpdate.SourceProgType = GpuProgramType.Vertex;
					refToUpdate.ConstantDef = parami;
					return true;
				}
			}

			if ( fragmentConstantDefs != null )
			{
				if ( fragmentConstantDefs.ContainsKey( paramName ) )
				{
					refToUpdate.SourceProgType = GpuProgramType.Fragment;
					refToUpdate.ConstantDef = fragmentConstantDefs[ paramName ];
					return true;
				}
			}

			return false;
		}
        protected bool CompleteParamSource(string paramName, Graphics.GpuProgramParameters.GpuConstantDefinitionMap vertexConstantDefs, Graphics.GpuProgramParameters.GpuConstantDefinitionMap fragmentConstantDefs, GLUniformReference refToUpdate)
        {
            if (vertexConstantDefs != null)
            {
                if (vertexConstantDefs.ContainsKey(paramName))
                {
                    var parami = vertexConstantDefs[paramName];
                    refToUpdate.SourceProgType = GpuProgramType.Vertex;
                    refToUpdate.ConstantDef    = parami;
                    return(true);
                }
            }

            if (fragmentConstantDefs != null)
            {
                if (fragmentConstantDefs.ContainsKey(paramName))
                {
                    refToUpdate.SourceProgType = GpuProgramType.Fragment;
                    refToUpdate.ConstantDef    = fragmentConstantDefs[paramName];
                    return(true);
                }
            }

            return(false);
        }