public static LogObjectInfo ( string message, int handle ) : string | ||
message | string | The info log message string is appended to this string. |
handle | int | The GL object handle that is used to retrieve the info log |
return | string |
/// <summary> /// Makes a program object active by making sure it is linked and then putting it in use. /// </summary> public void Activate() { if(!linked) { int linkStatus; Gl.glLinkProgramARB(glHandle); Gl.glGetObjectParameterivARB(glHandle, Gl.GL_OBJECT_LINK_STATUS_ARB, out linkStatus); linked = (linkStatus != 0); // force logging and raise exception if not linked GLSLHelper.CheckForGLSLError("Error linking GLSL Program Object", glHandle, !linked, !linked); if(linked) { GLSLHelper.LogObjectInfo("GLSL link result : ", glHandle); BuildUniformReferences(); } } if(linked) { Gl.glUseProgramObjectARB(glHandle); } }
/// <summary> /// /// </summary> /// <param name="checkErrors"></param> protected bool Compile(bool checkErrors) { Gl.glCompileShaderARB(glHandle); int compiled; // check for compile errors Gl.glGetObjectParameterivARB(glHandle, Gl.GL_OBJECT_COMPILE_STATUS_ARB, out compiled); isCompiled = (compiled != 0); // force exception if not compiled if (checkErrors) { GLSLHelper.CheckForGLSLError("Cannot compile GLSL high-level shader: " + name + " ", glHandle, !isCompiled, !isCompiled); if (isCompiled) { GLSLHelper.LogObjectInfo(name + " : GLGL compiled ", glHandle); } } return(isCompiled); }
protected internal bool Compile(bool checkErrors) { if (this.isCompiled) { return(true); } if (checkErrors) { GLSLHelper.LogObjectInfo("GLSL compiling: " + Name, GLHandle); } if (IsSupported) { GLSLHelper.CheckForGLSLError("GL Errors before creating shader object", 0); var shaderType = 0; switch (Type) { case GpuProgramType.Vertex: shaderType = Gl.GL_VERTEX_SHADER_ARB; break; case GpuProgramType.Fragment: shaderType = Gl.GL_FRAGMENT_SHADER_ARB; break; case GpuProgramType.Geometry: shaderType = Gl.GL_GEOMETRY_SHADER_EXT; break; } GLHandle = Gl.glCreateShaderObjectARB(shaderType); GLSLHelper.CheckForGLSLError("Error creating GLSL shader object", 0); } // Preprocess the GLSL shader in order to get a clean source // CPreprocessor cpp; // TODO: preprocessor not supported yet in axiom // Add preprocessor extras and main source if (!string.IsNullOrEmpty(source)) { Gl.glShaderSourceARB(GLHandle, 1, new[] { source }, new[] { source.Length }); // check for load errors GLSLHelper.CheckForGLSLError("Cannot load GLSL high-level shader source : " + Name, 0); } Gl.glCompileShaderARB(GLHandle); int compiled; // check for compile errors Gl.glGetObjectParameterivARB(GLHandle, Gl.GL_OBJECT_COMPILE_STATUS_ARB, out compiled); this.isCompiled = (compiled != 0); // force exception if not compiled if (checkErrors) { GLSLHelper.CheckForGLSLError("GLSL : Cannot compile GLSL high-level shader: " + Name + ".", GLHandle, !this.isCompiled, !this.isCompiled); if (this.isCompiled) { GLSLHelper.LogObjectInfo("GLSL : " + Name + " : compiled.", GLHandle); } } return(this.isCompiled); }
private void CompileAndLink() { if (this.vertexProgram != null) { // compile and attach Vertex Program if (!this.vertexProgram.GLSLProgram.Compile(true)) { // todo error return; } this.vertexProgram.GLSLProgram.AttachToProgramObject(this.glHandle); IsSkeletalAnimationIncluded = this.vertexProgram.IsSkeletalAnimationIncluded; // Some drivers (e.g. OS X on nvidia) incorrectly determine the attribute binding automatically // and end up aliasing existing built-ins. So avoid! // Bind all used attribs - not all possible ones otherwise we'll get // lots of warnings in the log, and also may end up aliasing names used // as varyings by accident // Because we can't ask GL whether an attribute is used in the shader // until it is linked (chicken and egg!) we have to parse the source var vpSource = this.vertexProgram.GLSLProgram.Source; foreach (var a in this.sCustomAttributes) { // we're looking for either: // attribute vec<n> <semantic_name> // in vec<n> <semantic_name> // The latter is recommended in GLSL 1.3 onwards // be slightly flexible about formatting var pos = vpSource.IndexOf(a.name); if (pos != -1) { var startpos = vpSource.IndexOf("attribute", pos < 20 ? 0 : pos - 20); if (startpos == -1) { startpos = vpSource.IndexOf("in", pos < 20 ? 0 : pos - 20); } if (startpos != -1 && startpos < pos) { // final check var expr = vpSource.Substring(startpos, pos + a.name.Length - startpos); var vec = expr.Split(); if ((vec[0] == "in" || vec[0] == "attribute") && vec[2] == a.name) { Gl.glBindAttribLocationARB(this.glHandle, (int)a.attrib, a.name); } } } } } if (this.geometryProgram != null) { // compile and attach Geometry Program if (!this.geometryProgram.GLSLProgram.Compile(true)) { // todo error return; } this.geometryProgram.GLSLProgram.AttachToProgramObject(this.glHandle); //Don't set adjacency flag. We handle it internally and expose "false" OperationType inputOperationType = this.geometryProgram.GLSLProgram.InputOperationType; Gl.glProgramParameteriEXT(this.glHandle, Gl.GL_GEOMETRY_INPUT_TYPE_EXT, GetGLGeometryInputPrimitiveType(inputOperationType, this.geometryProgram.IsAdjacencyInfoRequired)); OperationType outputOperationType = this.geometryProgram.GLSLProgram.OutputOperationType; switch (outputOperationType) { case OperationType.PointList: case OperationType.LineStrip: case OperationType.TriangleStrip: case OperationType.LineList: case OperationType.TriangleList: case OperationType.TriangleFan: break; } Gl.glProgramParameteriEXT(this.glHandle, Gl.GL_GEOMETRY_OUTPUT_TYPE_EXT, GetGLGeometryOutputPrimitiveType(outputOperationType)); Gl.glProgramParameteriEXT(this.glHandle, Gl.GL_GEOMETRY_VERTICES_OUT_EXT, this.geometryProgram.GLSLProgram.MaxOutputVertices); } if (this.fragmentProgram != null) { if (!this.fragmentProgram.GLSLProgram.Compile(true)) { // todo error return; } this.fragmentProgram.GLSLProgram.AttachToProgramObject(this.glHandle); } // now the link Gl.glLinkProgramARB(this.glHandle); int linkStatus; Gl.glGetObjectParameterivARB(this.glHandle, Gl.GL_OBJECT_LINK_STATUS_ARB, out linkStatus); this.linked = linkStatus != 0; this.triedToLinkAndFailed = !this.linked; GLSLHelper.CheckForGLSLError("Error linking GLSL Program Object", this.glHandle, !this.linked, !this.linked); if (this.linked) { GLSLHelper.LogObjectInfo(CombinedName + " GLSL link result : ", this.glHandle); // TODO: cache the microcode. // OpenTK is not up to date yet for this. // We need deeper engine updates for this as well /* * if (GpuProgramManager.Instance.SaveMicrocodesToCache) * { * // add to the microcode to the cache * var name = CombinedName; * * // get buffer size * int binaryLength; * Gl.glGetProgramiv( glHandle, Gl.GL_PROGRAM_BINARY_LENGTH, out binaryLength ); * * // turns out we need this param when loading * // it will be the first bytes of the array in the microcode * int binaryFormat; * * // create microcode * GpuProgramManager.Microcode newMicrocode = * GpuProgramManager.Instance.CreateMicrocode( binaryLength + sizeof ( GLenum ) ); * * // get binary * uint8* programBuffer = newMicrocode->getPtr() + sizeof ( GLenum ); * glGetProgramBinary( mGLHandle, binaryLength, NULL, &binaryFormat, programBuffer ); * * // save binary format * memcpy( newMicrocode->getPtr(), &binaryFormat, sizeof ( GLenum ) ); * * // add to the microcode to the cache * GpuProgramManager::getSingleton().addMicrocodeToCache( name, newMicrocode ); * }*/ } }