GLShader Class v0.1.0.1 - 12-30-2013

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Reflection;
using System.IO;
using System.Windows.Forms;
using System.Xml;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;

[assembly: AssemblyProduct("OpenTK/OpenGL Library")]
[assembly: AssemblyCopyright("Copyright © Jason Beighel")]
[assembly: AssemblyTrademark("Mindlence")]
[assembly: AssemblyVersion("0.1.0.1")]
[assembly: AssemblyFileVersion("0.1.0.1")]

namespace MDLN {
 namespace GLTools {
  public class GLShader {
   public enum ErrorCodes {None, CompileFail, LinkFail, InvalidAttrName};

   private int ciProgram;
   private ErrorCodes ceErrCode;
   private string cstrErrDesc, cstrVertexFile, cstrFragmentFile, cstrName;
   private List clUniformList, clAttribList;

   public GLShader() {
    //Initilize class variables
    ciProgram = -1;
    ceErrCode = ErrorCodes.None;
    cstrErrDesc = "";
    clUniformList = new List();
    clAttribList = new List();
   }

   public string VertexFile {
    get {
     return cstrVertexFile;
    }

    set {
     cstrVertexFile = value;

     return;
    }
   }

   public string FragmentFile {
    get {
     return cstrFragmentFile;
    }

    set {
     cstrFragmentFile = value;

     return;
    }
   }

   public string Name {
    get {
     return cstrName;
    }

    set {
     cstrName = value;

     return;
    }
   }

   public int Program {
    get {
     return ciProgram;
    }
   }

   public string ErrorDescription {
    get {
     return cstrErrDesc;
    }
   }

   public ErrorCodes ErrorCode {
    get {
     return ceErrCode;
    }
   }

   public bool AddUniform(string strName, int iID) {
    ShaderVar oNewVar;

    oNewVar = new ShaderVar(iID, strName);

    clUniformList.Add(oNewVar);

    return true;
   }

   public bool AddAttribute(string strName, int iID) {
    ShaderVar oNewVar;

    oNewVar = new ShaderVar(iID, strName);

    clAttribList.Add(oNewVar);

    return true;
   }

   public int FindUniformID(string strName) {
    foreach (ShaderVar oUniform in clUniformList) {
     if (oUniform.VariableName == strName) {
      return oUniform.VariableID;
     }
    }

    return -1;
   }

   public int FindAttributeID(string strName) {
    ceErrCode = ErrorCodes.None;
    cstrErrDesc = "";

    foreach (ShaderVar oAttr in clAttribList) {
     if (oAttr.VariableName == strName) {
      return oAttr.VariableID;
     }
    }

    ceErrCode = ErrorCodes.InvalidAttrName;
    cstrErrDesc = "Unable to find an attribute with the name " + strName;

    return -1;
   }

   public bool BuildShader() {
    int iVertShader, iFragShader, iUniformID, iNewProgram, iStatus;
    bool bRetVal = true;

    cstrErrDesc = "";
    ceErrCode = ErrorCodes.None;

    //Create Vertex shader
    iVertShader = GL.CreateShader(ShaderType.VertexShader);
    using (StreamReader srShader = new StreamReader(cstrVertexFile)) {
     GL.ShaderSource(iVertShader, srShader.ReadToEnd());
    }
    GL.CompileShader(iVertShader);
  
    GL.GetShader(iVertShader, ShaderParameter.CompileStatus, out iStatus);
    if (iStatus != 1) { //Failed to compile
     bRetVal = false;
     ceErrCode = ErrorCodes.CompileFail;
     cstrErrDesc = "Vertex Shader failed to compile.\n" + GL.GetShaderInfoLog(iVertShader) + "\n";
    }

    //Create Fragment shader
    iFragShader = GL.CreateShader(ShaderType.FragmentShader);
    using (StreamReader srShader = new StreamReader(cstrFragmentFile)) {
     GL.ShaderSource(iFragShader, srShader.ReadToEnd());
    }
    GL.CompileShader(iFragShader);
  
    GL.GetShader(iFragShader, ShaderParameter.CompileStatus, out iStatus);
    if (iStatus != 1) { //Failed to compile
     bRetVal = false;
     ceErrCode = ErrorCodes.CompileFail;
     cstrErrDesc = cstrErrDesc + "Fragment Shader failed to compile.\n" + GL.GetShaderInfoLog(iFragShader);
    }

    if (bRetVal != true) { //If a compile error happens, stop
     return bRetVal;
    }

    //Build the program
    iNewProgram = GL.CreateProgram();
    GL.AttachShader(iNewProgram, iVertShader);
    GL.AttachShader(iNewProgram, iFragShader);

    //Assign attribute buffers]
    foreach (ShaderVar oAttr in clAttribList) {
     GL.BindAttribLocation(iNewProgram, oAttr.VariableID, oAttr.VariableName);
    }

    //Link the program
    GL.LinkProgram(iNewProgram);
    GL.GetProgram(iNewProgram, ProgramParameter.LinkStatus, out iStatus);
    if (iStatus != 1) { //Failed to link
     bRetVal = false;
     ceErrCode = ErrorCodes.LinkFail;
     cstrErrDesc = "Shading program failed to link.\n" + GL.GetProgramInfoLog(iNewProgram);
    }

    if (bRetVal != true) { //If a link error happens, stop
     return bRetVal;
    }

    //Define uniform blocks
    foreach (ShaderVar oUniform in clUniformList) {
     iUniformID = GL.GetUniformBlockIndex(iNewProgram, oUniform.VariableName);
     GL.UniformBlockBinding(iNewProgram, iUniformID, oUniform.VariableID);
    }

    //Cleanup
    GL.DeleteShader(iVertShader);
    GL.DeleteShader(iFragShader);

    if (ciProgram != -1) { //Delete old program
     GL.DeleteProgram(ciProgram);
    }

    ciProgram = iNewProgram;
    return true;
   }

   private class ShaderVar {
    private int ciVarID;
    private string cstrVarName;

    public ShaderVar() : this(0, "") {}  //Chained constructor

    public ShaderVar(int iID, string strName) {
     ciVarID = iID;
     cstrVarName = strName;
    }

    public string VariableName {
     get {
      return cstrVarName;
     }

     set {
      cstrVarName = value;
     }
    }

    public int VariableID {
     get {
      return ciVarID;
     }

     set {
      ciVarID = value;
     }
    }
   }
  }
 }
}

No comments:

Post a Comment