VolViz
A volume visualization tool
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
ShaderProgram.h
Go to the documentation of this file.
1 #ifndef VolViz_ShaderProgram_h
2 #define VolViz_ShaderProgram_h
3 
4 #include "Error.h"
5 #include "GLdefs.h"
6 
7 #include <Eigen/Core>
8 
9 #include <string>
10 #include <unordered_map>
11 #include <vector>
12 
13 namespace VolViz {
14 namespace Private_ {
15 namespace GL {
16 
17 class ShaderProgram;
18 
20 class Shader {
21 public:
23 
25 
26  Shader(Shader const &) = delete;
27 
28  inline Shader(Shader &&rhs) noexcept {
29  using std::swap;
30  swap(shader_, rhs.shader_);
31  }
32 
33  inline Shader &operator=(Shader &&rhs) noexcept {
34  using std::swap;
35  swap(shader_, rhs.shader_);
36  return *this;
37  }
38 
39 private:
40  void compile() const;
41 
42  friend class ShaderProgram;
43 
45 };
46 
47 class UniformProxy {
48 public:
49  inline UniformProxy(GLint loccation) noexcept : location_(loccation) {}
50 
51  UniformProxy(UniformProxy const &) = delete;
52  UniformProxy(UniformProxy &&) = default;
53 
54  UniformProxy const &operator=(float f) const noexcept {
55  assertGL("Precondition violation");
57  assertGL("Failed to upload uniform");
58  return *this;
59  }
60 
61  UniformProxy const &operator=(GLint i) const noexcept {
62  assertGL("Precondition violation");
64  assertGL("Failed to upload uniform");
65  return *this;
66  }
67 
68  UniformProxy const &operator=(GLuint i) const noexcept {
69  assertGL("Precondition violation");
71  assertGL("Failed to upload uniform");
72  return *this;
73  }
74 
75  UniformProxy const &operator=(Eigen::Vector2f const &v) const noexcept {
76  assertGL("Precondition violation");
77  glUniform2fv(location_, 1, v.data());
78  assertGL("Failed to upload uniform");
79  return *this;
80  }
81 
82  UniformProxy const &operator=(Eigen::Vector3f const &v) const noexcept {
83  assertGL("Precondition violation");
84  glUniform3fv(location_, 1, v.data());
85  assertGL("Failed to upload uniform");
86  return *this;
87  }
88 
89  UniformProxy const &operator=(Eigen::Vector4f const &v) const noexcept {
90  assertGL("Precondition violation");
91  glUniform4fv(location_, 1, v.data());
92  assertGL("Failed to upload uniform");
93  return *this;
94  }
95 
96  UniformProxy const &operator=(Eigen::Matrix4f const &m) const noexcept {
97  assertGL("Precondition violation");
98  glUniformMatrix4fv(location_, 1, false, m.data());
99  assertGL("Failed to upload uniform");
100  return *this;
101  }
102 
103  UniformProxy const &
104  operator=(Eigen::Transpose<Eigen::Matrix4f> const &m) const noexcept {
105  assertGL("Precondition violation");
106  glUniformMatrix4fv(location_, 1, true, m.nestedExpression().data());
107  assertGL("Failed to upload uniform");
108  return *this;
109  }
110 
111  UniformProxy const &operator=(Eigen::Matrix3f const &m) const noexcept {
112  assertGL("Precondition violation");
113  glUniformMatrix3fv(location_, 1, true, m.data());
114  assertGL("Failed to upload uniform");
115  return *this;
116  }
117 
118 private:
120 };
121 
122 #pragma clang diagnostic push
123 #pragma clang diagnostic ignored "-Wpadded"
124 class ShaderProgram {
126 public:
127  inline ShaderProgram() noexcept {
128  assertGL("OpenGL error stack not clean");
130  assert(program_ != 0 && "Shader program creation failed");
131  }
132 
133  inline ~ShaderProgram() {
134  detachShaders();
136  }
137 
138  ShaderProgram(ShaderProgram const &) = delete;
139 
140  inline ShaderProgram(ShaderProgram &&rhs) noexcept {
141  using std::swap;
142  swap(program_, rhs.program_);
143  swap(attachedShaders_, rhs.attachedShaders_);
144  swap(uniforms_, rhs.uniforms_);
145  }
146 
147  inline ShaderProgram &operator=(ShaderProgram &&rhs) noexcept {
148  using std::swap;
149  swap(program_, rhs.program_);
150  swap(attachedShaders_, rhs.attachedShaders_);
151  swap(uniforms_, rhs.uniforms_);
152  return *this;
153  }
154 
155  inline ShaderProgram &attachShader(Shader const &shader) noexcept {
156  glAttachShader(program_, shader.shader_);
157  assertGL("Shader attachment failed");
158  attachedShaders_.push_back(shader.shader_);
159  return *this;
160  }
161 
162  template <class Container>
163  inline ShaderProgram &attachShaders(Container &&c) noexcept {
164  for (auto const &s : std::forward<Container>(c)) attachShader(s);
165  return *this;
166  }
167 
168  ShaderProgram &link();
169 
170  inline void use() const noexcept {
171  assertGL("Dirty OpenGL error stack");
173  assertGL("Failed to use program");
174  }
175 
176  inline UniformProxy const &operator[](std::string const &name) const {
177  auto search = uniforms_.find(name);
178  if (search != uniforms_.end()) return search->second;
179 
180  throw std::runtime_error(name +
181  " is not an active uniform of shader program " +
182  std::to_string(program_));
183  // Dummy return statement because GCC is complaining, this code is never
184  // reached!
185  return uniforms_.begin()->second;
186  }
187 
188  inline auto activeUniformNames() const {
189  std::vector<std::string> activeUniforms;
190  for (auto const &kv : uniforms_) activeUniforms.push_back(kv.first);
191  return activeUniforms;
192  }
193 
194 private:
195  inline void detachShaders() noexcept {
196  for (auto s : attachedShaders_) glDetachShader(program_, s);
197  attachedShaders_.clear();
198  }
199 
200  void queryUniforms();
201 
202  using UniformTable = std::unordered_map<std::string, UniformProxy>;
203 
204  std::vector<GLuint> attachedShaders_;
207 };
208 #pragma clang diagnostic pop
209 
210 } // namespace GL
211 } // namespace Private_
212 } // namespace VolViz
213 
214 #endif // VolViz_ShaderProgram_h
int GLint
Definition: glad.h:684
void assertGL(char const *txt) noexcept
Definition: Error.h:17
void use() const noexcept
Definition: ShaderProgram.h:170
~ShaderProgram()
Definition: ShaderProgram.h:133
GLsizei const GLchar *const * string
Definition: glad.h:2514
#define glUniform1i
Definition: glad.h:2534
const GLdouble * v
Definition: glad.h:2583
#define glDetachShader
Definition: glad.h:2450
UniformProxy const & operator=(Eigen::Matrix4f const &m) const noexcept
Definition: ShaderProgram.h:96
#define glDeleteProgram
Definition: glad.h:2444
void queryUniforms()
Definition: ShaderProgram.cpp:71
unsigned int GLenum
Definition: glad.h:678
GLint const location_
Definition: ShaderProgram.h:119
GLenum type
Definition: glad.h:732
unsigned int GLuint
Definition: glad.h:688
UniformProxy(GLint loccation) noexcept
Definition: ShaderProgram.h:49
~Shader()
Definition: ShaderProgram.h:24
ShaderProgram(ShaderProgram &&rhs) noexcept
Definition: ShaderProgram.h:140
#define glUniform2fv
Definition: glad.h:2549
RAII wrapper for OpenGL shader programs objects.
Definition: ShaderProgram.h:125
GLuint shader
Definition: glad.h:2427
RAII wrapper for OpenGL shader objects.
Definition: ShaderProgram.h:20
UniformProxy const & operator[](std::string const &name) const
Definition: ShaderProgram.h:176
UniformProxy const & operator=(Eigen::Transpose< Eigen::Matrix4f > const &m) const noexcept
Definition: ShaderProgram.h:104
const GLubyte * c
Definition: glad.h:14924
UniformProxy const & operator=(Eigen::Vector4f const &v) const noexcept
Definition: ShaderProgram.h:89
GLuint shader_
Definition: ShaderProgram.h:44
GLuint const GLchar * name
Definition: glad.h:2430
auto activeUniformNames() const
Definition: ShaderProgram.h:188
UniformTable uniforms_
Definition: ShaderProgram.h:205
GLuint program_
Definition: ShaderProgram.h:206
#define glUniform3fv
Definition: glad.h:2552
Shader(Shader &&rhs) noexcept
Definition: ShaderProgram.h:28
#define glAttachShader
Definition: glad.h:2429
ShaderProgram & attachShader(Shader const &shader) noexcept
Definition: ShaderProgram.h:155
UniformProxy const & operator=(GLuint i) const noexcept
Definition: ShaderProgram.h:68
#define glUniform1f
Definition: glad.h:2522
void compile() const
Definition: ShaderProgram.cpp:21
void detachShaders() noexcept
Definition: ShaderProgram.h:195
Shader(GLenum type, std::string const &source)
Definition: ShaderProgram.cpp:12
ShaderProgram & link()
Definition: ShaderProgram.cpp:46
UniformProxy const & operator=(Eigen::Matrix3f const &m) const noexcept
Definition: ShaderProgram.h:111
UniformProxy const & operator=(Eigen::Vector2f const &v) const noexcept
Definition: ShaderProgram.h:75
#define glUniform1ui
Definition: glad.h:2842
std::unordered_map< std::string, UniformProxy > UniformTable
Definition: ShaderProgram.h:202
#define glUniformMatrix4fv
Definition: glad.h:2576
ShaderProgram & attachShaders(Container &&c) noexcept
Definition: ShaderProgram.h:163
std::vector< GLuint > attachedShaders_
Definition: ShaderProgram.h:204
Eigen::Vector3f Vector3f
Definition: Types.h:15
#define glUseProgram
Definition: glad.h:2519
ShaderProgram & operator=(ShaderProgram &&rhs) noexcept
Definition: ShaderProgram.h:147
#define glUniformMatrix3fv
Definition: glad.h:2573
ShaderProgram() noexcept
Definition: ShaderProgram.h:127
const GLfloat * m
Definition: glad.h:10074
#define glUniform4fv
Definition: glad.h:2555
GLdouble s
Definition: glad.h:8448
#define glCreateProgram
Definition: glad.h:2438
UniformProxy const & operator=(GLint i) const noexcept
Definition: ShaderProgram.h:61
#define glDeleteShader
Definition: glad.h:2447
Shader & operator=(Shader &&rhs) noexcept
Definition: ShaderProgram.h:33
UniformProxy const & operator=(float f) const noexcept
Definition: ShaderProgram.h:54
UniformProxy const & operator=(Eigen::Vector3f const &v) const noexcept
Definition: ShaderProgram.h:82
Definition: ShaderProgram.h:47
GLfloat f
Definition: glad.h:3403
GLsizei GLsizei GLchar * source
Definition: glad.h:2481