MorphoGraphX
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Shader.hpp
1 #ifndef SHADER_H
2 #define SHADER_H
3 
4 #include <Config.hpp>
5 #include <GL.hpp>
6 
7 #include <Assert.hpp>
8 #include <Matrix.hpp>
9 #include <Parms.hpp>
10 #include <Vector.hpp>
11 
12 #include <iostream>
13 #include <QHash>
14 #include <QString>
15 #include <string>
16 #include <vector>
17 
18 #define CHECK_GL_ERROR(cmd) \
19  cmd; \
20  Shader::reportGLError(#cmd, __FILE__, __LINE__)
21 #define REPORT_GL_ERROR(str) Shader::reportGLError(str, __FILE__, __LINE__)
22 
23 class QString;
24 
25 namespace mgx {
26 
27 typedef util::Vector<1, GLint> ivec1;
28 typedef util::Vector<2, GLint> ivec2;
29 typedef util::Vector<3, GLint> ivec3;
30 typedef util::Vector<4, GLint> ivec4;
31 typedef util::Vector<1, GLfloat> vec1;
32 typedef util::Vector<2, GLfloat> vec2;
33 typedef util::Vector<3, GLfloat> vec3;
34 typedef util::Vector<4, GLfloat> vec4;
35 typedef util::Matrix<2, 2, GLfloat> mat2;
36 typedef util::Matrix<3, 3, GLfloat> mat3;
37 typedef util::Matrix<4, 4, GLfloat> mat4;
38 
39 enum UNIFORM_TYPE {
40  UNIFORM_INT,
41  UNIFORM_INT2,
42  UNIFORM_INT3,
43  UNIFORM_INT4,
44  UNIFORM_FLOAT,
45  UNIFORM_FLOAT2,
46  UNIFORM_FLOAT3,
47  UNIFORM_FLOAT4,
48  UNIFORM_MATRIX2,
49  UNIFORM_MATRIX3,
50  UNIFORM_MATRIX4
51 };
52 
53 class mgx_EXPORT GLSLValue {
54  class Value {
55 public:
56  virtual ~Value() {
57  }
58  virtual void setUniform(GLint location) const = 0;
59  virtual void setAttrib(GLuint location) const = 0;
60  virtual QTextStream& read(QTextStream& s) = 0;
61  virtual QTextStream& write(QTextStream& s) const = 0;
62  virtual std::istream& read(std::istream& s) = 0;
63  virtual std::ostream& write(std::ostream& s) const = 0;
64  virtual Value* copy() = 0;
65  }* value;
66 
67  template <typename T> class ValueImpl : public Value {
68 public:
69  typedef typename T::value_type value_type;
70  typedef void (*uniform_fct)(GLint, GLsizei, const value_type*);
71  typedef void (*attrib_fct)(GLuint, const value_type*);
72 
73  ValueImpl(uniform_fct ufct, attrib_fct afct, const T* v, int count)
74  : Value()
75  , value(v, v + count)
76  , glUniform(ufct)
77  , glVertexAttrib(afct)
78  {
79  }
80 
81  ValueImpl(uniform_fct ufct, attrib_fct afct)
82  : Value()
83  , glUniform(ufct)
84  , glVertexAttrib(afct)
85  {
86  }
87 
88  ValueImpl(const ValueImpl& copy)
89  : Value()
90  , value(copy.value)
91  , glUniform(copy.glUniform)
92  , glVertexAttrib(copy.glVertexAttrib)
93  {
94  }
95 
96  virtual Value* copy() {
97  return new ValueImpl(*this);
98  }
99 
100  virtual void setUniform(GLint location) const {
101  glUniform(location, (GLint)value.size(), value[0].c_data());
102  }
103  virtual void setAttrib(GLuint location) const {
104  glVertexAttrib(location, value[0].c_data());
105  }
106  virtual QTextStream& read(QTextStream& s)
107  {
108  value.resize(1);
109  s >> value[0];
110  return s;
111  }
112  virtual QTextStream& write(QTextStream& s) const
113  {
114  s << value[0];
115  return s;
116  }
117  virtual std::istream& read(std::istream& s)
118  {
119  value.resize(1);
120  s >> value[0];
121  return s;
122  }
123  virtual std::ostream& write(std::ostream& s) const
124  {
125  s << value[0];
126  return s;
127  }
128  std::vector<T> value;
129  uniform_fct glUniform;
130  attrib_fct glVertexAttrib;
131  };
132 
133  UNIFORM_TYPE type;
134 
135 public:
136  GLSLValue()
137  : value(0)
138  , type(UNIFORM_INT)
139  {
140  }
141 
142  GLSLValue(const GLSLValue& copy)
143  : value(0)
144  , type(copy.type)
145  {
146  if(copy.value)
147  value = copy.value->copy();
148  }
149 
150  template <typename T>
151  explicit GLSLValue(const T& val)
152  : value(0)
153  {
154  setValue(val);
155  }
156 
157  template <typename T>
158  explicit GLSLValue(const std::vector<T>& val)
159  : value(0)
160  {
161  setValue(val);
162  }
163 
164  template <typename T>
165  explicit GLSLValue(const T* val, int count)
166  : value(0)
167  {
168  setValue(val, count);
169  }
170 
171  ~GLSLValue() {
172  delete value;
173  }
174  GLSLValue& operator=(const GLSLValue& copy)
175  {
176  delete value;
177  value = 0;
178  if(copy.value)
179  value = copy.value->copy();
180  type = copy.type;
181  return *this;
182  }
183  void setUniform(GLint location) const {
184  value->setUniform(location);
185  }
186  void setAttrib(GLuint location) const {
187  value->setAttrib(location);
188  }
189  std::istream& read(std::istream& s);
190  std::ostream& write(std::ostream& s) const;
191  QTextStream& read(QTextStream& s);
192  QTextStream& write(QTextStream& s) const;
193 
194  void setValue(const GLint* value, int count);
195  void setValue(const ivec1* value, int count);
196  void setValue(const ivec2* value, int count);
197  void setValue(const ivec3* value, int count);
198  void setValue(const ivec4* value, int count);
199  void setValue(const GLfloat* value, int count);
200  void setValue(const vec1* value, int count);
201  void setValue(const vec2* value, int count);
202  void setValue(const vec3* value, int count);
203  void setValue(const vec4* value, int count);
204  void setValue(const mat2* value, int count);
205  void setValue(const mat3* value, int count);
206  void setValue(const mat4* value, int count);
207 
208  void setValue(const GLint& value) {
209  setValue(&value, 1);
210  }
211  void setValue(const ivec1& value) {
212  setValue(&value, 1);
213  }
214  void setValue(const ivec2& value) {
215  setValue(&value, 1);
216  }
217  void setValue(const ivec3& value) {
218  setValue(&value, 1);
219  }
220  void setValue(const ivec4& value) {
221  setValue(&value, 1);
222  }
223  void setValue(const GLfloat& value) {
224  setValue(&value, 1);
225  }
226  void setValue(const vec1& value) {
227  setValue(&value, 1);
228  }
229  void setValue(const vec2& value) {
230  setValue(&value, 1);
231  }
232  void setValue(const vec3& value) {
233  setValue(&value, 1);
234  }
235  void setValue(const vec4& value) {
236  setValue(&value, 1);
237  }
238  void setValue(const mat2& value) {
239  setValue(&value, 1);
240  }
241  void setValue(const mat3& value) {
242  setValue(&value, 1);
243  }
244  void setValue(const mat4& value) {
245  setValue(&value, 1);
246  }
247 
248  bool valid() const {
249  return value != 0;
250  }
251 };
252 
253 inline QTextStream& operator<<(QTextStream& s, const GLSLValue& ut) {
254  return ut.write(s);
255 }
256 
257 inline QTextStream& operator>>(QTextStream& s, GLSLValue& ut) {
258  return ut.read(s);
259 }
260 
261 inline std::ostream& operator<<(std::ostream& s, const GLSLValue& ut) {
262  return ut.write(s);
263 }
264 
265 inline std::istream& operator>>(std::istream& s, GLSLValue& ut) {
266  return ut.read(s);
267 }
268 
269 class mgx_EXPORT Shader {
270 public:
271  enum ActiveTextures {
272  AT_NONE = 0,
273  AT_TEX3D,
274  AT_SECOND_TEX3D,
275  AT_TEX2D,
276  AT_LABEL_TEX,
277  AT_SURF_TEX,
278  AT_HEAT_TEX,
279  AT_DEPTH_TEX,
280  AT_CMAP_TEX,
281  AT_SECOND_CMAP_TEX,
282  AT_SURF_RENDER_TEX,
283  AT_FINAL_VOLUME_TEX,
284  AT_FRONT_TEX,
285  AT_BACK_TEX,
286  AT_FRONT_COLOR_TEX,
287  AT_OCCLUSION_TEX,
288  AT_END
289  };
290  Shader(int verbosity = 1);
291 
292  static void activeTexture(ActiveTextures at) {
293  glActiveTexture(at + GL_TEXTURE0);
294  }
295 
296  static void activeTexture(int at) {
297  glActiveTexture(at + GL_TEXTURE0);
298  }
299 
300  bool init();
301  void invalidate() {
302  _initialized = false;
303  }
304 
305  // void readParms(Parms& parms, QString shaders_section, QString uniforms_section);
306 
307  bool setupShaders();
308  bool useShaders();
309  static bool stopUsingShaders();
310 
311  static bool reportGLError(const char* id, const char* file, int line);
312  static bool reportGLError(const QString& id, const char* file, int line);
313 
314  bool isVertexShaderCode(unsigned int pos) const {
315  return vertex_shaders_code[pos].second;
316  }
317 
318  bool isFragmentShaderCode(unsigned int pos) const {
319  return fragment_shaders_code[pos].second;
320  }
321 
322  const QString& getVertexShader(unsigned int pos) const {
323  return vertex_shaders_code[pos].first;
324  }
325 
326  const QString& getFragmentShader(unsigned int pos) const {
327  return fragment_shaders_code[pos].first;
328  }
329 
330  void addVertexShaderCode(const QString& code);
331  bool changeVertexShaderCode(int pos, const QString& code);
332  void removeVertexShaderCode(const QString& code);
333  void addFragmentShaderCode(const QString& code);
334  bool changeFragmentShaderCode(int pos, const QString& code);
335  void removeFragmentShaderCode(const QString& code);
336 
337  void addVertexShader(const QString& filename);
338  bool changeVertexShader(int pos, const QString& filename);
339  void removeVertexShader(const QString& filename);
340  void addFragmentShader(const QString& filename);
341  bool changeFragmentShader(int pos, const QString& filename);
342  void removeFragmentShader(const QString& filename);
343  void setVerbosity(int verb) {
344  verbosity = verb;
345  }
346 
347  QString shaderTypeName(GLenum shader_type);
348 
349  GLuint compileShaderFile(GLenum shader_type, QString filename);
350  GLuint compileShader(GLenum shader_type, QString content);
351 
352  void printProgramInfoLog(GLuint object);
353  void printShaderInfoLog(GLuint object);
354  void cleanShaders();
355 
356  bool hasShaders() const {
357  return has_shaders;
358  }
359 
360  GLuint program() const {
361  return _program;
362  }
363 
364  void setupUniforms();
365 
366  GLuint attribLocation(const QString& name);
367 
368  void setAttrib(const QString& name, const GLSLValue& value);
369  void setAttrib(GLuint loc, const GLSLValue& value);
370 
371  bool setUniform(const QString& name, const GLSLValue& value);
372  void setUniform_instant(const QString& name, const GLSLValue& value);
373 
374  bool initialized() const {
375  return _initialized;
376  }
377 
378 protected:
379  void loadUniform(GLint program, const QString& name, const GLSLValue& value);
380 
381  bool has_shaders;
382 
383  // if bool is true, then it's really code, otherwise, it's a file
384  typedef std::pair<QString, bool> code_t;
385  std::vector<code_t> vertex_shaders_code, fragment_shaders_code;
386 
387  std::vector<GLuint> vertex_shaders, fragment_shaders;
388 
389  std::vector<QString> uniform_names, model_uniform_names;
390  std::vector<GLSLValue> uniform_values, model_uniform_values;
391 
392  int verbosity;
393 
394  GLuint _program;
395 
396  bool _initialized;
397 };
398 } // namespace mgx
399 #endif // SHADER_H
AttribBase(const QString &name) const QString & name()
Default constructor of named attribute.
Definition: Attributes.hpp:54
Defines the util::Parms class.
Definition: Shader.hpp:269
Graphical (or textual) assertion utility.
Namespace containing all the utility classes.
Definition: Vector.hpp:37
Definition: Shader.hpp:53
Class representing a fixed-size matrix.
Definition: Matrix.hpp:34
Defines the Matrix class template This file is shared by cuda, do not include headers that nvcc can't...
Defines the Vector class template This file is shared by cuda, do not include headers that nvcc can't...