galaxy 1.0.0
Real-Time C++23 Game Programming Framework. Built on data-driven design principles and agile software engineering.
Loading...
Searching...
No Matches
Shader.hpp
Go to the documentation of this file.
1
7
8#ifndef GALAXY_GRAPHICS_GL_SHADER_HPP_
9#define GALAXY_GRAPHICS_GL_SHADER_HPP_
10
11#include <ankerl/unordered_dense.h>
12#include <entt/core/compressed_pair.hpp>
13#include <glad/glad.h>
14#include <glm/gtc/type_ptr.hpp>
15
18#include "galaxy/math/Math.hpp"
19
20namespace galaxy
21{
27 class Shader final
28 {
29 public:
33 Shader() noexcept;
34
38 Shader(Shader&&) noexcept;
39
43 Shader& operator=(Shader&&) noexcept;
44
48 ~Shader() noexcept;
49
57 [[nodiscard]]
58 bool load(const std::string& file) noexcept;
59
68 [[nodiscard]]
69 bool load(const std::string& vertex, const std::string& frag) noexcept;
70
78 [[nodiscard]]
79 bool parse(const std::string& src) noexcept;
80
89 [[nodiscard]]
90 bool parse(const std::string& vertex, const std::string& frag) noexcept;
91
95 void compile();
96
100 void destroy();
101
105 void bind() const;
106
110 void unbind() const;
111
121 template<typename... Uniforms>
122 void set_uniform(const std::string& name, const Uniforms&... args);
123
129 [[nodiscard]]
130 unsigned int id() const noexcept;
131
132 private:
136 Shader(const Shader&) = delete;
137
141 Shader& operator=(const Shader&) = delete;
142
150 [[nodiscard]]
151 bool preprocess(const std::string& src) noexcept;
152
160 [[nodiscard]]
161 int get_uniform_location(const std::string& name);
162
163 private:
167 unsigned int m_id;
168
172 ankerl::unordered_dense::map<std::string, int> m_cache;
173
177 entt::compressed_pair<std::string, std::string> m_src;
178 };
179
180 template<>
181 inline void Shader::set_uniform(const std::string& name)
182 {
183 GALAXY_LOG(GALAXY_ERROR, "Tried to set uniform without value: '{0}'.", name);
184 }
185
186 template<>
187 inline void Shader::set_uniform<bool>(const std::string& name, const bool& a)
188 {
189 glProgramUniform1i(m_id, get_uniform_location(name), a);
190 }
191
192 template<>
193 inline void Shader::set_uniform<int>(const std::string& name, const int& a)
194 {
195 glProgramUniform1i(m_id, get_uniform_location(name), a);
196 }
197
198 template<>
199 inline void Shader::set_uniform<int, int>(const std::string& name, const int& a, const int& b)
200 {
201 glProgramUniform2i(m_id, get_uniform_location(name), a, b);
202 }
203
204 template<>
205 inline void Shader::set_uniform<int, int, int>(const std::string& name, const int& a, const int& b, const int& c)
206 {
207 glProgramUniform3i(m_id, get_uniform_location(name), a, b, c);
208 }
209
210 template<>
211 inline void Shader::set_uniform<int, int, int, int>(const std::string& name, const int& a, const int& b, const int& c, const int& d)
212 {
213 glProgramUniform4i(m_id, get_uniform_location(name), a, b, c, d);
214 }
215
216 template<>
217 inline void Shader::set_uniform<unsigned int>(const std::string& name, const unsigned int& a)
218 {
219 glProgramUniform1ui(m_id, get_uniform_location(name), a);
220 }
221
222 template<>
223 inline void Shader::set_uniform<unsigned int, unsigned int>(const std::string& name, const unsigned int& a, const unsigned int& b)
224 {
225 glProgramUniform2ui(m_id, get_uniform_location(name), a, b);
226 }
227
228 template<>
229 inline void Shader::set_uniform<unsigned int, unsigned int, unsigned int>(const std::string& name, const unsigned int& a, const unsigned int& b, const unsigned int& c)
230 {
231 glProgramUniform3ui(m_id, get_uniform_location(name), a, b, c);
232 }
233
234 template<>
236 const std::string& name,
237 const unsigned int& a,
238 const unsigned int& b,
239 const unsigned int& c,
240 const unsigned int& d
241 )
242 {
243 glProgramUniform4ui(m_id, get_uniform_location(name), a, b, c, d);
244 }
245
246 template<>
247 inline void Shader::set_uniform<float>(const std::string& name, const float& a)
248 {
249 glProgramUniform1f(m_id, get_uniform_location(name), a);
250 }
251
252 template<>
253 inline void Shader::set_uniform<float, float>(const std::string& name, const float& a, const float& b)
254 {
255 glProgramUniform2f(m_id, get_uniform_location(name), a, b);
256 }
257
258 template<>
259 inline void Shader::set_uniform<float, float, float>(const std::string& name, const float& a, const float& b, const float& c)
260 {
261 glProgramUniform3f(m_id, get_uniform_location(name), a, b, c);
262 }
263
264 template<>
265 inline void Shader::set_uniform<float, float, float, float>(const std::string& name, const float& a, const float& b, const float& c, const float& d)
266 {
267 glProgramUniform4f(m_id, get_uniform_location(name), a, b, c, d);
268 }
269
270 template<>
271 inline void Shader::set_uniform<double>(const std::string& name, const double& a)
272 {
273 glProgramUniform1d(m_id, get_uniform_location(name), a);
274 }
275
276 template<>
277 inline void Shader::set_uniform<double, double>(const std::string& name, const double& a, const double& b)
278 {
279 glProgramUniform2d(m_id, get_uniform_location(name), a, b);
280 }
281
282 template<>
283 inline void Shader::set_uniform<double, double, double>(const std::string& name, const double& a, const double& b, const double& c)
284 {
285 glProgramUniform3d(m_id, get_uniform_location(name), a, b, c);
286 }
287
288 template<>
289 inline void Shader::set_uniform<double, double, double, double>(const std::string& name, const double& a, const double& b, const double& c, const double& d)
290 {
291 glProgramUniform4d(m_id, get_uniform_location(name), a, b, c, d);
292 }
293
294 template<>
295 inline void Shader::set_uniform<std::uint64_t>(const std::string& name, const std::uint64_t& a)
296 {
297 glProgramUniform1ui64ARB(m_id, get_uniform_location(name), a);
298 }
299
300 template<>
301 inline void Shader::set_uniform<glm::mat3>(const std::string& name, const glm::mat3& a)
302 {
303 glProgramUniformMatrix3fv(m_id, get_uniform_location(name), 1, GL_FALSE, glm::value_ptr(a));
304 }
305
306 template<>
307 inline void Shader::set_uniform<glm::mat4>(const std::string& name, const glm::mat4& a)
308 {
309 glProgramUniformMatrix4fv(m_id, get_uniform_location(name), 1, GL_FALSE, glm::value_ptr(a));
310 }
311
312 template<>
313 inline void Shader::set_uniform<glm::vec2>(const std::string& name, const glm::vec2& a)
314 {
315 glProgramUniform2f(m_id, get_uniform_location(name), a.x, a.y);
316 }
317
318 template<>
319 inline void Shader::set_uniform<glm::vec3>(const std::string& name, const glm::vec3& a)
320 {
321 glProgramUniform3f(m_id, get_uniform_location(name), a.x, a.y, a.z);
322 }
323
324 template<>
325 inline void Shader::set_uniform<glm::vec4>(const std::string& name, const glm::vec4& a)
326 {
327 glProgramUniform4f(m_id, get_uniform_location(name), a.x, a.y, a.z, a.w);
328 }
329
330 template<>
331 inline void Shader::set_uniform<std::array<float, 4>>(const std::string& name, const std::array<float, 4>& a)
332 {
333 glProgramUniform4f(m_id, get_uniform_location(name), a[0], a[1], a[2], a[3]);
334 }
335
336 template<>
337 inline void Shader::set_uniform<Colour>(const std::string& name, const Colour& a)
338 {
339 auto vec4 = glm::vec4();
340
341 vec4.x = std::clamp(math::normalize(a.r(), Colour::OFFSET), 0.0f, 1.0f);
342 vec4.y = std::clamp(math::normalize(a.g(), Colour::OFFSET), 0.0f, 1.0f);
343 vec4.z = std::clamp(math::normalize(a.b(), Colour::OFFSET), 0.0f, 1.0f);
344 vec4.w = std::clamp(math::normalize(a.a(), Colour::OFFSET), 0.0f, 1.0f);
345
346 set_uniform(name, vec4);
347 }
348} // namespace galaxy
349
350#endif
#define GALAXY_LOG(level, msg,...)
Definition Log.hpp:28
#define GALAXY_ERROR
Definition Log.hpp:24
Represents an RGBA colour.
Definition Colour.hpp:24
void g(const std::uint8_t g) noexcept
Green.
Definition Colour.cpp:83
void a(const std::uint8_t a) noexcept
Alpha.
Definition Colour.cpp:93
void r(const std::uint8_t r) noexcept
Red.
Definition Colour.cpp:78
void b(const std::uint8_t b) noexcept
Blue.
Definition Colour.cpp:88
static const constexpr std::uint8_t OFFSET
Colour offsets for normalization.
Definition Colour.hpp:39
OpenGL Shader Program.
Definition Shader.hpp:28
entt::compressed_pair< std::string, std::string > m_src
Shader source code.
Definition Shader.hpp:177
Shader() noexcept
Constructor.
Definition Shader.cpp:22
ankerl::unordered_dense::map< std::string, int > m_cache
Cache of uniforms for better performance.
Definition Shader.hpp:172
unsigned int id() const noexcept
Get program id.
Definition Shader.cpp:221
int get_uniform_location(const std::string &name)
Retrieves the location of a shader uniform.
Definition Shader.cpp:273
~Shader() noexcept
Destructor.
Definition Shader.cpp:60
void compile()
Compiles shader into GPU mem.
Definition Shader.cpp:113
void unbind() const
Unbind.
Definition Shader.cpp:216
Shader & operator=(Shader &&) noexcept
Move assignment operator.
Definition Shader.cpp:41
void set_uniform(const std::string &name, const Uniforms &... args)
Specialized variadic template for setting shader uniforms.
bool preprocess(const std::string &src) noexcept
Extract source code from a combined shader.
Definition Shader.cpp:226
bool parse(const std::string &src) noexcept
Loads a combined raw shader.
Definition Shader.cpp:83
bool load(const std::string &file) noexcept
Loads a combined shader.
Definition Shader.cpp:65
void bind() const
Make active shader.
Definition Shader.cpp:211
void destroy()
Destroys shader program.
Definition Shader.cpp:202
unsigned int m_id
OpenGL handle.
Definition Shader.hpp:167
float constexpr normalize(const Arithmetic val, const Arithmetic max) noexcept
Calc normalized value from range.
Definition Math.hpp:29
Animated.cpp galaxy.
Definition Animated.cpp:16
STL namespace.