Allolib  1.0
C++ Components For Interactive Multimedia
al_Shader.hpp
1 #ifndef INCLUDE_AL_GRAPHICS_SHADER_HPP
2 #define INCLUDE_AL_GRAPHICS_SHADER_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology, UCSB.
8  Copyright (C) 2012. The Regents of the University of California.
9  All rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are met:
13 
14  Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16 
17  Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 
21  Neither the name of the University of California nor the names of its
22  contributors may be used to endorse or promote products derived from
23  this software without specific prior written permission.
24 
25  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
29  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  POSSIBILITY OF SUCH DAMAGE.
36 
37 
38  File description:
39  Wrappers to OpenGL GLSL shaders
40 
41  File author(s):
42  Lance Putnam, 2010, putnam.lance@gmail.com
43  Graham Wakefield, 2010, grrrwaaa@gmail.com
44  Wesley Smith, 2010, wesley.hoke@gmail.com
45  Keehong Youn, 2017, younkeehong@gmail.com
46 
47 */
48 
49 #include <string>
50 #include <unordered_map>
51 #include "al/graphics/al_GPUObject.hpp"
52 #include "al/math/al_Mat.hpp"
53 #include "al/math/al_Quat.hpp"
54 #include "al/math/al_Vec.hpp"
55 #include "al/types/al_Color.hpp"
56 
57 #define AL_SHADER_MAX_LOG_SIZE 4096
58 
59 namespace al {
60 
63 class ShaderBase : public GPUObject {
64  public:
65  virtual ~ShaderBase() {}
66 
68  const char *log() const;
69 
71  void printLog() const;
72 
73  protected:
74  virtual void get(int pname, void *params) const = 0;
75  virtual void getLog(char *buf) const = 0;
76 };
77 
79 
83 class Shader : public ShaderBase {
84  public:
85  enum Type { VERTEX, GEOMETRY, FRAGMENT };
86 
87  Shader(const std::string &source = "", Shader::Type type = FRAGMENT);
88 
91  virtual ~Shader() { destroy(); }
92 
93  Shader &source(const std::string &v);
94  Shader &source(const std::string &v, Shader::Type type);
95  Shader &compile();
96  bool compiled() const;
97 
98  Shader::Type type() const { return mType; }
99 
100  private:
101  std::string mSource;
102  Shader::Type mType;
103 
104  virtual void get(int pname, void *params) const;
105  virtual void getLog(char *buf) const;
106 
107  virtual void onCreate();
108  virtual void onDestroy();
109 };
110 
112 
116 class ShaderProgram : public ShaderBase {
117  public:
121  enum Type {
122  NONE = 0, // uninitialized type
123 
128 
129  INT,
133 
138 
142 
150 
151  // textures? non square matrices? attributes?
152  };
153 
154  struct Attribute {};
155 
156  ShaderProgram();
157 
159  virtual ~ShaderProgram();
160 
162 
166 
168  const ShaderProgram &detach(const Shader &s) const;
169 
171 
176  const ShaderProgram &link(bool doValidate = true) const;
177 
179  bool compile(const std::string &vertSource, const std::string &fragSource,
180  const std::string &geomSource = "");
181 
182  const ShaderProgram &use();
183 
185  void begin();
186 
188  void end() const;
189 
191  bool linked() const;
192 
194  bool validateProgram(bool printLog = false) const;
195 
197  void listParams() const;
198 
200  int getUniformLocation(const char *name) const;
201  int getUniformLocation(const std::string &s) const {
202  return getUniformLocation(s.c_str());
203  }
204 
206  int attribute(const char *name) const;
207 
208  const ShaderProgram &uniform(const char *name, const Color &c) const {
209  return uniform4(name, c.components);
210  }
211 
212  void uniform4f(int loc, float v0, float v1, float v2, float v3) const;
213  void uniformMat4f(int loc, float *data) const;
214 
215  const ShaderProgram &uniform(int loc, int v) const;
216  const ShaderProgram &uniform(int loc, float v) const;
217  const ShaderProgram &uniform(int loc, double v) const {
218  return uniform(loc, float(v));
219  }
220  const ShaderProgram &uniform(int loc, float v0, float v1) const;
221  const ShaderProgram &uniform(int loc, float v0, float v1, float v2) const;
222  const ShaderProgram &uniform(int loc, float v0, float v1, float v2,
223  float v3) const;
224  const ShaderProgram &uniform4v(int loc, const float *v, int count = 1) const;
225 
226  template <typename T>
227  const ShaderProgram &uniform(int loc, const Vec<2, T> &v) const {
228  return uniform(loc, v.x, v.y);
229  }
230  template <typename T>
231  const ShaderProgram &uniform(int loc, const Vec<3, T> &v) const {
232  return uniform(loc, v.x, v.y, v.z);
233  }
234  template <typename T>
235  const ShaderProgram &uniform(int loc, const Vec<4, T> &v) const {
236  return uniform(loc, v.x, v.y, v.z, v.w);
237  }
238  const ShaderProgram &uniformMatrix3(int loc, const float *v,
239  bool transpose = false) const;
240  const ShaderProgram &uniformMatrix4(int loc, const float *v,
241  bool transpose = false) const;
242  const ShaderProgram &uniform(int loc, const Mat<4, float> &m) const {
243  return uniformMatrix4(loc, m.elems());
244  }
245  template <typename T>
246  const ShaderProgram &uniform(int loc, const Mat<4, T> &m) const {
247  return uniform(loc, Mat4f(m));
248  }
249 
250  const ShaderProgram &uniform(const char *name, int v) const;
251  const ShaderProgram &uniform(const char *name, float v) const;
252  const ShaderProgram &uniform(const char *name, double v) const {
253  return uniform(name, float(v));
254  }
255  const ShaderProgram &uniform(const char *name, float v0, float v1) const;
256  const ShaderProgram &uniform(const char *name, float v0, float v1,
257  float v2) const;
258  const ShaderProgram &uniform(const char *name, float v0, float v1, float v2,
259  float v3) const;
260 
261  template <typename T>
262  const ShaderProgram &uniform(const char *name, const Vec<2, T> &v) const {
263  return uniform(name, v.x, v.y);
264  }
265 
266  template <typename T>
267  const ShaderProgram &uniform(const char *name, const Vec<3, T> &v) const {
268  return uniform(name, v.x, v.y, v.z);
269  }
270 
271  template <typename T>
272  const ShaderProgram &uniform(const char *name, const Vec<4, T> &v) const {
273  return uniform(name, v.x, v.y, v.z, v.w);
274  }
275 
276  const ShaderProgram &uniform(const char *name, const Mat<4, float> &m,
277  bool transpose = false) const {
278  return uniformMatrix4(name, m.elems(), transpose);
279  }
280 
281  template <typename T>
282  const ShaderProgram &uniform(const char *name, const Mat<4, T> &m,
283  bool transpose = false) const {
284  return uniform(name, Mat4f(m), transpose);
285  }
286 
287  template <typename T>
288  const ShaderProgram &uniform(const char *name, const Quat<T> &q) const {
289  // note wxyz => xyzw for GLSL vec4:
290  return uniform(name, q.x, q.y, q.z, q.w);
291  }
292 
293  const ShaderProgram &uniform1(const char *name, const float *v,
294  int count = 1) const;
295  const ShaderProgram &uniform2(const char *name, const float *v,
296  int count = 1) const;
297  const ShaderProgram &uniform3(const char *name, const float *v,
298  int count = 1) const;
299  const ShaderProgram &uniform4(const char *name, const float *v,
300  int count = 1) const;
301 
302  const ShaderProgram &uniformMatrix3(const char *name, const float *v,
303  bool transpose = false) const;
304  const ShaderProgram &uniformMatrix4(const char *name, const float *v,
305  bool transpose = false) const;
306 
307  const ShaderProgram &attribute(int loc, float v) const;
308  const ShaderProgram &attribute(int loc, float v0, float v1) const;
309  const ShaderProgram &attribute(int loc, float v0, float v1, float v2) const;
310  const ShaderProgram &attribute(int loc, float v0, float v1, float v2,
311  float v3) const;
312 
313  const ShaderProgram &attribute(const char *name, float v) const;
314  const ShaderProgram &attribute(const char *name, float v0, float v1) const;
315  const ShaderProgram &attribute(const char *name, float v0, float v1,
316  float v2) const;
317  const ShaderProgram &attribute(const char *name, float v0, float v1, float v2,
318  float v3) const;
319 
320  const ShaderProgram &attribute1(const char *name, const float *v) const;
321  const ShaderProgram &attribute2(const char *name, const float *v) const;
322  const ShaderProgram &attribute3(const char *name, const float *v) const;
323  const ShaderProgram &attribute4(const char *name, const float *v) const;
324  const ShaderProgram &attribute1(int loc, const double *v) const;
325  const ShaderProgram &attribute2(int loc, const double *v) const;
326  const ShaderProgram &attribute3(int loc, const double *v) const;
327  const ShaderProgram &attribute4(int loc, const double *v) const;
328 
329  template <typename T>
330  const ShaderProgram &attribute(int loc, const Vec<2, T> &v) const {
331  return attribute(loc, v.x, v.y);
332  }
333  template <typename T>
334  const ShaderProgram &attribute(int loc, const Vec<3, T> &v) const {
335  return attribute(loc, v.x, v.y, v.z);
336  }
337  template <typename T>
338  const ShaderProgram &attribute(int loc, const Vec<4, T> &v) const {
339  return attribute(loc, v.x, v.y, v.z, v.w);
340  }
341  template <typename T>
342  const ShaderProgram &attribute(int loc, const Quat<T> &q) const {
343  // note wxyz => xyzw for GLSL vec4:
344  return attribute(loc, q.x, q.y, q.z, q.w);
345  }
346 
347  static void use(unsigned programID);
348 
349  protected:
350  // Graphics::Primitive mInPrim, mOutPrim; // IO primitives for geometry
351  // shaders unsigned int mOutVertices;
352  std::string mVertSource, mFragSource, mGeomSource;
353  mutable std::unordered_map<std::string, int> mUniformLocs, mAttribLocs;
354  // bool mActive;
355 
356  virtual void get(int pname, void *params) const;
357  virtual void getLog(char *buf) const;
358 
359  virtual void onCreate();
360  virtual void onDestroy();
361 };
362 
363 } // namespace al
364 
365 #endif
void destroy()
Destroys object on GPU.
void printLog() const
Prints info log, if any.
const char * log() const
Returns info log or 0 if none.
Shader object.
Definition: al_Shader.hpp:83
virtual ~Shader()
Definition: al_Shader.hpp:91
Shader program object.
Definition: al_Shader.hpp:116
const ShaderProgram & detach(const Shader &s) const
Detach shader from program.
const ShaderProgram & link(bool doValidate=true) const
Link attached shaders.
virtual void onCreate()
Called when currently assigned context is created.
void end() const
End use of shader program.
bool validateProgram(bool printLog=false) const
Returns whether linked program can execute in current graphics state.
@ BOOL4
Four bool values.
Definition: al_Shader.hpp:137
@ SAMPLER_1D
A 1D texture.
Definition: al_Shader.hpp:143
@ BOOL3
Three bool values.
Definition: al_Shader.hpp:136
@ SAMPLER_CUBE
A cubemap texture.
Definition: al_Shader.hpp:147
@ FLOAT
A single float value.
Definition: al_Shader.hpp:124
@ INT3
Three int values.
Definition: al_Shader.hpp:131
@ SAMPLER_RECT
A rectangular texture.
Definition: al_Shader.hpp:145
@ VEC2
Two float values.
Definition: al_Shader.hpp:125
@ MAT22
A 2x2 matrix.
Definition: al_Shader.hpp:139
@ BOOL
A single bool value.
Definition: al_Shader.hpp:134
@ INT2
Two int values.
Definition: al_Shader.hpp:130
@ MAT44
A 4x4 matrix.
Definition: al_Shader.hpp:141
@ SAMPLER_2D_SHADOW
A 2D depth texture.
Definition: al_Shader.hpp:149
@ VEC3
Three float values.
Definition: al_Shader.hpp:126
@ BOOL2
Two bool values.
Definition: al_Shader.hpp:135
@ SAMPLER_1D_SHADOW
A 1D depth texture.
Definition: al_Shader.hpp:148
@ INT
A single int value.
Definition: al_Shader.hpp:129
@ VEC4
Four float values.
Definition: al_Shader.hpp:127
@ INT4
Four int values.
Definition: al_Shader.hpp:132
@ MAT33
A 3x3 matrix.
Definition: al_Shader.hpp:140
@ SAMPLER_2D
A 2D texture.
Definition: al_Shader.hpp:144
@ SAMPLER_3D
A 3D texture.
Definition: al_Shader.hpp:146
int attribute(const char *name) const
Get location of attribute.
virtual ~ShaderProgram()
Any attached shaders will automatically be detached, but not deleted.
ShaderProgram & attach(Shader &s)
Attach shader to program.
void begin()
Begin use of shader program.
void listParams() const
Print out all the input parameters to the shader.
bool linked() const
Returns whether program linked successfully.
bool compile(const std::string &vertSource, const std::string &fragSource, const std::string &geomSource="")
Compile and link shader sources.
int getUniformLocation(const char *name) const
Get location of uniform.
virtual void onDestroy()
Called when currently assigned context is destroyed.
Definition: al_App.hpp:23
Mat< 4, float > Mat4f
float 4x4 matrix
Definition: al_Mat.hpp:61
float components[4]
RGBA component vector.
Definition: al_Color.hpp:76