Shader.hpp
1// Copyright 2019 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4
5#ifndef SMK_SHADER_HPP
6#define SMK_SHADER_HPP
7
8#include <glm/glm.hpp>
9#include <initializer_list>
10#include <map>
11#include <smk/OpenGL.hpp>
12#include <string>
13#include <vector>
14#include <memory>
15
16namespace smk {
17
18class Shader;
19class ShaderProgram;
20
21/// @brief A Shader is a little program that rest on the GPU. They are run on a
22/// specific section of the graphic pipeline.
23///
24/// This class is movable and copyable (via internal ref-count).
25///
26/// @see https://learnopengl.com/Getting-started/Shaders
27///
28/// This class is independant from SMK.
29///
30/// ## Example:
31///
32/// ~~~cpp
33/// auto vertex_shader = smk::Shader::FromString(R"(
34/// layout(location = 0) in vec2 space_position;
35/// layout(location = 1) in vec2 texture_position;
36/// uniform mat4 projection;
37/// uniform mat4 view;
38/// out vec2 f_texture_position;
39/// void main() {
40/// f_texture_position = texture_position;
41/// gl_Position = projection * view * vec4(space_position, 0.0, 1.0);
42/// }
43/// )", GL_VERTEX_SHADER);
44///
45/// auto fragment_shader = smk::Shader::FromString(R"(
46/// in vec2 f_texture_position;
47/// uniform sampler2D texture_0;
48/// uniform vec4 color;
49/// out vec4 out_color;
50/// void main() {
51/// vec4 color = texture(texture_0, f_texture_position) * color;
52/// vec3 inverted_color = vec3(1.0) - color.rgb;
53/// out_color = vec4(inverted_color, color.a);
54/// }
55/// )", GL_FRAGMENT_SHADER);
56///
57/// auto shader_program = smk::ShaderProgram();
58/// shader_program.AddShader(vertex_shader);
59/// shader_program.AddShader(fragment_shader);
60/// shader_program.Link();
61///
62/// window.SetShaderProgram(shader_program);
63/// ~~~
64//
65/// @see ShaderProgram
66class Shader {
67 public:
68 Shader(); // Invalid shader.
69 static Shader FromFile(const std::string& filename, GLenum type);
70 static Shader FromString(const std::string& content, GLenum type);
71
72 ~Shader();
73
74 // Linking shader is an asynchronous process. Using the shader can causes the
75 // CPU to wait until its completion. If you need to do some work before the
76 // completion, you can use this function and use the Shader only after it
77 // becomes ready.
78 bool IsReady() const;
79
80 // Wait until the Shader to be ready. Return true if it suceeded.
81 bool CompileStatus() const;
82
83 // Provide opengl shader identifiant.
84 GLuint id() const;
85
86 // --- Movable-Copyable (via ref-count) --------------------------------------
87 Shader(Shader&&) noexcept;
88 Shader(const Shader&) noexcept;
89 Shader& operator=(Shader&&) noexcept;
90 Shader& operator=(const Shader&) noexcept;
91 // ---------------------------------------------------------------------------
92
93 private:
94 Shader(const std::vector<char>& content, GLenum type);
95 void Release();
96
97 // opengl program identifier.
98 GLuint id_ = 0;
99
100 // Used to support copy. Nullptr as long as this class is not copied.
101 // Otherwise an integer counting how many instances shares this resource.
102 mutable int* ref_count_ = nullptr;
103};
104
105/// @brief A shader program is a set of shader (for instance vertex shader +
106/// pixel shader) defining the rendering pipeline.
107///
108/// This is a move-only ressource.
109///
110/// This class provide an interface to define the OpenGL uniforms and attributes
111/// using GLM objects.
112///
113/// @see Shader
115 public:
117 void AddShader(const Shader& shader);
118 void Link() const;
119
120 // Linking shader is an asynchronous process. Using the shader can causes the
121 // CPU to wait until its completion. If you need to do some work before the
122 // completion, you can use this function and use the Shader only after it
123 // becomes ready.
124 bool IsReady() const;
125
126 // Wait until the ShaderProgram to be ready. Return true if it suceeded.
127 bool LinkStatus() const;
128
129 // bind the program
130 void Use() const;
131 void Unuse() const;
132
133 // provide the opengl identifiant
134 GLuint id() const;
135
136 // provide attributes informations.
137 GLint Attribute(const std::string& name) const;
138 void SetAttribute(const std::string& name,
139 GLint size,
140 GLsizei stride,
141 GLuint offset,
142 GLboolean normalize,
143 GLenum type) const;
144 void SetAttribute(const std::string& name,
145 GLint size,
146 GLsizei stride,
147 GLuint offset,
148 GLboolean normalize) const;
149 void SetAttribute(const std::string& name,
150 GLint size,
151 GLsizei stride,
152 GLuint offset,
153 GLenum type) const;
154 void SetAttribute(const std::string& name,
155 GLint size,
156 GLsizei stride,
157 GLuint offset) const;
158
159 // provide uniform location
160 GLint Uniform(const std::string& name);
161 GLint operator[](const std::string& name);
162
163 // affect uniform
164 void SetUniform(const std::string& name, float x, float y, float z);
165 void SetUniform(const std::string& name, const glm::vec3& v);
166 void SetUniform(const std::string& name, const glm::vec4& v);
167 void SetUniform(const std::string& name, const glm::mat4& m);
168 void SetUniform(const std::string& name, const glm::mat3& m);
169 void SetUniform(const std::string& name, float val);
170 void SetUniform(const std::string& name, int val);
171
173
174 // --- Movable-Copyable (via ref-count) --------------------------------------
175 ShaderProgram(ShaderProgram&&) noexcept;
177 ShaderProgram& operator=(ShaderProgram&&) noexcept;
178 ShaderProgram& operator=(const ShaderProgram&);
179 // ---------------------------------------------------------------------------
180
181 bool operator==(const ShaderProgram& rhs) const;
182 bool operator!=(const ShaderProgram& rhs) const;
183
184 private:
185 struct Impl;
186 std::shared_ptr<Impl> impl_;
187};
188
189} // namespace smk
190
191#endif // SMK_SHADER_HPP
A shader program is a set of shader (for instance vertex shader + pixel shader) defining the renderin...
Definition: Shader.hpp:114
GLint Attribute(const std::string &name) const
Return the GPU attribute id.
Definition: Shader.cpp:304
void SetAttribute(const std::string &name, GLint size, GLsizei stride, GLuint offset, GLboolean normalize, GLenum type) const
Set an OpenGL attribute properties.
Definition: Shader.cpp:331
ShaderProgram()
The constructor. The ShaderProgram is initially invalid. You need to call AddShader and Link before b...
Definition: Shader.cpp:219
GLint Uniform(const std::string &name)
Return the uniform ID.
Definition: Shader.cpp:278
void SetUniform(const std::string &name, float x, float y, float z)
Assign shader vec3 uniform.
Definition: Shader.cpp:377
void Unuse() const
Unbind the ShaderProgram.
Definition: Shader.cpp:435
void AddShader(const Shader &shader)
Add a Shader to the program list. This must called multiple time for each shader components before ca...
Definition: Shader.cpp:224
GLuint id() const
The GPU id to the ShaderProgram.
Definition: Shader.cpp:441
void Use() const
Bind the ShaderProgram. Future draw will use it. This unbind any previously bound ShaderProgram.
Definition: Shader.cpp:429
void Link() const
Add a Shader to the program list.
Definition: Shader.cpp:236
A Shader is a little program that rest on the GPU. They are run on a specific section of the graphic ...
Definition: Shader.hpp:66
bool CompileStatus() const
Wait until the Shader to be ready.
Definition: Shader.cpp:113
static Shader FromFile(const std::string &filename, GLenum type)
Load a shader from a file.
Definition: Shader.cpp:42
GLuint id() const
The GPU shader id.
Definition: Shader.cpp:74
static Shader FromString(const std::string &content, GLenum type)
Load a shader from a std::string.
Definition: Shader.cpp:60
bool IsReady() const
Check the status of a Shader. Linking shader is an asynchronous process. Using the shader can causes ...
Definition: Shader.cpp:100