public static DemoSource LoadSource(string filePathName) { var source = new DemoSource(); // Check the file name suffix to determine what type of shader this is if(Path.GetExtension(filePathName) == ".fsh") { source.ShaderType = All.FragmentShader; } else if(Path.GetExtension(filePathName) == ".vsh") { source.ShaderType = All.VertexShader; } else { // Unknown source.ShaderType = (All)0; } var fileContent = File.ReadAllText(filePathName); source.String = fileContent; return source; }
int BuildProgramWithVertexSource(DemoSource vertexSource, DemoSource fragmentSource, bool hasNormal, bool hasTexcoord) { int prgName = 0; int logLength = 0, status = 0; // String to pass to Gl.ShaderSource var sourceString = string.Empty; // Determine if GLSL version 140 is supported by this context. // We'll use this info to generate a GLSL shader source string // with the proper version preprocessor string prepended float glLanguageVersion; var glVerString = GL.GetString( StringName.ShadingLanguageVersion); glLanguageVersion = Convert.ToSingle(glVerString.Replace("OpenGL ES GLSL ES", string.Empty)); // All.ShadingLanguageVersion returns the version standard version form // with decimals, but the GLSL version preprocessor directive simply // uses integers (thus 1.10 should 110 and 1.40 should be 140, etc.) // We multiply the floating point number by 100 to get a proper // number for the GLSL preprocessor directive int version = Convert.ToInt32(100 * glLanguageVersion); prgName = GL.CreateProgram(); // Indicate the attribute indicies on which vertex arrays will be // set with GL.VertexAttribPointer // See BuildVAO to see where vertex array are actually set GL.BindAttribLocation(prgName, POS_ATTRIB_IDX, "inPosition"); if(hasNormal) { GL.BindAttribLocation(prgName, NORMAL_ATTRIB_IDX, "inNormal"); } if(hasTexcoord) { GL.BindAttribLocation(prgName, TEXCOORD_ATTRIB_IDX, "inTexcoord"); } ////////////////////////////////////// // Specify and compile VertexShader // ////////////////////////////////////// // Prepend our vertex shader source string with the supported GLSL version so // the shader will work on ES, Legacy, and OpenGL 3.2 Core Profile contexts sourceString = string.Format("#version {0}\n{1}", version, vertexSource.String); int vertexShader; if(!CompileShader(out vertexShader, ShaderType.VertexShader, sourceString)) { Console.WriteLine("Could not Compile Vertex Shader"); return 0; } GL.AttachShader(prgName, vertexShader); ///////////////////////////////////////// // Specify and compile Fragment Shader // ///////////////////////////////////////// sourceString = string.Format("#version {0}\n{1}", version, fragmentSource.String); int fragShader; if(!CompileShader(out fragShader, ShaderType.FragmentShader, sourceString)) { Console.WriteLine("Could not Compile Fragment Shader"); return 0; } // Attach the fragment shader to our program GL.AttachShader(prgName, fragShader); ////////////////////// // Link the program // ////////////////////// GL.LinkProgram(prgName); GL.GetProgram(prgName, ProgramParameter.InfoLogLength, out logLength); if(logLength > 0) { var log = new StringBuilder(logLength); GL.GetProgramInfoLog(prgName, logLength, out logLength, log); Console.WriteLine("Program link log: " + log.ToString()); } GL.GetProgram(prgName, ProgramParameter.LinkStatus, out status); if(status == 0) { Console.WriteLine("Failed to link program"); return 0; } GL.ValidateProgram(prgName); GL.GetProgram(prgName, ProgramParameter.InfoLogLength, out logLength); if(logLength > 0) { var log = new StringBuilder(logLength); GL.GetProgramInfoLog(prgName, logLength, out logLength, log); Console.WriteLine("Program validate log: " + log.ToString()); } GL.GetProgram(prgName, ProgramParameter.ValidateStatus, out status); if(status == 0) { Console.WriteLine("Failed to validate program"); return 0; } GL.UseProgram(prgName); /////////////////////////////////////// // Setup common program input points // /////////////////////////////////////// int sampleLoc = GL.GetUniformLocation(prgName, "diffuseTexture"); // Indicate that the diffuse texture will be bound to texture uint 0 var uint0 = 0; GL.Uniform1 (sampleLoc, uint0); GetGLError(); return prgName; }