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