1 /* 2 Copyright © 2020, Luna Nielsen 3 Distributed under the 2-Clause BSD License, see LICENSE file. 4 5 Authors: Luna Nielsen 6 */ 7 module engine.render.shader; 8 import engine; 9 import std.string; 10 import gl3n.linalg; 11 12 /** 13 A shader 14 */ 15 class Shader { 16 private: 17 GLuint shaderProgram; 18 GLuint fragShader; 19 GLuint vertShader; 20 21 void compileShaders(string vertex, string fragment) { 22 23 // Compile vertex shader 24 vertShader = glCreateShader(GL_VERTEX_SHADER); 25 auto c_vert = vertex.toStringz; 26 glShaderSource(vertShader, 1, &c_vert, null); 27 glCompileShader(vertShader); 28 verifyShader(vertShader); 29 30 // Compile fragment shader 31 fragShader = glCreateShader(GL_FRAGMENT_SHADER); 32 auto c_frag = fragment.toStringz; 33 glShaderSource(fragShader, 1, &c_frag, null); 34 glCompileShader(fragShader); 35 verifyShader(fragShader); 36 37 // Attach and link them 38 shaderProgram = glCreateProgram(); 39 glAttachShader(shaderProgram, vertShader); 40 glAttachShader(shaderProgram, fragShader); 41 glLinkProgram(shaderProgram); 42 verifyProgram(); 43 } 44 45 void verifyShader(GLuint shader) { 46 47 // Get the length of the error log 48 GLint logLength; 49 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); 50 if (logLength > 0) { 51 52 // Fetch the error log 53 char[] log = new char[logLength]; 54 glGetShaderInfoLog(shader, logLength, null, log.ptr); 55 56 AppLog.fatal("Engine::Shader", cast(string)log); 57 } 58 } 59 60 void verifyProgram() { 61 62 // Get the length of the error log 63 GLint logLength; 64 glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &logLength); 65 if (logLength > 0) { 66 67 // Fetch the error log 68 char[] log = new char[logLength]; 69 glGetProgramInfoLog(shaderProgram, logLength, null, log.ptr); 70 71 AppLog.fatal("Engine::Shader", cast(string)log); 72 } 73 } 74 75 public: 76 77 /** 78 Destructor 79 */ 80 ~this() { 81 glDetachShader(shaderProgram, vertShader); 82 glDetachShader(shaderProgram, fragShader); 83 glDeleteProgram(shaderProgram); 84 85 glDeleteShader(fragShader); 86 glDeleteShader(vertShader); 87 } 88 89 /** 90 Creates a new shader object from source 91 */ 92 this(string vertex, string fragment) { 93 compileShaders(vertex, fragment); 94 } 95 96 /** 97 Use the shader 98 */ 99 void use() { 100 glUseProgram(shaderProgram); 101 } 102 103 GLint getUniformLocation(string name) { 104 return glGetUniformLocation(shaderProgram, name.ptr); 105 } 106 107 void setUniform(GLint uniform, bool value) { 108 glUniform1i(uniform, cast(int)value); 109 } 110 111 void setUniform(GLint uniform, int value) { 112 glUniform1i(uniform, value); 113 } 114 115 void setUniform(GLint uniform, float value) { 116 glUniform1f(uniform, value); 117 } 118 119 void setUniform(GLint uniform, vec2 value) { 120 glUniform2f(uniform, value.x, value.y); 121 } 122 123 void setUniform(GLint uniform, vec3 value) { 124 glUniform3f(uniform, value.x, value.y, value.z); 125 } 126 127 void setUniform(GLint uniform, vec4 value) { 128 glUniform4f(uniform, value.x, value.y, value.z, value.w); 129 } 130 131 void setUniform(GLint uniform, mat4 value) { 132 glUniformMatrix4fv(uniform, 1, GL_TRUE, value.value_ptr); 133 } 134 }