/// <summary> /// Creates a new instance of <see cref="QFontSharedState"/> /// </summary> /// <param name="defaultTextureUnit">The default texture unit</param> /// <param name="shaderVariables">The shader variables</param> public QFontSharedState(TextureUnit defaultTextureUnit, ShaderLocations shaderVariables) { DefaultTextureUnit = defaultTextureUnit; ShaderVariables = shaderVariables; }
/// <summary> /// Initializes the static shared render state using builtin shaders /// </summary> private static void InitialiseStaticState() { // Enable 2D textures GL.Enable(EnableCap.Texture2D); //Create vertex and fragment shaders int vert = GL.CreateShader(ShaderType.VertexShader); int frag = GL.CreateShader(ShaderType.FragmentShader); //Check shaders were created succesfully if (vert == -1 || frag == -1) { throw new Exception(string.Format("Error creating shader name for {0}", vert == -1 ? (frag == -1 ? "vert and frag shaders" : "vert shader") : "frag shader")); } // We try to compile the shaders with ever increasing version numbers (up to 1.50) // This fixes a bug on MaxOSX where the Core profile only supports shaders >= 1.50 (or sometimes 1.40) var versions = new[] { SHADER_VERSION_STRING130, SHADER_VERSION_STRING140, SHADER_VERSION_STRING150 }; // Holds the compilation status of the shaders int vertCompileStatus = 0; int fragCompileStatus = 0; foreach (var version in versions) { #if OPENGL_ES GL.ShaderSource(vert, LoadShaderFromResource("simple_es.vs")); GL.ShaderSource(frag, LoadShaderFromResource("simple_es.fs")); #else GL.ShaderSource(vert, version + LoadShaderFromResource("simple.vs")); GL.ShaderSource(frag, version + LoadShaderFromResource("simple.fs")); #endif GL.CompileShader(vert); GL.CompileShader(frag); GL.GetShader(vert, ShaderParameter.CompileStatus, out vertCompileStatus); GL.GetShader(frag, ShaderParameter.CompileStatus, out fragCompileStatus); // Check shaders were compiled correctly // If they have, we break out of the foreach loop as we have found the minimum supported glsl version if (vertCompileStatus != 0 && fragCompileStatus != 0) { break; } // Otherwise continue with the loop } // Check that we ended up with a compiled shader at the end of all this // These will only be 0 if all compilations with different versions failed, // since we break out of the version loop as soon as one compiles if (vertCompileStatus == 0 || fragCompileStatus == 0) { string vertInfo = GL.GetShaderInfoLog(vert); string fragInfo = GL.GetShaderInfoLog(frag); throw new Exception(String.Format("Shaders were not compiled correctly. Info logs are\nVert:\n{0}\nFrag:\n{1}", vertInfo, fragInfo)); } int prog; int progLinkStatus; prog = GL.CreateProgram(); GL.AttachShader(prog, vert); GL.AttachShader(prog, frag); GL.LinkProgram(prog); //Check program was linked without errors GL.GetProgram(prog, GetProgramParameterName.LinkStatus, out progLinkStatus); if (progLinkStatus == 0) { string programInfoLog = GL.GetProgramInfoLog(prog); throw new Exception(String.Format("Program was not linked correctly. Info log is\n{0}", programInfoLog)); } //Detach then delete unneeded shaders GL.DetachShader(prog, vert); GL.DetachShader(prog, frag); GL.DeleteShader(vert); GL.DeleteShader(frag); //Retrieve shader attribute and uniform locations int projLoc = GL.GetUniformLocation(prog, "proj_matrix"); int mvLoc = GL.GetUniformLocation(prog, "modelview_matrix"); int samplerLoc = GL.GetUniformLocation(prog, "tex_object"); int posLoc = GL.GetAttribLocation(prog, "in_position"); int tcLoc = GL.GetAttribLocation(prog, "in_tc"); int colLoc = GL.GetAttribLocation(prog, "in_colour"); //Now we have all the information, time to create the shared state object var shaderVariables = new ShaderLocations { ShaderProgram = prog, ProjectionMatrixUniformLocation = projLoc, ModelViewMatrixUniformLocation = mvLoc, TextureCoordAttribLocation = tcLoc, PositionCoordAttribLocation = posLoc, SamplerLocation = samplerLoc, ColorCoordAttribLocation = colLoc, }; var sharedState = new QFontSharedState(TextureUnit.Texture0, shaderVariables); _sharedState = sharedState; }