protected override void CompileAndLink() { //Compile and attach vertex program if (!vertexProgram.GLSLProgram.Compile(true)) { triedToLinkAndFailed = true; return; } vertexProgram.GLSLProgram.AttachToProgramObject(glProgramHandle); SkeletalAnimationIncluded = vertexProgram.IsSkeletalAnimationIncluded; //Compile and attach fragment program if (!fragmentProgram.GLSLProgram.Compile(true)) { triedToLinkAndFailed = true; return; } fragmentProgram.GLSLProgram.AttachToProgramObject(glProgramHandle); //The link GL.LinkProgram(glProgramHandle); GLES2Config.GlCheckError(this); GL.GetProgram(glProgramHandle, GLenum.LinkStatus, ref linked); GLES2Config.GlCheckError(this); triedToLinkAndFailed = (linked == 0) ? true : false; }
public virtual int GetAttributeIndex(VertexElementSemantic semantic, int index) { int res = this.customAttribues[(int)semantic - 1, index]; if (res == NullCustomAttributesIndex) { string attString = this.GetAttributeSemanticString(semantic); int attrib = GL.GetAttribLocation(this.glProgramHandle, attString); GLES2Config.GlCheckError(this); //sadly position is a special case if (attrib == NotFoundCustomAttributesIndex && semantic == VertexElementSemantic.Position) { attrib = GL.GetAttribLocation(this.glProgramHandle, "position"); GLES2Config.GlCheckError(this); } //for uv and other case the index is a part of the name if (attrib == NotFoundCustomAttributesIndex) { string attStringWithSemantic = attString + index.ToString(); attrib = GL.GetAttribLocation(this.glProgramHandle, attStringWithSemantic); GLES2Config.GlCheckError(this); } //update customAttributes with the index we found (or didnt' find) this.customAttribues[(int)semantic - 1, index] = attrib; res = attrib; } return(res); }
public override void Activate() { if (linked == 0 && !triedToLinkAndFailed) { GL.GetError(); glProgramHandle = GL.CreateProgram(); GLES2Config.GlCheckError(this); #if !AXIOM_NO_GLES2_GLSL_OPTIMIZER if (vertexProgram != null) { string paramStr = vertexProgram.GLSLProgram.GetParameter["use_optimiser"]; if (paramStr == "true" || paramStr.Length == 0) { GLSLESLinkProgramManager.Instance.OptimizeShaderSource(vertexProgram); } } if (vertexProgram != null) { string paramStr = fragmentProgram.GLSLProgram.GetParameter("use_optimiser"); if (paramStr == "true" || paramStr.Length == 0) { GLSLESLinkProgramManager.Instance.OptimizeShaderSource(fragmentProgram); } } #endif this.CompileAndLink(); this.ExtractLayoutQualifiers(); this.BuildGLUniformReferences(); } this._useProgram(); }
public override int GetAttributeIndex(Graphics.VertexElementSemantic semantic, int index) { int res = customAttribues[(int)semantic - 1, index]; if (res == NullCustomAttributesIndex) { int handle = vertexProgram.GLSLProgram.GLProgramHandle; string attString = GetAttributeSemanticString(semantic); int attrib = GL.GetAttribLocation(handle, attString); GLES2Config.GlCheckError(this); if (attrib == NotFoundCustomAttributesIndex && semantic == VertexElementSemantic.Position) { attrib = GL.GetAttribLocation(handle, "position"); GLES2Config.GlCheckError(this); } if (attrib == NotFoundCustomAttributesIndex) { string attStringWithSemantic = attString + index.ToString(); attrib = GL.GetAttribLocation(handle, attStringWithSemantic); GLES2Config.GlCheckError(this); } customAttribues[(int)semantic - 1, index] = attrib; res = attrib; } return(res); }
protected override void _useProgram() { if (linked != 0) { GL.UseProgram(glProgramHandle); GLES2Config.GlCheckError(this); } }
public void CheckAndFixInvalidDefaultPrecisionError(string message) { string precisionQualifierErrorString = ": 'Default Precision Qualifier' : invalid type Type for default precision qualifier can be only float or int"; string[] los = source.Split('\n'); var linesOfSource = new List <string>(los); if (message.Contains(precisionQualifierErrorString)) { LogManager.Instance.Write("Fixing invalid type Type fore default precision qualifier by deleting bad lines then re-compiling"); //remove releavant lines from source string[] errors = message.Split('\n'); //going from the end so when we delete a line the numbers of the lines beforew will not change for (int i = errors.Length - 1; i >= 0; i--) { string curError = errors[i]; int foundPos = curError.IndexOf(precisionQualifierErrorString); if (foundPos != -1) { string lineNumber = curError.Substring(0, foundPos); int posOfStartOfNumber = lineNumber.LastIndexOf(':'); if (posOfStartOfNumber != -1) { lineNumber = lineNumber.Substring(posOfStartOfNumber + 1, lineNumber.Length - (posOfStartOfNumber + 1)); int numLine = -1; if (int.TryParse(lineNumber, out numLine)) { linesOfSource.RemoveAt(numLine - 1); } } } } //rebuild source var newSource = new StringBuilder(); for (int i = 0; i < linesOfSource.Count; i++) { newSource.AppendLine(linesOfSource[i]); } source = newSource.ToString(); int r = 0; var sourceArray = new string[] { source }; GL.ShaderSource(this.glShaderHandle, 1, sourceArray, ref r); GLES2Config.GlCheckError(this); if (this.Compile()) { LogManager.Instance.Write("The removing of the lines fixed the invalid type Type for default precision qualifier error."); } else { LogManager.Instance.Write("The removing of the lines didn't help."); } } }
protected override void UnloadHighLevelImpl() { if (IsSupported) { GL.DeleteShader(this.glShaderHandle); GLES2Config.GlCheckError(this); // TODO : Root.Instance.RenderSystem.Capabilities.HasCapability(Capabilities.SeperateShaderObjects)) if (false) { GL.DeleteProgram(this.glProgramHandle); GLES2Config.GlCheckError(this); } } }
public override void UpdatePassIterationUniforms(Graphics.GpuProgramParameters parms) { if (parms.HasPassIterationNumber) { int index = parms.PassIterationNumberIndex; foreach (var currentUniform in glUniformReferences) { if (index == currentUniform.ConstantDef.PhysicalIndex) { unsafe { GL.Uniform1(currentUniform.Location, 1, parms.GetFloatPointer(index).Pointer.ToFloatPointer()); GLES2Config.GlCheckError(this); //There will only be one multipass entry return; } } } } }
public override void UpdateUniforms(Graphics.GpuProgramParameters parms, int mask, Graphics.GpuProgramType fromProgType) { foreach (var currentUniform in glUniformReferences) { //Only pull values from buffer it's supposed to be in (vertex or fragment) //This method will be called twice, once for vertex program params, //and once for fragment program params. if (fromProgType == currentUniform.SourceProgType) { var def = currentUniform.ConstantDef; if (((int)def.Variability & mask) != 0) { int glArraySize = def.ArraySize; switch (def.ConstantType) { case GpuProgramParameters.GpuConstantType.Float1: unsafe { GL.Uniform1(currentUniform.Location, glArraySize, parms.GetFloatPointer(def.PhysicalIndex).Pointer.ToFloatPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Float2: unsafe { GL.Uniform2(currentUniform.Location, glArraySize, parms.GetFloatPointer(def.PhysicalIndex).Pointer.ToFloatPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Float3: unsafe { GL.Uniform3(currentUniform.Location, glArraySize, parms.GetFloatPointer(def.PhysicalIndex).Pointer.ToFloatPointer()); } break; case GpuProgramParameters.GpuConstantType.Float4: unsafe { GL.Uniform4(currentUniform.Location, glArraySize, parms.GetFloatPointer(def.PhysicalIndex).Pointer.ToFloatPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Matrix_2X2: unsafe { GL.UniformMatrix2(currentUniform.Location, glArraySize, false, parms.GetFloatPointer(def.PhysicalIndex).Pointer.ToFloatPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Matrix_3X3: unsafe { GL.UniformMatrix3(currentUniform.Location, glArraySize, false, parms.GetFloatPointer(def.PhysicalIndex).Pointer.ToFloatPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Matrix_4X4: unsafe { GL.UniformMatrix4(currentUniform.Location, glArraySize, false, parms.GetFloatPointer(def.PhysicalIndex).Pointer.ToFloatPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Int1: unsafe { GL.Uniform1(currentUniform.Location, glArraySize, parms.GetIntPointer(def.PhysicalIndex).Pointer.ToIntPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Int2: unsafe { GL.Uniform2(currentUniform.Location, glArraySize, parms.GetIntPointer(def.PhysicalIndex).Pointer.ToIntPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Int3: unsafe { GL.Uniform3(currentUniform.Location, glArraySize, parms.GetIntPointer(def.PhysicalIndex).Pointer.ToIntPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Int4: unsafe { GL.Uniform4(currentUniform.Location, glArraySize, parms.GetIntPointer(def.PhysicalIndex).Pointer.ToIntPointer()); GLES2Config.GlCheckError(this); } break; case GpuProgramParameters.GpuConstantType.Sampler1D: case GpuProgramParameters.GpuConstantType.Sampler1DShadow: case GpuProgramParameters.GpuConstantType.Sampler2D: case GpuProgramParameters.GpuConstantType.Sampler2DShadow: case GpuProgramParameters.GpuConstantType.Sampler3D: case GpuProgramParameters.GpuConstantType.SamplerCube: //samplers handled like 1-elemnt ints unsafe { GL.Uniform1(currentUniform.Location, 1, parms.GetIntPointer(def.PhysicalIndex).Pointer.ToIntPointer()); GLES2Config.GlCheckError(this); } break; } } } } }
public override void Stop() { EGL.Terminate(GlDisplay); GLES2Config.GlCheckError(this); }
public void DetachFromProgramObject(int programObject) { GL.DetachShader(programObject, this.glShaderHandle); GLES2Config.GlCheckError(this); }
public bool Compile(bool checkErrors) { if (this.compiled == 1) { return(true); } //ONly creaet a shader object if glsl es is supported if (IsSupported) { //Create shader object GLenum shaderType = GLenum.None; if (type == GpuProgramType.Vertex) { shaderType = GLenum.VertexShader; } else { shaderType = GLenum.FragmentShader; } this.glShaderHandle = GL.CreateShader(shaderType); GLES2Config.GlCheckError(this); //TODO : Root.Instance.RenderSystem.Capabilities.HasCapability(Capabilities.SeperateShaderObjects)) if (false) { this.glProgramHandle = GL.CreateProgram(); GLES2Config.GlCheckError(this); } } //Add preprocessor extras and main source if (source.Length > 0) { var sourceArray = new string[] { source }; int r = 0; GL.ShaderSource(this.glShaderHandle, 1, sourceArray, ref r); GLES2Config.GlCheckError(this); } if (checkErrors) { LogManager.Instance.Write("GLSL ES compiling: " + Name); } GL.CompileShader(this.glShaderHandle); GLES2Config.GlCheckError(this); //check for compile errors GL.GetShader(this.glShaderHandle, GLenum.CompileStatus, ref this.compiled); GLES2Config.GlCheckError(this); if (this.compiled == 0 && checkErrors) { string message = "GLSL ES compile log: " + Name; this.CheckAndFixInvalidDefaultPrecisionError(message); } //Log a message that the shader compiled successfully. if (this.compiled == 1 && checkErrors) { LogManager.Instance.Write("GLSL ES compiled: " + Name); } return(this.compiled == 1); }
protected override void CompileAndLink() { int linkStatus = 0; //Compile and attach vertex program if (vertexProgram != null && !vertexProgram.IsLinked) { if (!vertexProgram.GLSLProgram.Compile()) { triedToLinkAndFailed = true; return; } int programHandle = vertexProgram.GLSLProgram.GLProgramHandle; //GL.ProgramParameter(programHandle, GLenum.LinkStatus, ref linkStatus); vertexProgram.GLSLProgram.AttachToProgramObject(programHandle); GL.LinkProgram(programHandle); GLES2Config.GlCheckError(this); GL.GetProgram(programHandle, GLenum.LinkStatus, ref linkStatus); GLES2Config.GlCheckError(this); if (linkStatus != 0) { vertexProgram.IsLinked = true; linked |= (int)Linked.VertexProgram; } bool bLinkStatus = (linkStatus != 0); triedToLinkAndFailed = !bLinkStatus; SkeletalAnimationIncluded = vertexProgram.IsSkeletalAnimationIncluded; } //Compile and attach Fragment program if (fragmentProgram != null && !fragmentProgram.IsLinked) { if (!fragmentProgram.GLSLProgram.Compile(true)) { triedToLinkAndFailed = true; return; } int programHandle = fragmentProgram.GLSLProgram.GLProgramHandle; //GL.ProgramParameter(programHandle, GLenum.ProgramSeperableExt, true); fragmentProgram.GLSLProgram.AttachToProgramObject(programHandle); GL.LinkProgram(programHandle); GLES2Config.GlCheckError(this); GL.GetProgram(programHandle, GLenum.LinkStatus, ref linkStatus); GLES2Config.GlCheckError(this); if (linkStatus != 0) { fragmentProgram.IsLinked = true; linked |= (int)Linked.FragmentProgram; } triedToLinkAndFailed = !fragmentProgram.IsLinked; } if (linked != 0) { } }
///<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; } }