1 module D2DGame.Rendering.Shader; 2 3 import D2D; 4 5 /// All valid types of shaders for the `Shader` class. 6 enum ShaderType : ubyte 7 { 8 /// Vertex Shader 9 Vertex, 10 /// Tessellation Control Shader 11 TessControl, 12 /// Tessellation Evaluation Shader 13 TessEvaluation, 14 /// Geometry Shader 15 Geometry, 16 /// Fragment/Pixel Shader 17 Fragment 18 } 19 20 /// Class containing a single shader for combining in a ShaderProgram. 21 class Shader : IVerifiable 22 { 23 /// Loads the shader content into memory. 24 public bool load(ShaderType type, string content) 25 { 26 this.content = content; 27 switch (type) 28 { 29 case ShaderType.Vertex: 30 _id = glCreateShader(GL_VERTEX_SHADER); 31 break; 32 case ShaderType.TessControl: 33 _id = glCreateShader(GL_TESS_CONTROL_SHADER); 34 break; 35 case ShaderType.TessEvaluation: 36 _id = glCreateShader(GL_TESS_EVALUATION_SHADER); 37 break; 38 case ShaderType.Geometry: 39 _id = glCreateShader(GL_GEOMETRY_SHADER); 40 break; 41 case ShaderType.Fragment: 42 _id = glCreateShader(GL_FRAGMENT_SHADER); 43 break; 44 default: 45 throw new Exception("ShaderType " ~ to!string(type) ~ " is not defined!"); 46 } 47 48 const int len = cast(const(int)) content.length; 49 50 glShaderSource(_id, 1, [content.ptr].ptr, &len); 51 return true; 52 } 53 54 /// Creates a shader, loads the content and compiles it in one function. 55 static Shader create(ShaderType type, string content) 56 { 57 Shader shader = new Shader(); 58 shader.load(type, content); 59 shader.compile(); 60 return shader; 61 } 62 63 /// Compiles the shader and throws an Exception if an error occured. 64 /// Will automatically be called when attaching the shader to a ShaderProgram instance. 65 public bool compile() 66 { 67 if (compiled) 68 return true; 69 glCompileShader(_id); 70 int success = 0; 71 glGetShaderiv(_id, GL_COMPILE_STATUS, &success); 72 73 if (success == 0) 74 { 75 int logSize = 0; 76 glGetShaderiv(_id, GL_INFO_LOG_LENGTH, &logSize); 77 78 char* log = new char[logSize].ptr; 79 glGetShaderInfoLog(_id, logSize, &logSize, &log[0]); 80 81 throw new Exception(cast(string) log[0 .. logSize]); 82 } 83 compiled = true; 84 return true; 85 } 86 87 /// The OpenGL id of this shader. 88 public @property uint id() 89 { 90 return _id; 91 } 92 93 /// Checks if this shader is valid. 94 public @property bool valid() 95 { 96 return _id > 0; 97 } 98 99 private uint _id = 0; 100 private string content; 101 private bool compiled = false; 102 }