1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.Graphic.Shader; 25 26 private: 27 28 import derelict.opengl3.gl; 29 30 import Dgame.Internal.m3; 31 import Dgame.Internal.Error; 32 33 @nogc 34 char[] file_get_contents(string filename) nothrow { 35 import Dgame.Internal.d2c : toStringz; 36 import core.stdc.stdio; 37 38 FILE* f = fopen(toStringz(filename), "rb"); 39 if (f) { 40 scope(exit) fclose(f); 41 42 fseek(f, 0, SEEK_END); 43 immutable size_t length = ftell(f); 44 fseek(f, 0, SEEK_SET); 45 46 char[] buffer = make!(char[])(length * char.sizeof); 47 if (buffer.length) 48 fread(buffer.ptr, char.sizeof, length, f); 49 50 return buffer; 51 } 52 53 return null; 54 } 55 56 public: 57 58 /** 59 * The Shader struct manages a OpenGL Shader instance 60 * The Shader can be loaded and compiled. But to use it, you must pass the Shader to the Program (see below). 61 * 62 * Author: Randy Schuett (rswhite4@googlemail.com) 63 */ 64 struct Shader { 65 private: 66 uint _shader; 67 68 public: 69 /** 70 * The supported Shader-Types 71 */ 72 enum Type { 73 Vertex = GL_VERTEX_SHADER, /// To use as a Vertex-Shader 74 Geometry = GL_GEOMETRY_SHADER, /// To use as a Geometry-Shader 75 Fragment = GL_FRAGMENT_SHADER, /// To use as a Fragment-Shader 76 } 77 78 /** 79 * CTor 80 */ 81 @nogc 82 this(Type type, string filename = null) nothrow { 83 glCreateShader(type); 84 if (filename) 85 this.loadFromFile(filename); 86 } 87 88 /** 89 * Postblit is disabled 90 */ 91 @disable 92 this(this); 93 94 /** 95 * DTor 96 */ 97 @nogc 98 ~this() nothrow { 99 glDeleteShader(_shader); 100 } 101 102 /** 103 * Returns the internal Shader ID 104 */ 105 @nogc 106 @property 107 uint id() const pure nothrow { 108 return _shader; 109 } 110 111 /** 112 * Load the Shader-Source from a file. 113 * 114 * Note: The Shader will not be automatically compiled, use compile to do that by yourself 115 */ 116 @nogc 117 void loadFromFile(string filename) const nothrow { 118 assert(_shader != 0, "Shader was not created so far"); 119 120 char[] buffer = file_get_contents(filename); 121 scope(exit) unmake(buffer); 122 123 const char* ptr = buffer.ptr; 124 glShaderSource(_shader, 1, &ptr, null); 125 } 126 127 /** 128 * Compiles the Shader 129 * 130 * Returns if the compilation was successful 131 */ 132 @nogc 133 bool compile() const nothrow { 134 assert(_shader != 0, "Shader was not created so far"); 135 136 glCompileShader(_shader); 137 138 int isCompiled = 0; 139 glGetShaderiv(_shader, GL_COMPILE_STATUS, &isCompiled); 140 if (isCompiled == GL_FALSE) { 141 int maxLength = 0; 142 glGetShaderiv(_shader, GL_INFO_LOG_LENGTH, &maxLength); 143 144 //The maxLength includes the NULL character 145 char[] infoLog = make!(char[])(maxLength); 146 scope(exit) unmake(infoLog); 147 148 glGetShaderInfoLog(_shader, maxLength, &maxLength, infoLog.ptr); 149 150 print_fmt("Shader could not be compiled: %s\n", infoLog.ptr); 151 152 return false; 153 } 154 155 return true; 156 } 157 }