///<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); }