ScummVM API documentation
shader.h
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 modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (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, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef GRAPHICS_OPENGL_SHADER_H
23 #define GRAPHICS_OPENGL_SHADER_H
24 
25 #include "common/file.h"
26 #include "common/array.h"
27 #include "common/ptr.h"
28 
29 #include "math/matrix3.h"
30 #include "math/matrix4.h"
31 #include "math/vector2d.h"
32 #include "math/vector3d.h"
33 #include "math/vector4d.h"
34 
35 #include "graphics/opengl/debug.h"
36 #include "graphics/opengl/system_headers.h"
37 
38 namespace OpenGL {
39 
40 struct VertexAttrib {
41  VertexAttrib(uint32 idx, const char *name) :
42  _enabled(false), _idx(idx), _name(name), _vbo(0), _size(0),
43  _type(GL_FLOAT), _normalized(false), _stride(0), _pointer(0) {}
44  bool _enabled;
45  uint32 _idx;
46  Common::String _name;
47  GLuint _vbo;
48  GLint _size;
49  GLenum _type;
50  bool _normalized;
51  GLsizei _stride;
52  uintptr _pointer;
53  float _const[4];
54 };
55 
56 class Shader {
58 
59 public:
60  Shader();
61  ~Shader();
62  Shader *clone() {
63  return new Shader(*this);
64  }
65 
66  void use(bool forceReload = false);
67 
68  bool setUniform(const Common::String &uniform, const Math::Matrix4 &m) {
69  GLint pos = getUniformLocation(uniform);
70  if (pos != -1) {
71  use();
72  GL_CALL(glUniformMatrix4fv(pos, 1, GL_FALSE, m.getData()));
73  return true;
74  } else {
75  return false;
76  }
77  }
78 
79  bool setUniform(const Common::String &uniform, const Math::Matrix3 &m) {
80  GLint pos = getUniformLocation(uniform);
81  if (pos != -1) {
82  use();
83  GL_CALL(glUniformMatrix3fv(pos, 1, GL_FALSE, m.getData()));
84  return true;
85  } else {
86  return false;
87  }
88  }
89 
90  bool setUniform(const Common::String &uniform, const Math::Vector4d &v) {
91  GLint pos = getUniformLocation(uniform);
92  if (pos != -1) {
93  use();
94  GL_CALL(glUniform4fv(pos, 1, v.getData()));
95  return true;
96  } else {
97  return false;
98  }
99  }
100 
101  bool setUniform(const Common::String &uniform, const Math::Vector3d &v) {
102  GLint pos = getUniformLocation(uniform);
103  if (pos != -1) {
104  use();
105  GL_CALL(glUniform3fv(pos, 1, v.getData()));
106  return true;
107  } else {
108  return false;
109  }
110  }
111 
112  bool setUniform(const Common::String &uniform, const Math::Vector2d &v) {
113  GLint pos = getUniformLocation(uniform);
114  if (pos != -1) {
115  use();
116  GL_CALL(glUniform2fv(pos, 1, v.getData()));
117  return true;
118  } else {
119  return false;
120  }
121  }
122 
123  bool setUniform(const Common::String &uniform, unsigned int x) {
124  GLint pos = getUniformLocation(uniform);
125  if (pos != -1) {
126  use();
127  GL_CALL(glUniform1i(pos, x));
128  return true;
129  } else {
130  return false;
131  }
132  }
133 
134  bool setUniform(const Common::String &uniform, const int size, const int *array) {
135  GLint pos = getUniformLocation(uniform);
136  if (pos != -1) {
137  use();
138  GL_CALL(glUniform1iv(pos, size, array));
139  return true;
140  } else {
141  return false;
142  }
143  }
144 
145  // Different name to avoid overload ambiguity
146  bool setUniform1f(const Common::String &uniform, float f) {
147  GLint pos = getUniformLocation(uniform);
148  if (pos != -1) {
149  use();
150  GL_CALL(glUniform1f(pos, f));
151  return true;
152  } else {
153  return false;
154  }
155  }
156 
157  GLint getUniformLocation(const Common::String &uniform) const {
158  UniformsMap::iterator kv = _uniforms->find(uniform);
159  if (kv == _uniforms->end()) {
160  GLint ret;
161  GL_ASSIGN(ret, glGetUniformLocation(*_shaderNo, uniform.c_str()));
162  _uniforms->setVal(uniform, ret);
163  return ret;
164  } else {
165  return kv->_value;
166  }
167  }
168 
169  void enableVertexAttribute(const char *attrib, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
170  void enableVertexAttribute(const char *attrib, GLuint vbo, GLint size, GLenum type, GLboolean normalized, GLsizei stride, uint32 offset);
171  void disableVertexAttribute(const char *attrib, int size, const float *data);
172  template <int r>
173  void disableVertexAttribute(const char *attrib, const Math::Matrix<r,1> &m) {
174  disableVertexAttribute(attrib, r, m.getData());
175  }
176  bool addAttribute(const char *attrib);
177  VertexAttrib & getAttributeAt(uint32 idx);
178  VertexAttrib & getAttribute(const char *attrib);
179 
180  static GLuint createBuffer(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage = GL_STATIC_DRAW);
181  static void freeBuffer(GLuint vbo);
182 
197  static Shader *fromFiles(const char *vertex, const char *fragment, const char *const *attributes, int compatGLSLVersion = 120);
198  static Shader *fromFiles(const char *shared, const char *const *attributes, int compatGLSLVersion = 120) {
199  return fromFiles(shared, shared, attributes, compatGLSLVersion);
200  }
201 
216  static Shader *fromStrings(const Common::String &name, const char *vertex, const char *fragment, const char *const *attributes, int compatGLSLVersion = 0);
217 
218  bool loadFromFiles(const char *vertex, const char *fragment, const char *const *attributes, int compatGLSLVersion = 120);
219  bool loadFromStrings(const Common::String &name, const char *vertex, const char *fragment, const char *const *attributes, int compatGLSLVersion = 0);
220 
235  bool loadFromStringsArray(const Common::String &name,
236  size_t vertexCount, const char *const *vertex,
237  size_t fragmentCount, const char *const *fragment,
238  const char *const *attributes);
239 
240  void unbind();
241 
242  Common::String &getError() { return _error; }
243  bool hasError() { return !_error.empty(); }
244 
245 private:
246  bool loadShader(const Common::String &name, GLuint vertexShader, GLuint fragmentShader, const char *const *attributes);
247 
248  GLuint createCompatShader(const char *shaderSource, GLenum shaderType, const Common::String &name, int compatGLSLVersion);
249  GLuint createDirectShader(size_t shaderSourcesCount, const char *const *shaderSources, GLenum shaderType, const Common::String &name);
250  GLuint loadShaderFromFile(const char *base, const char *extension, GLenum shaderType, int compatGLSLVersion);
251 
252  // Since this class is cloned using the implicit copy constructor,
253  // a reference counting pointer is used to ensure deletion of the OpenGL
254  // program upon destruction of the last clone.
255  Common::SharedPtr<GLuint> _shaderNo;
256 
257  Common::String _name;
258 
259  Common::Array<VertexAttrib> _attributes;
261 
262  static Shader *_previousShader;
263  static uint32 previousNumAttributes;
264 
265  Common::String _error;
266 };
267 
268 } // End of namespace OpenGL
269 
270 #endif
Definition: str.h:59
Definition: array.h:52
Definition: shader.h:56
Definition: hashmap.h:85
Definition: shader.h:40
Definition: renderbuffer.h:27