public unsafe Shader(uint eShaderType, string strFileData) { var shader = Gl.CreateShader(eShaderType); var file = Gl.Utf8ToNative(strFileData); var ptr = Marshal.AllocHGlobal(file.Length); Marshal.Copy(file, 0, ptr, file.Length); var cString = (char *)ptr; Gl.ShaderSource(shader, 1, &cString, null); Marshal.FreeHGlobal(ptr); Gl.CompileShader(shader); int status; Gl.GetShaderiv(shader, Gl.CompileStatus, &status); if (status == 0) { int infoLogLength; Gl.GetShaderiv(shader, Gl.InfoLogLength, &infoLogLength); var strInfoLog = Marshal.AllocHGlobal(infoLogLength + 1); Gl.GetShaderInfoLog(shader, infoLogLength, null, (char *)strInfoLog); var infoLog = Gl.Utf8ToManaged(strInfoLog); Marshal.FreeHGlobal(strInfoLog); throw new Exception("Compile failure in " + GetShaderTypeString(eShaderType) + " shader:" + infoLog); } _hdc = shader; }
/// <summary> /// Compiles a shader, which can be either vertex, fragment or geometry. /// </summary> /// <param name="source">Specifies the source code of the shader object.</param> /// <param name="type">Specifies the type of shader to create (either vertex, fragment or geometry).</param> public Shader(string source, ShaderType type) { this.ShaderType = type; this.ShaderID = Gl.CreateShader(type); Gl.ShaderSource(ShaderID, source); Gl.CompileShader(ShaderID); }
/// <summary> /// Compiles a shader, which can be either vertex, fragment or geometry. /// </summary> /// <param name="source">Specifies the source code of the shader object.</param> /// <param name="type">Specifies the type of shader to create (either vertex, fragment or geometry).</param> public Shader(string source, ShaderType type) { this.ShaderType = type; this.ShaderID = Gl.CreateShader(type); Gl.ShaderSource(ShaderID, source); Gl.CompileShader(ShaderID); //Check whether the shader compiled successfully. //If not then throw an error with the compile error. if (!Gl.GetShaderCompileStatus(ShaderID)) { throw new Exception(ShaderLog); } }
/// <summary> /// Replaces the source code in a shader object. /// </summary> /// <param name="shader">Specifies the handle of the shader object whose source code is to be replaced.</param> /// <param name="source">Specifies a string containing the source code to be loaded into the shader.</param> public static void ShaderSource(UInt32 shader, string source) { int1[0] = source.Length; Gl.ShaderSource(shader, 1, new string[] { source }, int1); }
/// <summary> /// Actually create this ShaderObject resource. /// </summary> /// <param name="ctx"> /// A <see cref="GraphicsContext"/> used for allocating resources. /// </param> protected override void CreateObject(GraphicsContext ctx) { if (ctx == null) { throw new ArgumentNullException("ctx"); } if (_CompilationParams == null) { throw new InvalidOperationException("no compiler parameters"); } // Using a deep copy of the shader compiler context, since it will be modified by this ShaderProgram // instance and the attached ShaderObject instances ShaderCompilerContext cctx = new ShaderCompilerContext(_CompilationParams); sLog.Debug("Compilation of shader object '{0}'.", _SourcePath); List <string> source = GenerateSource(ctx, cctx); // Source generation! // Set shader source Gl.ShaderSource(ObjectName, source.ToArray()); if (ctx.Caps.GlExtensions.ShadingLanguageInclude_ARB) { string[] includePaths = new string[cctx.Includes.Count]; cctx.Includes.CopyTo(includePaths, 0); // Compile shader object (specifying include paths) Gl.CompileShaderIncludeARB(ObjectName, includePaths, null); } else { // Compile shader object (includes are already preprocessed) Gl.CompileShader(ObjectName); } // Check for compilation errors int cStatus; Gl.GetObjectParameterARB(ObjectName, Gl.COMPILE_STATUS, out cStatus); if (cStatus != Gl.TRUE) { StringBuilder sb = GetInfoLog(); // Stop compilation process sLog.Error("Shader object \"{0}\" compilation failed:\n{1}", _SourcePath ?? "<Hardcoded>", sb.ToString()); // Log the source code referred to the shader log sLog.Error("Source code for shader '{0}' that has generated the compiler error.", _SourcePath); sLog.Error("--------------------------------------------------------------------------------"); uint sourcelineNo = 0; foreach (string sourceline in source) { sLog.Error("{0,4} | {1}", ++sourcelineNo, sourceline.Length > 0 ? sourceline.Remove(sourceline.Length - 1, 1) : String.Empty); } sLog.Error("--------------------------------------------------------------------------------"); throw new ShaderException("shader object is not valid. Compiler output for {0}: {1}\n", _SourcePath, sb.ToString()); } else { StringBuilder sb = GetInfoLog(); if (sb.Length > 0) { sLog.Warn("Shader object \"{0}\" compilation warning: {1}", _SourcePath ?? "<Hardcoded>", sb.ToString()); } } _Compiled = true; }