1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef BACKENDS_GRAPHICS_OPENGL_SHADER_H 24 #define BACKENDS_GRAPHICS_OPENGL_SHADER_H 25 26 #include "backends/graphics/opengl/opengl-sys.h" 27 28 #if !USE_FORCED_GLES 29 30 #include "common/singleton.h" 31 #include "common/hash-str.h" 32 #include "common/ptr.h" 33 34 namespace OpenGL { 35 36 /** 37 * A generic uniform value interface for a shader program. 38 */ 39 class ShaderUniformValue { 40 public: ~ShaderUniformValue()41 virtual ~ShaderUniformValue() {} 42 43 /** 44 * Setup the the value to the given location. 45 * 46 * @param location Location of the uniform. 47 */ 48 virtual void set(GLint location) const = 0; 49 }; 50 51 /** 52 * Integer value for a shader uniform. 53 */ 54 class ShaderUniformInteger : public ShaderUniformValue { 55 public: ShaderUniformInteger(GLint value)56 ShaderUniformInteger(GLint value) : _value(value) {} 57 58 virtual void set(GLint location) const override; 59 60 private: 61 const GLint _value; 62 }; 63 64 /** 65 * Float value for a shader uniform. 66 */ 67 class ShaderUniformFloat : public ShaderUniformValue { 68 public: ShaderUniformFloat(GLfloat value)69 ShaderUniformFloat(GLfloat value) : _value(value) {} 70 71 virtual void set(GLint location) const override; 72 73 private: 74 const GLfloat _value; 75 }; 76 77 /** 78 * 4x4 Matrix value for a shader uniform. 79 */ 80 class ShaderUniformMatrix44 : public ShaderUniformValue { 81 public: ShaderUniformMatrix44(const GLfloat * mat44)82 ShaderUniformMatrix44(const GLfloat *mat44) { 83 memcpy(_matrix, mat44, sizeof(_matrix)); 84 } 85 86 virtual void set(GLint location) const override; 87 88 private: 89 GLfloat _matrix[4*4]; 90 }; 91 92 class Shader { 93 public: 94 Shader(const Common::String &vertex, const Common::String &fragment); 95 ~Shader(); 96 97 /** 98 * Destroy the shader program. 99 * 100 * This keeps the vertex and fragment shader sources around and thus 101 * allows for recreating the shader on context recreation. It also keeps 102 * the uniform state around. 103 */ 104 void destroy(); 105 106 /** 107 * Recreate shader program. 108 * 109 * @return true on success, false on failure. 110 */ 111 bool recreate(); 112 113 /** 114 * Make shader active. 115 */ 116 void activate(); 117 118 /** 119 * Make shader inactive. 120 */ 121 void deactivate(); 122 123 /** 124 * Return location for attribute with given name. 125 * 126 * @param name Name of the attribute to look up in the shader. 127 * @return The loctaion of -1 if attribute was not found. 128 */ 129 GLint getAttributeLocation(const char *name) const; getAttributeLocation(const Common::String & name)130 GLint getAttributeLocation(const Common::String &name) const { 131 return getAttributeLocation(name.c_str()); 132 } 133 134 /** 135 * Return location for uniform with given name. 136 * 137 * @param name Name of the uniform to look up in the shader. 138 * @return The location or -1 if uniform was not found. 139 */ 140 GLint getUniformLocation(const char *name) const; getUniformLocation(const Common::String & name)141 GLint getUniformLocation(const Common::String &name) const { 142 return getUniformLocation(name.c_str()); 143 } 144 145 /** 146 * Bind value to uniform. 147 * 148 * @param name The name of the uniform to be set. 149 * @param value The value to be set. 150 * @return 'false' on error (i.e. uniform unknown or otherwise), 151 * 'true' otherwise. 152 */ 153 bool setUniform(const Common::String &name, ShaderUniformValue *value); 154 155 /** 156 * Bind integer value to uniform. 157 * 158 * @param name The name of the uniform to be set. 159 * @param value The value to be set. 160 * @return 'false' on error (i.e. uniform unknown or otherwise), 161 * 'true' otherwise. 162 */ setUniform1I(const Common::String & name,GLint value)163 bool setUniform1I(const Common::String &name, GLint value) { 164 return setUniform(name, new ShaderUniformInteger(value)); 165 } 166 protected: 167 /** 168 * Vertex shader sources. 169 */ 170 const Common::String _vertex; 171 172 /** 173 * Fragment shader sources. 174 */ 175 const Common::String _fragment; 176 177 /** 178 * Whether the shader is active or not. 179 */ 180 bool _isActive; 181 182 /** 183 * Shader program handle. 184 */ 185 GLprogram _program; 186 187 /** 188 * A uniform descriptor. 189 * 190 * This stores the state of a shader uniform. The state is made up of the 191 * uniform location, whether the state was altered since last set, and the 192 * value of the uniform. 193 */ 194 struct Uniform { UniformUniform195 Uniform() : location(-1), altered(false), value() {} UniformUniform196 Uniform(GLint loc, ShaderUniformValue *val) 197 : location(loc), altered(true), value(val) {} 198 199 /** 200 * Write uniform value into currently active shader. 201 */ setUniform202 void set() { 203 if (altered && value) { 204 value->set(location); 205 altered = false; 206 } 207 } 208 209 /** 210 * The location of the uniform or -1 in case it does not exist. 211 */ 212 GLint location; 213 214 /** 215 * Whether the uniform state was aletered since last 'set'. 216 */ 217 bool altered; 218 219 /** 220 * The value of the uniform. 221 */ 222 Common::SharedPtr<ShaderUniformValue> value; 223 }; 224 225 typedef Common::HashMap<Common::String, Uniform> UniformMap; 226 227 /** 228 * Map from uniform name to associated uniform description. 229 */ 230 UniformMap _uniforms; 231 232 /** 233 * Compile a vertex or fragment shader. 234 * 235 * @param source Sources to the shader. 236 * @param shaderType Type of shader to compile (GL_FRAGMENT_SHADER_ARB or 237 * GL_VERTEX_SHADER_ARB) 238 * @return The shader object or 0 on failure. 239 */ 240 static GLshader compileShader(const char *source, GLenum shaderType); 241 }; 242 243 class ShaderManager : public Common::Singleton<ShaderManager> { 244 public: 245 enum ShaderUsage { 246 /** Default shader implementing the GL fixed-function pipeline. */ 247 kDefault = 0, 248 249 /** CLUT8 look up shader. */ 250 kCLUT8LookUp, 251 252 /** Number of built-in shaders. Should not be used for query. */ 253 kMaxUsages 254 }; 255 256 /** 257 * Notify shader manager about context destruction. 258 */ 259 void notifyDestroy(); 260 261 /** 262 * Notify shader manager about context creation. 263 */ 264 void notifyCreate(); 265 266 /** 267 * Query a built-in shader. 268 */ 269 Shader *query(ShaderUsage shader) const; 270 271 private: 272 friend class Common::Singleton<SingletonBaseType>; 273 ShaderManager(); 274 ~ShaderManager(); 275 276 bool _initializeShaders; 277 278 Shader *_builtIn[kMaxUsages]; 279 }; 280 281 } // End of namespace OpenGL 282 283 /** Shortcut for accessing the font manager. */ 284 #define ShaderMan (OpenGL::ShaderManager::instance()) 285 286 #endif // !USE_FORCED_GLES 287 288 #endif 289