Browse code

Add texture

Robert Cranston authored on 01/07/2021 00:25:58
Showing 1 changed files
... ...
@@ -39,6 +39,8 @@ int main()
39 39
         std::array<float, 4> value1;
40 40
         std::array<float, 4> value2;
41 41
     } values = {};
42
+    auto texture0 = GLuint{};
43
+    glGenTextures(1, &texture0);
42 44
 
43 45
     // Global settings.
44 46
     Shader::root("assets/shaders");
... ...
@@ -65,6 +67,7 @@ int main()
65 67
         .uniform("light_count", light_count)
66 68
         .uniform("color", color)
67 69
         .uniform("values", values)
70
+        .texture("texture0", texture0, GL_TEXTURE_2D)
68 71
         .validate();
69 72
     Shader::uniform_buffer("values", values);
70 73
 }
... ...
@@ -319,6 +322,26 @@ Bare arrays are not supported, wrap them in uniform blocks.
319 322
 [memory layout]: https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Memory_layout
320 323
 [avoid `vec3`/`mat3`]: https://stackoverflow.com/questions/38172696/should-i-ever-use-a-vec3-inside-of-a-uniform-buffer-or-shader-storage-buffer-object
321 324
 
325
+#### Textures
326
+
327
+As a special case, uniform texture samplers can be set by calling
328
+`texture(std::string const & name, GLuint texture, GLenum target, bool required
329
+= true)`. Unless a texture unit is already correctly set up as a result of a
330
+previous call, one is automatically allocated and its `target` bound to
331
+`texture`. If a texture unit needs to be allocated but no unused one is
332
+available (the limit can be queried with
333
+[`glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, ...)`][glGet] the least
334
+recently used one is reused. [`uniform`](#uniforms) is then called with the
335
+given `name` (and `required`) and the allocated texture unit as the `value`.
336
+
337
+Subsequent calls with a given `texture` are very cheap provided that the number
338
+of other textures set since the previous call stay below the limit.
339
+
340
+If a subsequent call for a given `texture` uses a different `target` an error
341
+is thrown.
342
+
343
+[glGet]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGet.xhtml
344
+
322 345
 ## Dependencies
323 346
 
324 347
 Public (interface):
Browse code

Add uniform block / buffer

Robert Cranston authored on 17/05/2020 15:29:35
Showing 1 changed files
... ...
@@ -13,6 +13,8 @@ A [C++11][] [OpenGL][] \>=[2.0][] [shader][] library.
13 13
 Overview of usage:
14 14
 
15 15
 ```cpp
16
+#include <array>
17
+
16 18
 #include <GL/glew.h>
17 19
 #include <glm/glm.hpp>
18 20
 
... ...
@@ -32,6 +34,11 @@ int main()
32 34
     // Local data.
33 35
     auto light_count = 3;
34 36
     auto color = glm::vec4{1, 0, 0, 1};
37
+    struct
38
+    {
39
+        std::array<float, 4> value1;
40
+        std::array<float, 4> value2;
41
+    } values = {};
35 42
 
36 43
     // Global settings.
37 44
     Shader::root("assets/shaders");
... ...
@@ -57,7 +64,9 @@ int main()
57 64
         .use()
58 65
         .uniform("light_count", light_count)
59 66
         .uniform("color", color)
67
+        .uniform("values", values)
60 68
         .validate();
69
+    Shader::uniform_buffer("values", values);
61 70
 }
62 71
 ```
63 72
 
... ...
@@ -294,6 +303,22 @@ the supplied variables `TYPE const & value` and `GLint const & location`,
294 303
 probably as parameters to `glUniform*`. `GLSHADER_UNIFORM_DELETE(TYPE)` can be
295 304
 used to [`delete`][] the specialization for a given type.
296 305
 
306
+#### Uniform blocks / buffers
307
+
308
+If no specialization is provided, [uniform block][]s are assumed. This requires
309
+OpenGL \>=3.1 or the [`ARB_uniform_buffer_object`][] extension, an error is
310
+thrown if it is not available. Shared, by name, [Uniform Buffer Object
311
+(UBO)][]s are automatically allocated. Beware of alignment, it is recommended
312
+to use the `std140` [memory layout][] and to [avoid `vec3`/`mat3`][].
313
+
314
+Bare arrays are not supported, wrap them in uniform blocks.
315
+
316
+[Uniform block]: https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Uniform_blocks
317
+[`ARB_uniform_buffer_object`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_uniform_buffer_object.txt
318
+[Uniform Buffer Object (UBO)]: https://www.khronos.org/opengl/wiki/Uniform_Buffer_Object
319
+[memory layout]: https://www.khronos.org/opengl/wiki/Interface_Block_(GLSL)#Memory_layout
320
+[avoid `vec3`/`mat3`]: https://stackoverflow.com/questions/38172696/should-i-ever-use-a-vec3-inside-of-a-uniform-buffer-or-shader-storage-buffer-object
321
+
297 322
 ## Dependencies
298 323
 
299 324
 Public (interface):
Browse code

Add uniform GLM

Robert Cranston authored on 16/05/2020 10:39:49
Showing 1 changed files
... ...
@@ -14,8 +14,10 @@ Overview of usage:
14 14
 
15 15
 ```cpp
16 16
 #include <GL/glew.h>
17
+#include <glm/glm.hpp>
17 18
 
18 19
 #include <glshader.hpp>
20
+#include <glshader_glm.hpp>
19 21
 
20 22
 
21 23
 // Global data.
... ...
@@ -29,6 +31,7 @@ int main()
29 31
 {
30 32
     // Local data.
31 33
     auto light_count = 3;
34
+    auto color = glm::vec4{1, 0, 0, 1};
32 35
 
33 36
     // Global settings.
34 37
     Shader::root("assets/shaders");
... ...
@@ -53,6 +56,7 @@ int main()
53 56
     player
54 57
         .use()
55 58
         .uniform("light_count", light_count)
59
+        .uniform("color", color)
56 60
         .validate();
57 61
 }
58 62
 ```
... ...
@@ -271,6 +275,15 @@ literals) or use an explicit cast to get the `GLfloat` specialization.
271 275
 
272 276
 [`delete`]: https://en.cppreference.com/w/cpp/language/function#Deleted_functions
273 277
 
278
+#### OpenGL Mathematics (GLM)
279
+
280
+[OpenGL Mathematics (GLM)][] specializations are provided in the include file
281
+`glshader_glm.hpp`. OpenGL Mathematics (GLM) uses [OpenGL Shading Language
282
+(GLSL)][] naming conventions.
283
+
284
+[OpenGL Mathematics (GLM)]: https://glm.g-truc.net
285
+[OpenGL Shading Language (GLSL)]: https://www.khronos.org/opengl/wiki/OpenGL_Shading_Language
286
+
274 287
 #### User-defined uniforms
275 288
 
276 289
 Support for e.g. third party mathematics libraries can be added by providing
... ...
@@ -287,6 +300,7 @@ Public (interface):
287 300
 
288 301
 -   [OpenGL][], system (e.g. [`libgl1-mesa-dev`][]).
289 302
 -   [OpenGL Extension Wrangler (GLEW)][], system (e.g. [`libglew-dev`][]).
303
+-   [OpenGL Mathematics (GLM)][], **optional**, system (e.g. [`libglm-dev`][]).
290 304
 
291 305
 Private (build):
292 306
 
... ...
@@ -295,12 +309,15 @@ Private (build):
295 309
 Private (tests):
296 310
 
297 311
 -   [GLFW][], system (e.g. [`libglfw3-dev`][]).
312
+-   [OpenGL Mathematics (GLM)][], system (e.g. [`libglm-dev`][]).
298 313
 -   [`gltest`][], downloaded as part of the CMake configure step.
299 314
 
300 315
 [OpenGL Extension Wrangler (GLEW)]: http://glew.sourceforge.net
316
+[OpenGL Mathematics (GLM)]: https://glm.g-truc.net
301 317
 [GLFW]: https://www.glfw.org
302 318
 [`libgl1-mesa-dev`]: https://packages.debian.org/search?keywords=libgl1-mesa-dev
303 319
 [`libglew-dev`]: https://packages.debian.org/search?keywords=libglew-dev
320
+[`libglm-dev`]: https://packages.debian.org/search?keywords=libglm-dev
304 321
 [`libglfw3-dev`]: https://packages.debian.org/search?keywords=libglfw3-dev
305 322
 [`str`]: https://git.rcrnstn.net/rcrnstn/str
306 323
 [`gltest`]: https://git.rcrnstn.net/rcrnstn/gltest
Browse code

Add uniform scalars

Robert Cranston authored on 21/05/2021 00:46:44
Showing 1 changed files
... ...
@@ -27,6 +27,9 @@ constexpr auto frag_color = 0;
27 27
 
28 28
 int main()
29 29
 {
30
+    // Local data.
31
+    auto light_count = 3;
32
+
30 33
     // Global settings.
31 34
     Shader::root("assets/shaders");
32 35
     Shader::defines({
... ...
@@ -49,6 +52,7 @@ int main()
49 52
     // Use.
50 53
     player
51 54
         .use()
55
+        .uniform("light_count", light_count)
52 56
         .validate();
53 57
 }
54 58
 ```
... ...
@@ -257,6 +261,16 @@ value is of the wrong type. [`use`](#use) must be called before calling
257 261
 
258 262
 [uniform]: https://www.khronos.org/opengl/wiki/Uniform
259 263
 
264
+#### Scalar uniforms
265
+
266
+Template specializations are provided for all `GL*` types corresponding to a
267
+`glUniform1*` variant. As special cases, `GLboolean` and `bool` map to the `i`
268
+(`GLint`) variant. The `GLdouble` specialization is [`delete`][]d to avoid
269
+accidental conversions, change the type (with an `f`/`F` suffix in case of
270
+literals) or use an explicit cast to get the `GLfloat` specialization.
271
+
272
+[`delete`]: https://en.cppreference.com/w/cpp/language/function#Deleted_functions
273
+
260 274
 #### User-defined uniforms
261 275
 
262 276
 Support for e.g. third party mathematics libraries can be added by providing
... ...
@@ -267,8 +281,6 @@ the supplied variables `TYPE const & value` and `GLint const & location`,
267 281
 probably as parameters to `glUniform*`. `GLSHADER_UNIFORM_DELETE(TYPE)` can be
268 282
 used to [`delete`][] the specialization for a given type.
269 283
 
270
-[`delete`]: https://en.cppreference.com/w/cpp/language/function#Deleted_functions
271
-
272 284
 ## Dependencies
273 285
 
274 286
 Public (interface):
Browse code

Add uniform

Robert Cranston authored on 21/05/2021 00:46:36
Showing 1 changed files
... ...
@@ -137,6 +137,9 @@ Additional issues that are not typically detected by [`glValidateProgram`][]
137 137
 are checked for:
138 138
 
139 139
 -   Shader program not [current](#use).
140
+-   Uniforms not set with a call to [`uniform`](#uniforms), uniform blocks not
141
+    set with a call to `uniform` or `uniform_buffer`. (OpenGL defaults them to
142
+    zero unless initialized in the shader.)
140 143
 
141 144
 If the macro [`NDEBUG`][] is defined, the check is optimised out. Therefore, it
142 145
 is recommended to always call `validate()` before issuing draw calls.
... ...
@@ -148,7 +151,7 @@ is recommended to always call `validate()` before issuing draw calls.
148 151
 ### Use
149 152
 
150 153
 The shader needs to be [use][]d by calling `use()` before performing certain
151
-other actions on it.
154
+other actions on it, such as calling [`uniform`](#uniforms).
152 155
 
153 156
 If the macro [`NDEBUG`][] is not defined, an error is thrown if this is not the
154 157
 case.
... ...
@@ -243,6 +246,29 @@ up once at application startup.
243 246
 [`glDrawBuffers`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawBuffers.xhtml
244 247
 [program interface query]: https://www.khronos.org/opengl/wiki/Program_Introspection#Interface_query
245 248
 
249
+### Uniforms
250
+
251
+[Uniform][]s are set with the template specialized `uniform(std::string const &
252
+name, T const & value, bool required = true)`. If `required` is `true` an error
253
+is thrown if the shader does not contain an active uniform with the given
254
+`name`. If the macro [`NDEBUG`][] is not defined an error is thrown if the
255
+value is of the wrong type. [`use`](#use) must be called before calling
256
+`uniform`.
257
+
258
+[uniform]: https://www.khronos.org/opengl/wiki/Uniform
259
+
260
+#### User-defined uniforms
261
+
262
+Support for e.g. third party mathematics libraries can be added by providing
263
+the relevant template specializations of `uniform`. The macro
264
+`GLSHADER_UNIFORM(TYPE, CODE)` may be used to ease this task. `TYPE` is the
265
+type for which to provide the specialization and `CODE` is code that may use
266
+the supplied variables `TYPE const & value` and `GLint const & location`,
267
+probably as parameters to `glUniform*`. `GLSHADER_UNIFORM_DELETE(TYPE)` can be
268
+used to [`delete`][] the specialization for a given type.
269
+
270
+[`delete`]: https://en.cppreference.com/w/cpp/language/function#Deleted_functions
271
+
246 272
 ## Dependencies
247 273
 
248 274
 Public (interface):
Browse code

Add input and output

Robert Cranston authored on 11/05/2021 12:27:29
Showing 1 changed files
... ...
@@ -20,6 +20,9 @@ Overview of usage:
20 20
 
21 21
 // Global data.
22 22
 constexpr auto light_count_max = 32;
23
+constexpr auto vert_position  = 0;
24
+constexpr auto vert_tex_coord = 1;
25
+constexpr auto frag_color = 0;
23 26
 
24 27
 
25 28
 int main()
... ...
@@ -29,6 +32,13 @@ int main()
29 32
     Shader::defines({
30 33
         {"light_count_max", std::to_string(light_count_max)},
31 34
     });
35
+    Shader::verts({
36
+        {"vert_position",  vert_position},
37
+        {"vert_tex_coord", vert_tex_coord},
38
+    });
39
+    Shader::frags({
40
+        {"frag_color", frag_color},
41
+    });
32 42
 
33 43
     // Create.
34 44
     auto player = Shader({
... ...
@@ -202,6 +212,37 @@ been seen before.
202 212
 [`glNamedStringARB`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_shading_language_include.txt
203 213
 [`glCompileShaderIncludeARB`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_shading_language_include.txt
204 214
 
215
+### User-defined vertex inputs (attributes) and fragment outputs (data)
216
+
217
+Locations for user-defined [vertex inputs][] (attributes) and [fragment
218
+outputs][] (data, requires OpenGL >= 3.0) can be specified by calling
219
+`Shader::verts(Shader::Locations const & verts)` and
220
+`Shader::frags(Shader::Locations const & frags)` respectively before
221
+instantiating a `Shader` that uses them. `Shader::Locations` is an alias for
222
+`std::map<std::string, GLuint>`. Any `location` [layout qualifier][] overrides
223
+the values specified this way. Note that a `Shader` object retains the input
224
+and output locations that were in effect when it was instantiated. See
225
+[`glBindAttribLocation`][] and [`glBindFragDataLocation`][]. Note that fragment
226
+outputs are subject to [`glDrawBuffer`][] / [`glDrawBuffers`][].
227
+
228
+An error is thrown if a shader uses a non-specified input. No error is thrown
229
+for non-specified outputs (this is mostly a result of the inability to
230
+enumerate shader outputs before the introduction of the [program interface
231
+query][]). Shaders need not use all of the specified inputs/outputs.
232
+
233
+The intent is for the application to define global unchanging input/output
234
+locations that are used by all shaders, geometry and framebuffers and set them
235
+up once at application startup.
236
+
237
+[vertex inputs]: https://www.khronos.org/opengl/wiki/Vertex_Shader#Inputs
238
+[fragment outputs]: https://www.khronos.org/opengl/wiki/Fragment_Shader#Outputs
239
+[layout qualifier]: https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL)
240
+[`glBindAttribLocation`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindAttribLocation.xhtml
241
+[`glBindFragDataLocation`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glBindFragDataLocation.xhtml
242
+[`glDrawBuffer`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawBuffer.xhtml
243
+[`glDrawBuffers`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawBuffers.xhtml
244
+[program interface query]: https://www.khronos.org/opengl/wiki/Program_Introspection#Interface_query
245
+
205 246
 ## Dependencies
206 247
 
207 248
 Public (interface):
Browse code

Add preprocessing include

Robert Cranston authored on 26/02/2021 16:36:35
Showing 1 changed files
... ...
@@ -169,6 +169,39 @@ defines)` are injected after the `#version`. `Shader::Defines` is an alias for
169 169
 
170 170
 [`#define`]: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Preprocessor_directives
171 171
 
172
+#### `#include`s
173
+
174
+Support for [`#include`][]s is provided, with the same syntax as the
175
+[`ARB_shading_language_include`][] extension. An `#include`d path must be
176
+surrounded by `<` `>`, in which case it is treated as relative to
177
+[`root`](#loading-files), or by `"` `"`, in which case it is treated as
178
+relative to the including file.
179
+
180
+Even though the extension is not used for including files, an `#extension
181
+GL_ARB_shading_language_include : require` line is required for portability,
182
+otherwise an error is thrown. The line is silently dropped before the source is
183
+fed to OpenGL so as to not upset the shader compiler if the extension is not
184
+available.
185
+
186
+If the [`ARB_shading_language_include`][] extension is available, `#line`
187
+statements that include the file path are injected before every line (after the
188
+`#version`) to improve error messages from the shader compiler.
189
+
190
+Note that the `#include` statements are expanded before the source is fed to
191
+OpenGL, and therefore before the [GLSL preprocessor][] is run which means
192
+things like [include guard][]s do not work. (For portability, it is recommended
193
+that include guards be used anyway.) Circular includes are broken by skipping
194
+`#include`s where the *including file, line number, included file* tuple has
195
+been seen before.
196
+
197
+[`#include`]: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Preprocessor_directives
198
+[`glCompileShader`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glCompileShader.xhtml
199
+[GLSL preprocessor]: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Preprocessor_directives
200
+[include guard]: https://en.wikipedia.org/wiki/Include_guard
201
+[`ARB_shading_language_include`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_shading_language_include.txt
202
+[`glNamedStringARB`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_shading_language_include.txt
203
+[`glCompileShaderIncludeARB`]: https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_shading_language_include.txt
204
+
172 205
 ## Dependencies
173 206
 
174 207
 Public (interface):
Browse code

Add preprocessing defines

Robert Cranston authored on 26/02/2021 23:38:21
Showing 1 changed files
... ...
@@ -18,10 +18,17 @@ Overview of usage:
18 18
 #include <glshader.hpp>
19 19
 
20 20
 
21
+// Global data.
22
+constexpr auto light_count_max = 32;
23
+
24
+
21 25
 int main()
22 26
 {
23 27
     // Global settings.
24 28
     Shader::root("assets/shaders");
29
+    Shader::defines({
30
+        {"light_count_max", std::to_string(light_count_max)},
31
+    });
25 32
 
26 33
     // Create.
27 34
     auto player = Shader({
... ...
@@ -154,6 +161,14 @@ is to use `#version 110` if none is provided.)
154 161
 
155 162
 [`#version`]: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Version
156 163
 
164
+#### `#define`s
165
+
166
+[`#define`][]s specified with `Shader::defines(Shader::Defines const &
167
+defines)` are injected after the `#version`. `Shader::Defines` is an alias for
168
+`std::map<std::string, std::string>`.
169
+
170
+[`#define`]: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Preprocessor_directives
171
+
157 172
 ## Dependencies
158 173
 
159 174
 Public (interface):
Browse code

Add preprocessing version

Robert Cranston authored on 26/02/2021 16:06:29
Showing 1 changed files
... ...
@@ -138,6 +138,22 @@ case.
138 138
 
139 139
 [use]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glUseProgram.xhtml
140 140
 
141
+### Preprocessing
142
+
143
+A simple preprocessor is run before shader sources are passed to OpenGL.
144
+
145
+At present the preprocessor does not interpret line continuations or multi-line
146
+comments correctly on lines it acts upon. Other lines are left alone so they
147
+can be used there without issue.
148
+
149
+#### `#version`
150
+
151
+Each supplied shader file is checked for the existence of one, and only one,
152
+[`#version`][]. An error is thrown if this is not the case. (The OpenGL default
153
+is to use `#version 110` if none is provided.)
154
+
155
+[`#version`]: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)#Version
156
+
141 157
 ## Dependencies
142 158
 
143 159
 Public (interface):
Browse code

Add use

Robert Cranston authored on 27/02/2021 00:53:41
Showing 1 changed files
... ...
@@ -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):
Browse code

Add validate

Robert Cranston authored on 27/02/2021 00:19:43
Showing 1 changed files
... ...
@@ -28,9 +28,18 @@ int main()
28 28
         "player.vert",
29 29
         "player.frag", "lighting.frag",
30 30
     });
31
+
32
+    // Use.
33
+    player
34
+        .validate();
31 35
 }
32 36
 ```
33 37
 
38
+All public (non-static) member functions return a reference to the current
39
+object, allowing [method chaining][].
40
+
41
+[method chaining]: https://en.wikipedia.org/wiki/Method_chaining
42
+
34 43
 ### Errors
35 44
 
36 45
 Errors are handled by throwing [`std::runtime_error`][] with a [`what()`][]
... ...
@@ -100,6 +109,22 @@ a separating `"/"` if non-empty, to all paths (defaults to `""`).
100 109
 [shader stage]: https://www.khronos.org/opengl/wiki/Shader#Stages
101 110
 [OpenGL / OpenGL ES Reference Compiler]: https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
102 111
 
112
+### Validation
113
+
114
+By calling `validate()` the shader can be [validate][]d against the current
115
+OpenGL state to make sure that a subsequent draw call would succeed. An error
116
+is thrown if a problem is detected.
117
+
118
+Additional issues that are not typically detected by [`glValidateProgram`][]
119
+are checked for.
120
+
121
+If the macro [`NDEBUG`][] is defined, the check is optimised out. Therefore, it
122
+is recommended to always call `validate()` before issuing draw calls.
123
+
124
+[validate]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glValidateProgram.xhtml
125
+[`glValidateProgram`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glValidateProgram.xhtml
126
+[`NDEBUG`]: https://en.cppreference.com/w/c/error/assert
127
+
103 128
 ## Dependencies
104 129
 
105 130
 Public (interface):
Browse code

Add create

Robert Cranston authored on 16/05/2020 11:49:30
Showing 1 changed files
... ...
@@ -8,6 +8,122 @@ A [C++11][] [OpenGL][] \>=[2.0][] [shader][] library.
8 8
 [2.0]: https://en.wikipedia.org/wiki/OpenGL#Version_history
9 9
 [shader]: https://www.khronos.org/opengl/wiki/Shader
10 10
 
11
+## Usage
12
+
13
+Overview of usage:
14
+
15
+```cpp
16
+#include <GL/glew.h>
17
+
18
+#include <glshader.hpp>
19
+
20
+
21
+int main()
22
+{
23
+    // Global settings.
24
+    Shader::root("assets/shaders");
25
+
26
+    // Create.
27
+    auto player = Shader({
28
+        "player.vert",
29
+        "player.frag", "lighting.frag",
30
+    });
31
+}
32
+```
33
+
34
+### Errors
35
+
36
+Errors are handled by throwing [`std::runtime_error`][] with a [`what()`][]
37
+that returns helpful context, including operating system messages and the
38
+OpenGL info log where appropriate.
39
+
40
+If OpenGL \>=4.3 or the extension [`GL_KHR_debug`][] is available,
41
+[`glObjectLabel`][] is used to improve debug messages provided to any callback
42
+registered with [`glDebugMessageCallback`][].
43
+
44
+Se [`tests/glshader.cpp`][] for an overview of some of the handled errors.
45
+(Note that the tests are written for compatibility and convenience and do not
46
+necessarily reflect current best practices.)
47
+
48
+[`std::runtime_error`]: https://en.cppreference.com/w/cpp/error/runtime_error
49
+[`what()`]: https://en.cppreference.com/w/cpp/error/exception/what
50
+[`GL_KHR_debug`]: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_debug.txt
51
+[`glObjectLabel`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glObjectLabel.xhtml
52
+[`glDebugMessageCallback`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDebugMessageCallback.xhtml
53
+[`tests/glshader.cpp`]: tests/glshader.cpp
54
+
55
+### Lifetime
56
+
57
+No default constructor is defined. This, together with a throwing constructor,
58
+means that a (non-moved-from) `Shader` object always corresponds to a valid
59
+OpenGL shader object.
60
+
61
+At destruction, the underlying OpenGL shader program is deleted, but not
62
+explicitly unbound. Note that the behavior of [deletion unbinding][] depends on
63
+the OpenGL version. It is recommended to always consider the underlying OpenGL
64
+shader program to be invalid after destruction.
65
+
66
+Copying (creating a new identical underlying OpenGL shader object) or move
67
+assigning (deleting the underlying OpenGL shader object of the moved-into
68
+`Shader` object) would probably be a (performance) bug and is disabled. I.e.
69
+`Shader` is a move(-constructible)-only type.
70
+
71
+[deletion unbinding]: https://www.khronos.org/opengl/wiki/OpenGL_Object#Deletion_unbinding
72
+
73
+### Loading files
74
+
75
+An arbitrary number of files can be loaded by giving them as arguments to the
76
+`Shader(Shader::Paths const & paths)` constructor.
77
+
78
+`Shader::Paths` is an alias for `std::set<std::string>`. `std::set` is used
79
+over e.g. `std::vector` to facilitate deduplicating shaders based on paths,
80
+even when the paths are given in different orders. `std::set` is used over
81
+`std::unordered_set` to retain the same ordering in error messages as in the
82
+creation for easy identification.
83
+
84
+The [shader stage][] is automatically detected by the file extension using the
85
+same rules as the [OpenGL / OpenGL ES Reference Compiler][]:
86
+
87
+-   `.vert`: vertex
88
+-   `.tesc`: tessellation control
89
+-   `.tese`: tessellation evaluation
90
+-   `.geom`: geometry
91
+-   `.frag`: fragment
92
+-   `.comp`: compute
93
+
94
+If multiple files are provided for the same stage they are compiled separately
95
+and linked into the final shader program.
96
+
97
+The value passed to `Shader::root(std::string const & root)` is prepended, with
98
+a separating `"/"` if non-empty, to all paths (defaults to `""`).
99
+
100
+[shader stage]: https://www.khronos.org/opengl/wiki/Shader#Stages
101
+[OpenGL / OpenGL ES Reference Compiler]: https://www.khronos.org/opengles/sdk/tools/Reference-Compiler/
102
+
103
+## Dependencies
104
+
105
+Public (interface):
106
+
107
+-   [OpenGL][], system (e.g. [`libgl1-mesa-dev`][]).
108
+-   [OpenGL Extension Wrangler (GLEW)][], system (e.g. [`libglew-dev`][]).
109
+
110
+Private (build):
111
+
112
+-   [`str`][], downloaded as part of the CMake configure step.
113
+
114
+Private (tests):
115
+
116
+-   [GLFW][], system (e.g. [`libglfw3-dev`][]).
117
+-   [`gltest`][], downloaded as part of the CMake configure step.
118
+
119
+[OpenGL Extension Wrangler (GLEW)]: http://glew.sourceforge.net
120
+[GLFW]: https://www.glfw.org
121
+[`libgl1-mesa-dev`]: https://packages.debian.org/search?keywords=libgl1-mesa-dev
122
+[`libglew-dev`]: https://packages.debian.org/search?keywords=libglew-dev
123
+[`libglfw3-dev`]: https://packages.debian.org/search?keywords=libglfw3-dev
124
+[`str`]: https://git.rcrnstn.net/rcrnstn/str
125
+[`gltest`]: https://git.rcrnstn.net/rcrnstn/gltest
126
+
11 127
 ## Build system
12 128
 
13 129
 This project supports [CMake][] and uses [`cmake-common`][]. There are several
Browse code

Add project

Robert Cranston authored on 16/05/2020 11:47:34
Showing 1 changed files
... ...
@@ -8,6 +8,95 @@ A [C++11][] [OpenGL][] \>=[2.0][] [shader][] library.
8 8
 [2.0]: https://en.wikipedia.org/wiki/OpenGL#Version_history
9 9
 [shader]: https://www.khronos.org/opengl/wiki/Shader
10 10
 
11
+## Build system
12
+
13
+This project supports [CMake][] and uses [`cmake-common`][]. There are several
14
+ways to use it in other CMake-based projects:
15
+
16
+-   With [`find_package`][]: ([Package][] and) [install][] it on the system.
17
+
18
+-   With [`add_subdirectory`][]: Bundle it.
19
+
20
+-   With [`FetchContent`][]: Download it as part of the CMake configure step.
21
+
22
+-   With [`cmake-common`][]: Use any of the above methods through a simplified
23
+    interface.
24
+
25
+As usual, use [`add_dependencies`][] or [`target_link_libraries`][] (or
26
+`cmake-common`'s `DEPENDENCIES_*`) to declare the dependency.
27
+
28
+[CMake]: https://cmake.org
29
+[`cmake-common`]: https://git.rcrnstn.net/rcrnstn/cmake-common
30
+[`FetchContent`]: https://cmake.org/cmake/help/v3.14/module/FetchContent.html
31
+[`add_subdirectory`]: https://cmake.org/cmake/help/v3.14/command/add_subdirectory.html
32
+[`find_package`]: https://cmake.org/cmake/help/v3.14/command/find_package.html
33
+[Package]: #Package
34
+[Install]: #Install
35
+[`add_dependencies`]: https://cmake.org/cmake/help/v3.14/command/add_dependencies.html
36
+[`target_link_libraries`]: https://cmake.org/cmake/help/v3.14/command/target_link_libraries.html
37
+
38
+### Configure and generate
39
+
40
+To configure and generate a build tree, use `cmake`:
41
+
42
+```sh
43
+cmake -B _build
44
+```
45
+
46
+To set the build type, pass e.g. `-D`[`CMAKE_BUILD_TYPE`][]`=Release`.
47
+
48
+[`cmake`]: https://cmake.org/cmake/help/v3.14/manual/cmake.1.html#generate-a-project-buildsystem
49
+[`CMAKE_BUILD_TYPE`]: https://cmake.org/cmake/help/v3.14/variable/CMAKE_BUILD_TYPE.html
50
+
51
+### Build
52
+
53
+To build, use [`cmake --build`][]:
54
+
55
+```sh
56
+cmake --build _build
57
+```
58
+
59
+To disable building tests, pass `-D`[`BUILD_TESTING`][]`=OFF`.
60
+
61
+[`cmake --build`]: https://cmake.org/cmake/help/v3.14/manual/cmake.1.html#build-a-project
62
+[`BUILD_TESTING`]: https://cmake.org/cmake/help/v3.14/module/CTest.html
63
+
64
+### Test
65
+
66
+To run tests, use [`ctest`][]:
67
+
68
+```sh
69
+(cd _build && ctest)
70
+```
71
+
72
+To show output from failing tests, pass `--output-on-failure`. To show output
73
+from all tests, pass `--verbose`.
74
+
75
+[`ctest`]: https://cmake.org/cmake/help/v3.14/manual/ctest.1.html
76
+
77
+### Package
78
+
79
+To package, use [`cpack`][]:
80
+
81
+```sh
82
+(cd _build && cpack)
83
+```
84
+
85
+[`cpack`]: https://cmake.org/cmake/help/v3.14/manual/cpack.1.html
86
+
87
+### Install
88
+
89
+To install onto the current system, use [`cmake --install`][]:
90
+
91
+```sh
92
+cmake --install _build
93
+```
94
+
95
+To set the prefix, pass e.g. `-D`[`CMAKE_INSTALL_PREFIX`][]`="$HOME/.local"`.
96
+
97
+[`cmake --install`]: https://cmake.org/cmake/help/v3.14/manual/cmake.1.html#install-a-project
98
+[`CMAKE_INSTALL_PREFIX`]: https://cmake.org/cmake/help/v3.14/variable/CMAKE_INSTALL_PREFIX.html
99
+
11 100
 ## License
12 101
 
13 102
 Licensed under the [ISC License][] unless otherwise noted, see the
Browse code

Add license

Robert Cranston authored on 15/05/2020 22:05:11
Showing 1 changed files
... ...
@@ -7,3 +7,11 @@ A [C++11][] [OpenGL][] \>=[2.0][] [shader][] library.
7 7
 [OpenGL]: https://en.wikipedia.org/wiki/OpenGL
8 8
 [2.0]: https://en.wikipedia.org/wiki/OpenGL#Version_history
9 9
 [shader]: https://www.khronos.org/opengl/wiki/Shader
10
+
11
+## License
12
+
13
+Licensed under the [ISC License][] unless otherwise noted, see the
14
+[`LICENSE`][] file.
15
+
16
+[ISC License]: https://choosealicense.com/licenses/isc
17
+[`LICENSE`]: LICENSE
Browse code

Add readme

Robert Cranston authored on 15/05/2020 22:04:11
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,9 @@
1
+# [`glshader`][]
2
+
3
+A [C++11][] [OpenGL][] \>=[2.0][] [shader][] library.
4
+
5
+[`glshader`]: https://git.rcrnstn.net/rcrnstn/glshader
6
+[C++11]: https://en.wikipedia.org/wiki/C++11
7
+[OpenGL]: https://en.wikipedia.org/wiki/OpenGL
8
+[2.0]: https://en.wikipedia.org/wiki/OpenGL#Version_history
9
+[shader]: https://www.khronos.org/opengl/wiki/Shader