... | ... |
@@ -31,6 +31,7 @@ int main() |
31 | 31 |
|
32 | 32 |
// Use. |
33 | 33 |
player |
34 |
+ .use() |
|
34 | 35 |
.validate(); |
35 | 36 |
} |
36 | 37 |
``` |
... | ... |
@@ -116,7 +117,9 @@ OpenGL state to make sure that a subsequent draw call would succeed. An error |
116 | 117 |
is thrown if a problem is detected. |
117 | 118 |
|
118 | 119 |
Additional issues that are not typically detected by [`glValidateProgram`][] |
119 |
-are checked for. |
|
120 |
+are checked for: |
|
121 |
+ |
|
122 |
+- Shader program not [current](#use). |
|
120 | 123 |
|
121 | 124 |
If the macro [`NDEBUG`][] is defined, the check is optimised out. Therefore, it |
122 | 125 |
is recommended to always call `validate()` before issuing draw calls. |
... | ... |
@@ -125,6 +128,16 @@ is recommended to always call `validate()` before issuing draw calls. |
125 | 128 |
[`glValidateProgram`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glValidateProgram.xhtml |
126 | 129 |
[`NDEBUG`]: https://en.cppreference.com/w/c/error/assert |
127 | 130 |
|
131 |
+### Use |
|
132 |
+ |
|
133 |
+The shader needs to be [use][]d by calling `use()` before performing certain |
|
134 |
+other actions on it. |
|
135 |
+ |
|
136 |
+If the macro [`NDEBUG`][] is not defined, an error is thrown if this is not the |
|
137 |
+case. |
|
138 |
+ |
|
139 |
+[use]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUseProgram.xhtml |
|
140 |
+ |
|
128 | 141 |
## Dependencies |
129 | 142 |
|
130 | 143 |
Public (interface): |
... | ... |
@@ -26,10 +26,14 @@ public: |
26 | 26 |
GLuint program() const; |
27 | 27 |
|
28 | 28 |
Shader & validate(); |
29 |
+ Shader & use(); |
|
29 | 30 |
|
30 | 31 |
protected: |
31 | 32 |
|
32 | 33 |
void validate_() const; |
34 |
+ void current_( |
|
35 |
+ std::string const & error |
|
36 |
+ ) const; |
|
33 | 37 |
|
34 | 38 |
GLuint program_; |
35 | 39 |
std::string program_name_; |
... | ... |
@@ -66,5 +70,11 @@ inline Shader & Shader::validate() |
66 | 70 |
return *this; |
67 | 71 |
} |
68 | 72 |
|
73 |
+inline Shader & Shader::use() |
|
74 |
+{ |
|
75 |
+ glUseProgram(program_); |
|
76 |
+ return *this; |
|
77 |
+} |
|
78 |
+ |
|
69 | 79 |
|
70 | 80 |
#endif // GLSHADER_SHADER_HPP_ |
... | ... |
@@ -229,4 +229,18 @@ void Shader::validate_() const |
229 | 229 |
glValidateProgram, program_, |
230 | 230 |
GL_VALIDATE_STATUS, glGetProgramiv, glGetProgramInfoLog |
231 | 231 |
); |
232 |
+ |
|
233 |
+ // Assert current. |
|
234 |
+ current_(validate_error); |
|
235 |
+} |
|
236 |
+ |
|
237 |
+ |
|
238 |
+void Shader::current_(std::string const & error) const |
|
239 |
+{ |
|
240 |
+ // Error if not current. |
|
241 |
+ if (get_integer_<GLuint>(GL_CURRENT_PROGRAM) != program_) |
|
242 |
+ throw std::runtime_error{STR( |
|
243 |
+ error << "; " << |
|
244 |
+ "shader program not current." |
|
245 |
+ )}; |
|
232 | 246 |
} |
... | ... |
@@ -46,12 +46,20 @@ GLTEST(2, 0, 640, 480, glshader) |
46 | 46 |
"active samplers with a different type refer to the same texture image unit" |
47 | 47 |
) |
48 | 48 |
|
49 |
+ // Use. |
|
50 |
+ GLTEST_EXPECT_EXCEPTION(false, |
|
51 |
+ Shader({"tests/use.vert"}).validate(), |
|
52 |
+ "Failed to validate shader program 'tests/use.vert'; " |
|
53 |
+ "shader program not current." |
|
54 |
+ ) |
|
55 |
+ |
|
49 | 56 |
auto all = Shader({ |
50 | 57 |
"tests/all.vert", |
51 | 58 |
"tests/all.frag", |
52 | 59 |
}); |
53 | 60 |
|
54 | 61 |
all |
62 |
+ .use() |
|
55 | 63 |
.validate(); |
56 | 64 |
|
57 | 65 |
constexpr auto size = 0.5F; |