... | ... |
@@ -2,12 +2,376 @@ |
2 | 2 |
|
3 | 3 |
A [C++11][]/[OpenGL][] [\>=1.0][] [object][] library. |
4 | 4 |
|
5 |
+The provided `GLObject` class is intended to be the base class of several other |
|
6 |
+classes that encapsulate different types of OpenGL objects. |
|
7 |
+ |
|
5 | 8 |
[`globject`]: https://git.rcrnstn.net/rcrnstn/globject |
6 | 9 |
[C++11]: https://en.wikipedia.org/wiki/C++11 |
7 | 10 |
[OpenGL]: https://en.wikipedia.org/wiki/OpenGL |
8 | 11 |
[\>=1.0]: https://en.wikipedia.org/wiki/OpenGL#Version_history |
9 | 12 |
[object]: https://www.khronos.org/opengl/wiki/OpenGL_Object |
10 | 13 |
|
14 |
+## Usage |
|
15 |
+ |
|
16 |
+### OpenGL loading library |
|
17 |
+ |
|
18 |
+This library can be used with an arbitrary [OpenGL loading library][] by making |
|
19 |
+sure `GLOBJECT_LOADER` is `#define`d to the file to `#include`, e.g. |
|
20 |
+`<glad/glad.h>` (either in the source or through a compiler switch, probably |
|
21 |
+defined in the build system). The default if none is defined is `<GL/glew.h>`. |
|
22 |
+ |
|
23 |
+[OpenGL loading library]: https://www.khronos.org/opengl/wiki/OpenGL_Loading_Library |
|
24 |
+ |
|
25 |
+### [OpenGL Mathematics (GLM)][] |
|
26 |
+ |
|
27 |
+If `glm/glm.hpp` is included (specifically, if `GLM_VERSION` is defined) before |
|
28 |
+inclusion of `globject.hpp` [OpenGL Mathematics (GLM)][] support will be |
|
29 |
+enabled. See [Data][]. |
|
30 |
+ |
|
31 |
+[OpenGL Mathematics (GLM)]: https://glm.g-truc.net |
|
32 |
+[Data]: #data |
|
33 |
+ |
|
34 |
+### Thread safety |
|
35 |
+ |
|
36 |
+"Global" state (usually used to mirrors some OpenGL [context][] internal state |
|
37 |
+for convenience or performance) is declared `thread_local`. This means that |
|
38 |
+multithreading is supported under the assumption that a given OpenGL |
|
39 |
+[context][] and the `GLObject`s created while it is current are only used from |
|
40 |
+a single thread. |
|
41 |
+ |
|
42 |
+This is not a huge limitation since driver vendors recommend to not share |
|
43 |
+OpenGL [context][]s between threads, for performance. |
|
44 |
+ |
|
45 |
+[context]: https://www.khronos.org/opengl/wiki/OpenGL_Context |
|
46 |
+ |
|
47 |
+### Function documentation |
|
48 |
+ |
|
49 |
+For brevity, argument and return types may omit `const &` and functions may |
|
50 |
+omit `const` qualifiers in the remainder of this documentation when it has no |
|
51 |
+implication for the user, other than performance. Consult the source for the |
|
52 |
+exact function signatures. |
|
53 |
+ |
|
54 |
+### `public` interface |
|
55 |
+ |
|
56 |
+#### [Special member functions][] |
|
57 |
+ |
|
58 |
+There is no `public` constructor. It is impossible to directly instantiate |
|
59 |
+`GLObject`s. Instead, use a derived class that encapsulates a specific type of |
|
60 |
+OpenGL object. |
|
61 |
+ |
|
62 |
+There is no defined default constructor. The copy constructor and copy/move |
|
63 |
+assignment operators are `delete`d. This enforces the invariant that a |
|
64 |
+successfully constructed instance (that has not been moved from) always (is the |
|
65 |
+only instance that) corresponds to a valid OpenGL object. |
|
66 |
+ |
|
67 |
+The destructor is `virtual`, so references to instances of (different) derived |
|
68 |
+classes can be held in (the same) containers. |
|
69 |
+ |
|
70 |
+The move constructor's `noexcept` specifier is only honored if `debug` is |
|
71 |
+`false`, see [Debug][]. |
|
72 |
+ |
|
73 |
+[special member functions]: https://en.wikipedia.org/wiki/Special_member_functions |
|
74 |
+[Debug]: #debug |
|
75 |
+ |
|
76 |
+#### Getters and setters |
|
77 |
+ |
|
78 |
+Getters and setters share the same name and use function overloading to |
|
79 |
+disambiguate. Getters (which can be run on `const` objects) take no argument |
|
80 |
+and return the value (by constant reference). Setters take a [forwarding |
|
81 |
+reference][] argument and return the old value (by value, after move). Getters |
|
82 |
+and setters use a "gets"/"sets" shorthand below to indicate they conform to |
|
83 |
+this behaviour. |
|
84 |
+ |
|
85 |
+[forwarding reference]: https://en.cppreference.com/w/cpp/language/reference#Forwarding_references |
|
86 |
+ |
|
87 |
+#### Core |
|
88 |
+ |
|
89 |
+`bool static supported(Version version_min, std::string extension = {})` |
|
90 |
+returns `true` if the current OpenGL context implements the given, or a later, |
|
91 |
+version or the given extension. If no version check is desired, provide `{0, |
|
92 |
+0}`. If no extension check is desired, provide an empty extension string (the |
|
93 |
+default). If no check at all is performed, `false` is returned. This is |
|
94 |
+convenient because extensions are often absorbed into newer versions of the |
|
95 |
+OpenGL specification itself, and some platforms stop reporting support for the |
|
96 |
+extension for those versions, so only checking if the extension is available |
|
97 |
+fails. [History of OpenGL][] has a list of which versions of OpenGL absorbed |
|
98 |
+which extensions. If a non-empty `extension` is provided, it must be on the |
|
99 |
+form returned by [`glGetStringi`][]`(GL_EXTENSIONS, index)`, i.e. it must start |
|
100 |
+with `"GL_"`. Since this library is agnostic to the used [OpenGL loading |
|
101 |
+library][] (which is usually used to perform these kind of checks), the OpenGL |
|
102 |
+API itself is queried. The old method of detecting the OpenGL version and |
|
103 |
+extensions was deprecated in OpenGL 3.0 and removed in OpenGL 3.1. Both methods |
|
104 |
+are dealt with correctly. `Version` is an alias for `std::array<GLint, 2>`. |
|
105 |
+ |
|
106 |
+`GLint static get_integer(GLenum name)` calls [`glGetIntegerv`][] with the |
|
107 |
+given argument and returns the result. |
|
108 |
+ |
|
109 |
+`GLuint object()` gets the underlying OpenGL object. This is guaranteed to be |
|
110 |
+valid, unless the `GLObject` has been moved from, in which case it is `0`. |
|
111 |
+ |
|
112 |
+`operator GLuint()` (implicit conversion operator) returns `object()`. |
|
113 |
+ |
|
114 |
+[History of OpenGL]: https://www.khronos.org/opengl/wiki/History_of_OpenGL |
|
115 |
+[`glGetStringi`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetString.xhtml |
|
116 |
+[`glGetIntegerv`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGet.xhtml |
|
117 |
+ |
|
118 |
+#### Data |
|
119 |
+ |
|
120 |
+`template<typename Data> struct DataTraits` is template specialized on `GL*` |
|
121 |
+(and, if enabled, [OpenGL Mathematics (GLM)][]) types and provides the |
|
122 |
+following `static constexpr` values. |
|
123 |
+ |
|
124 |
+- `char const[] name` |
|
125 |
+- `GLint columns` |
|
126 |
+- `GLint rows` |
|
127 |
+- `GLenum format` |
|
128 |
+- `GLenum type` |
|
129 |
+- `GLenum internal_format` |
|
130 |
+ |
|
131 |
+It also provides the following functions. |
|
132 |
+ |
|
133 |
+- `void static attrib(GLuint index, Data value)` which uploads `value` to the |
|
134 |
+ [non-array attribute][] indicated by `index`. Note that [OpenGL Mathematics |
|
135 |
+ (GLM)][] matrix types, if enabled, occupy several consecutive indices (one |
|
136 |
+ per column), which are all uploaded automatically by this call. |
|
137 |
+ |
|
138 |
+- `void static uniform(GLint location, Data value)` which uploads `value` to |
|
139 |
+ the [uniform][] indicated by `location` of the current [shader][] program. |
|
140 |
+ |
|
141 |
+`GLOBJECT_DATA*` macros to ease the definition of new template specializations |
|
142 |
+of `DataTraits` are defined. Consult the source for the definitions and usage |
|
143 |
+examples. |
|
144 |
+ |
|
145 |
+[non-array attribute]: https://www.khronos.org/opengl/wiki/Vertex_Specification#Non-array_attribute_values |
|
146 |
+[uniform]: https://www.khronos.org/opengl/wiki/Uniform_(GLSL) |
|
147 |
+[shader]: https://www.khronos.org/opengl/wiki/Shader |
|
148 |
+ |
|
149 |
+#### Path |
|
150 |
+ |
|
151 |
+`Path` is an alias for `std::string`. |
|
152 |
+ |
|
153 |
+`Paths` is an alias for `std::vector<Path>`. |
|
154 |
+ |
|
155 |
+#### Debug |
|
156 |
+ |
|
157 |
+`bool static debug()` gets/sets the global `debug` flag. When `true`, |
|
158 |
+potentially costly debug operations are performed as part of other operations. |
|
159 |
+Defaults to `true`. |
|
160 |
+ |
|
161 |
+`DebugCallback static debug_callback()` gets/sets a callback that may be called |
|
162 |
+by `GLObject` and its derived classes when `debug` is `true`. The debug |
|
163 |
+callback can also be called by client code if desired. `DebugCallback` is an |
|
164 |
+alias for `std::function<void (std::string const & message)>`. Defaults to a |
|
165 |
+function which outputs to `std::cerr`, appends a newline and flushes. |
|
166 |
+ |
|
167 |
+`DebugObjects static debug_objects()` gets a list of all `GLObjects` |
|
168 |
+constructed, and not subsequently destructed, during the time `debug` was |
|
169 |
+`true`. `DebugObjects` is an alias for `std::vector<GLObject *>`. |
|
170 |
+ |
|
171 |
+`std::string debug_name()` returns a short representation of the object. |
|
172 |
+ |
|
173 |
+`std::string debug_info()` returns a potentially longer representation of the |
|
174 |
+object. |
|
175 |
+ |
|
176 |
+`std::string static debug_objects_name()` returns a short representation of all |
|
177 |
+objects in `debug_objects`. |
|
178 |
+ |
|
179 |
+`std::string static debug_objects_info()` returns a potentially longer |
|
180 |
+representation of all objects in `debug_objects`. |
|
181 |
+ |
|
182 |
+Code in `GLObject` (and properly behaved derived classes) uses the macro |
|
183 |
+`GLOBJECT_DEBUG_IF(D)` which expands to `if (debug() >= 1)` by default. It can |
|
184 |
+be made to expand to `if (false)` by defining `GLOBJECT_DEBUG 0`, with the |
|
185 |
+result that an optimizing compiler will completely compile out the |
|
186 |
+corresponding debug code. |
|
187 |
+ |
|
188 |
+#### Exceptions |
|
189 |
+ |
|
190 |
+All exceptions thrown are of the type `GLObject::Exception`, which inherits |
|
191 |
+from `std::runtime_error`. |
|
192 |
+ |
|
193 |
+### `protected` interface |
|
194 |
+ |
|
195 |
+#### [Special member functions][] |
|
196 |
+ |
|
197 |
+Derived classes should define a (usually `explicit` non-default) constructor. A |
|
198 |
+`noexcept` move constructor and `virtual` destructor should only be defined if |
|
199 |
+resources (other than `object`, which is handled by `GLObject`) need to be |
|
200 |
+moved/released. Derived classes should not define or `delete` any of the |
|
201 |
+non-defined/`delete`d special member functions detailed in the `public` |
|
202 |
+interface documentation above. |
|
203 |
+ |
|
204 |
+Two helper functions that act as adapters from the interface of the |
|
205 |
+`glCreate*`/`glDelete*` family of functions (used by shader and program |
|
206 |
+objects, termed "unconventional objects" by the OpenGL Wiki) to the interface |
|
207 |
+of the `glGen*s`/`glDelete*s` family of functions are provided. |
|
208 |
+ |
|
209 |
+- `template<GLCreateObject gl_create_object> void static |
|
210 |
+ gl_create_object_(GLsizei n, GLuint * objects)` takes a `glCreate*` |
|
211 |
+ function as template argument, and conforms to the `glGen*s` interface. |
|
212 |
+ `GLCreateObject` is an alias for `GLuint (*)()`. |
|
213 |
+ |
|
214 |
+- `template<GLDeleteObject gl_delete_object> void static |
|
215 |
+ gl_delete_object_(GLsizei n, GLuint * objects)` takes a `glDelete*` |
|
216 |
+ function as template argument, and conforms to the `glDelete*s` interface. |
|
217 |
+ `GLDeleteObject` is an alias for `void (*)(GLuint)`. |
|
218 |
+ |
|
219 |
+`GLObject` has a concept of pseudo-objects. They are classes that wish to make |
|
220 |
+use of the `protected` interface of `GLObject` but does not encapsulate an |
|
221 |
+OpenGL [object][]. |
|
222 |
+ |
|
223 |
+The `GLObject` constructor takes: |
|
224 |
+ |
|
225 |
+- `GLGenObjects gl_gen_objects` which is a function pointer that conforms to |
|
226 |
+ the `glGen*s` interface. Specify `nullptr` for pseudo-objects. |
|
227 |
+ |
|
228 |
+- `GLDeleteObjects gl_delete_objects` which is a function pointer that |
|
229 |
+ conforms to the `glDelete*s` interface. Specify `nullptr` for |
|
230 |
+ pseudo-objects. |
|
231 |
+ |
|
232 |
+- `GLenum object_type` which is one of the following. Specify `0` for |
|
233 |
+ pseudo-objects. |
|
234 |
+ |
|
235 |
+ - `GL_BUFFER` |
|
236 |
+ - `GL_SHADER` |
|
237 |
+ - `GL_PROGRAM` |
|
238 |
+ - `GL_VERTEX_ARRAY` |
|
239 |
+ - `GL_QUERY` |
|
240 |
+ - `GL_PROGRAM_PIPELINE` |
|
241 |
+ - `GL_TRANSFORM_FEEDBACK` |
|
242 |
+ - `GL_SAMPLER` |
|
243 |
+ - `GL_TEXTURE` |
|
244 |
+ - `GL_RENDERBUFFER` |
|
245 |
+ - `GL_FRAMEBUFFER` |
|
246 |
+ |
|
247 |
+- `std::string object_label` which will be used when throwing exceptions and, |
|
248 |
+ if OpenGL [\>=4.3][] or the [`KHR_debug`][] extension is available, passed |
|
249 |
+ to [`glObjectLabel`][]. |
|
250 |
+ |
|
251 |
+[\>=4.3]: https://en.wikipedia.org/wiki/OpenGL#Version_history |
|
252 |
+[`KHR_debug`]: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_debug.txt |
|
253 |
+[`glObjectLabel`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glObjectLabel.xhtml |
|
254 |
+ |
|
255 |
+#### Getters and setters |
|
256 |
+ |
|
257 |
+Macros that aid in the implementation of (potentially static thread local) |
|
258 |
+getters and setters are defined. These should be used in the class definition. |
|
259 |
+They define functions named `NAME`, which operate on a variable named |
|
260 |
+`NAME##_`. The underlying variable is not declared automatically, this must be |
|
261 |
+done manually (probably `private`). The `ACCESS` variant defines both `GET` and |
|
262 |
+`SET`. |
|
263 |
+ |
|
264 |
+`GLOBJECT_{GET,SET,ACCESS}{,_THREAD}(TYPE, NAME)` |
|
265 |
+ |
|
266 |
+Additionally, static thread local member variables need to be defined in |
|
267 |
+exactly one translation unit. A macro to help with this is defined as well. |
|
268 |
+Note that, since the definition is outside the class definition, the `NAME` |
|
269 |
+needs to be qualified with the class name. |
|
270 |
+ |
|
271 |
+`GLOBJECT_THREAD(NAME, INIT)` |
|
272 |
+ |
|
273 |
+#### Path |
|
274 |
+ |
|
275 |
+`Path static path_prefix_(Path path, Path prefix)` returns `prefix` prepended |
|
276 |
+to `path`, separated with a `/`, unless |
|
277 |
+ |
|
278 |
+1. `prefix` is empty |
|
279 |
+2. `path` starts with a `/` |
|
280 |
+ |
|
281 |
+in which case `path` is returned as is. |
|
282 |
+ |
|
283 |
+#### TGA |
|
284 |
+ |
|
285 |
+A `TGA` class is provided to handle [Truevision TGA][] images in uncompressed |
|
286 |
+[BGRA][] (`GL_BGRA`) format. TGA was selected because it is widely supported |
|
287 |
+and has trivial header and data layout. |
|
288 |
+ |
|
289 |
+`Size` is an alias for `std::array<GLsizei, 2>`. |
|
290 |
+ |
|
291 |
+`Data` is an alias for `std::vector<GLubyte>`. |
|
292 |
+ |
|
293 |
+`explicit TGA(Size size, Data data)` instantiates a `TGA` object with the given |
|
294 |
+`size` and `data`. |
|
295 |
+ |
|
296 |
+`TGA static read(std::string path)` reads the file `path` into a `TGA` object. |
|
297 |
+ |
|
298 |
+`void write(std::string const & path)` writes the `TGA` object to the file |
|
299 |
+`path`. |
|
300 |
+ |
|
301 |
+`Data data()` gets the data of the TGA image. |
|
302 |
+ |
|
303 |
+`Size size()` gets the size of the TGA image. |
|
304 |
+ |
|
305 |
+[Truevision TGA]: https://en.wikipedia.org/wiki/Truevision_TGA |
|
306 |
+[BGRA]: https://en.wikipedia.org/wiki/RGBA_color_model |
|
307 |
+ |
|
308 |
+#### Check |
|
309 |
+ |
|
310 |
+These functions throw an exception if some condition does not hold. It is |
|
311 |
+recommended that derived classes use similar helper functions, defined in an |
|
312 |
+implementation file, to hide the string processing necessary to form a helpful |
|
313 |
+exception message. |
|
314 |
+ |
|
315 |
+Derived classes should treat error checking as free during: |
|
316 |
+ |
|
317 |
+- Construction and destruction, except move construction. |
|
318 |
+- Exceptions. |
|
319 |
+- Debug function calls. |
|
320 |
+ |
|
321 |
+At all other times, non-critical error checking should only be performed if |
|
322 |
+`debug` is `true`. |
|
323 |
+ |
|
324 |
+`void static check_path_(std::string path)` checks that `path` is non-empty. |
|
325 |
+ |
|
326 |
+`void static check_error_(GLenum error)` checks an error returned by |
|
327 |
+[`glGetError`][]. |
|
328 |
+ |
|
329 |
+`void static check_supported_(Version version_min, std::string extension = {})` |
|
330 |
+checks that `supported` returns `true` for the given arguments. |
|
331 |
+ |
|
332 |
+`void static check_format_(GLenum format, GLenum format_expected)` checks that |
|
333 |
+`format` matches `format_expected`. |
|
334 |
+ |
|
335 |
+`void static check_type_(GLenum type, GLenum type_expected)` checks that `type` |
|
336 |
+matches `type_expected`. |
|
337 |
+ |
|
338 |
+`void static check_internal_format_(GLenum internal_format)` checks that |
|
339 |
+`internal_format` is supported. |
|
340 |
+ |
|
341 |
+[`glGetError`]: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glGetError.xhtml |
|
342 |
+ |
|
343 |
+#### Fail |
|
344 |
+ |
|
345 |
+These functions throw an exception and should be marked `[[noreturn]]`. It is |
|
346 |
+recommended that derived classes use similar helper functions, defined in an |
|
347 |
+implementation file, to hide the string processing necessary to form a helpful |
|
348 |
+exception message. |
|
349 |
+ |
|
350 |
+`void fail_action_(std::string action)` throws an exception with a message that |
|
351 |
+includes `action` and `debug_name()`. |
|
352 |
+ |
|
353 |
+#### String |
|
354 |
+ |
|
355 |
+`std::string static str_path_(Path path)` returns `path` surrounded by quotes. |
|
356 |
+ |
|
357 |
+`std::string static str_paths_(Paths paths)` returns `paths` surrounded by |
|
358 |
+quotes and joined with commas. |
|
359 |
+ |
|
360 |
+`std::string static str_enum_(GLenum name)` returns the hexadecimal string |
|
361 |
+representation of `name` (often used as fallback). |
|
362 |
+ |
|
363 |
+`std::string static str_error_(GLenum error)` returns the string representation |
|
364 |
+of values returned by [`glGetError`][]. |
|
365 |
+ |
|
366 |
+`std::string static str_format_(GLenum format)` returns the string |
|
367 |
+representation of `format`. |
|
368 |
+ |
|
369 |
+`std::string static str_type_(GLenum type)` returns the string representation |
|
370 |
+of `type`. |
|
371 |
+ |
|
372 |
+`std::string static str_internal_format_(GLenum internal_format)` returns the |
|
373 |
+string representation of `internal_format`. |
|
374 |
+ |
|
11 | 375 |
## Build system |
12 | 376 |
|
13 | 377 |
This project supports [CMake][] and uses [`cmake-common`][]. There are several |
14 | 378 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,15 @@ |
1 |
+#!/bin/sh |
|
2 |
+set -euC |
|
3 |
+ |
|
4 |
+{ |
|
5 |
+ printf '%s\n' '#include <GL/glew.h>' |
|
6 |
+ g++ -DGLM_VERSION -E '../include/globject.hpp' \ |
|
7 |
+ | grep -v '^#' \ |
|
8 |
+ | clang-format \ |
|
9 |
+ | awk ' |
|
10 |
+ x>0 && /{/ {++x} |
|
11 |
+ /GLObject::DataTraits<.*> {/ {++x} |
|
12 |
+ x>0 |
|
13 |
+ x>0 && /}/ {--x} |
|
14 |
+ ' |
|
15 |
+} >| 'globject_data_traits.hpp' |
0 | 16 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,469 @@ |
1 |
+#include <GL/glew.h> |
|
2 |
+template <> struct GLObject::DataTraits<GLfloat> { |
|
3 |
+ auto static constexpr name = "GLfloat"; |
|
4 |
+ auto static constexpr columns = GLint{1}; |
|
5 |
+ auto static constexpr rows = GLint{1}; |
|
6 |
+ auto static constexpr format = GLenum{0x1903}; |
|
7 |
+ auto static constexpr type = GLenum{0x1406}; |
|
8 |
+ auto static constexpr internal_format = GLenum{0x822E}; |
|
9 |
+ void static attrib(GLuint index, GLfloat const &value) { |
|
10 |
+ if (GLObject::debug()) |
|
11 |
+ check_supported_({2, 0}); |
|
12 |
+ __glewVertexAttrib1f(index, value); |
|
13 |
+ } |
|
14 |
+ void static uniform(GLint location, GLfloat const &value) { |
|
15 |
+ if (GLObject::debug()) |
|
16 |
+ check_supported_({2, 0}); |
|
17 |
+ __glewUniform1f(location, value); |
|
18 |
+ } |
|
19 |
+}; |
|
20 |
+template <> struct GLObject::DataTraits<GLbyte> { |
|
21 |
+ auto static constexpr name = "GLbyte"; |
|
22 |
+ auto static constexpr columns = GLint{1}; |
|
23 |
+ auto static constexpr rows = GLint{1}; |
|
24 |
+ auto static constexpr format = GLenum{0x1903}; |
|
25 |
+ auto static constexpr type = GLenum{0x1400}; |
|
26 |
+ auto static constexpr internal_format = GLenum{0x8231}; |
|
27 |
+ void static attrib(GLuint index, GLbyte const &value) { |
|
28 |
+ if (GLObject::debug()) |
|
29 |
+ check_supported_({3, 0}); |
|
30 |
+ __glewVertexAttribI1i(index, value); |
|
31 |
+ } |
|
32 |
+ void static uniform(GLint location, GLbyte const &value) { |
|
33 |
+ if (GLObject::debug()) |
|
34 |
+ check_supported_({2, 0}); |
|
35 |
+ __glewUniform1i(location, value); |
|
36 |
+ } |
|
37 |
+}; |
|
38 |
+template <> struct GLObject::DataTraits<GLshort> { |
|
39 |
+ auto static constexpr name = "GLshort"; |
|
40 |
+ auto static constexpr columns = GLint{1}; |
|
41 |
+ auto static constexpr rows = GLint{1}; |
|
42 |
+ auto static constexpr format = GLenum{0x1903}; |
|
43 |
+ auto static constexpr type = GLenum{0x1402}; |
|
44 |
+ auto static constexpr internal_format = GLenum{0x8233}; |
|
45 |
+ void static attrib(GLuint index, GLshort const &value) { |
|
46 |
+ if (GLObject::debug()) |
|
47 |
+ check_supported_({3, 0}); |
|
48 |
+ __glewVertexAttribI1i(index, value); |
|
49 |
+ } |
|
50 |
+ void static uniform(GLint location, GLshort const &value) { |
|
51 |
+ if (GLObject::debug()) |
|
52 |
+ check_supported_({2, 0}); |
|
53 |
+ __glewUniform1i(location, value); |
|
54 |
+ } |
|
55 |
+}; |
|
56 |
+template <> struct GLObject::DataTraits<GLint> { |
|
57 |
+ auto static constexpr name = "GLint"; |
|
58 |
+ auto static constexpr columns = GLint{1}; |
|
59 |
+ auto static constexpr rows = GLint{1}; |
|
60 |
+ auto static constexpr format = GLenum{0x1903}; |
|
61 |
+ auto static constexpr type = GLenum{0x1404}; |
|
62 |
+ auto static constexpr internal_format = GLenum{0x8235}; |
|
63 |
+ void static attrib(GLuint index, GLint const &value) { |
|
64 |
+ if (GLObject::debug()) |
|
65 |
+ check_supported_({3, 0}); |
|
66 |
+ __glewVertexAttribI1i(index, value); |
|
67 |
+ } |
|
68 |
+ void static uniform(GLint location, GLint const &value) { |
|
69 |
+ if (GLObject::debug()) |
|
70 |
+ check_supported_({2, 0}); |
|
71 |
+ __glewUniform1i(location, value); |
|
72 |
+ } |
|
73 |
+}; |
|
74 |
+template <> struct GLObject::DataTraits<GLubyte> { |
|
75 |
+ auto static constexpr name = "GLubyte"; |
|
76 |
+ auto static constexpr columns = GLint{1}; |
|
77 |
+ auto static constexpr rows = GLint{1}; |
|
78 |
+ auto static constexpr format = GLenum{0x1903}; |
|
79 |
+ auto static constexpr type = GLenum{0x1401}; |
|
80 |
+ auto static constexpr internal_format = GLenum{0x8232}; |
|
81 |
+ void static attrib(GLuint index, GLubyte const &value) { |
|
82 |
+ if (GLObject::debug()) |
|
83 |
+ check_supported_({3, 0}); |
|
84 |
+ __glewVertexAttribI1ui(index, value); |
|
85 |
+ } |
|
86 |
+ void static uniform(GLint location, GLubyte const &value) { |
|
87 |
+ if (GLObject::debug()) |
|
88 |
+ check_supported_({3, 0}); |
|
89 |
+ __glewUniform1ui(location, value); |
|
90 |
+ } |
|
91 |
+}; |
|
92 |
+template <> struct GLObject::DataTraits<GLushort> { |
|
93 |
+ auto static constexpr name = "GLushort"; |
|
94 |
+ auto static constexpr columns = GLint{1}; |
|
95 |
+ auto static constexpr rows = GLint{1}; |
|
96 |
+ auto static constexpr format = GLenum{0x1903}; |
|
97 |
+ auto static constexpr type = GLenum{0x1403}; |
|
98 |
+ auto static constexpr internal_format = GLenum{0x8234}; |
|
99 |
+ void static attrib(GLuint index, GLushort const &value) { |
|
100 |
+ if (GLObject::debug()) |
|
101 |
+ check_supported_({3, 0}); |
|
102 |
+ __glewVertexAttribI1ui(index, value); |
|
103 |
+ } |
|
104 |
+ void static uniform(GLint location, GLushort const &value) { |
|
105 |
+ if (GLObject::debug()) |
|
106 |
+ check_supported_({3, 0}); |
|
107 |
+ __glewUniform1ui(location, value); |
|
108 |
+ } |
|
109 |
+}; |
|
110 |
+template <> struct GLObject::DataTraits<GLuint> { |
|
111 |
+ auto static constexpr name = "GLuint"; |
|
112 |
+ auto static constexpr columns = GLint{1}; |
|
113 |
+ auto static constexpr rows = GLint{1}; |
|
114 |
+ auto static constexpr format = GLenum{0x1903}; |
|
115 |
+ auto static constexpr type = GLenum{0x1405}; |
|
116 |
+ auto static constexpr internal_format = GLenum{0x8236}; |
|
117 |
+ void static attrib(GLuint index, GLuint const &value) { |
|
118 |
+ if (GLObject::debug()) |
|
119 |
+ check_supported_({3, 0}); |
|
120 |
+ __glewVertexAttribI1ui(index, value); |
|
121 |
+ } |
|
122 |
+ void static uniform(GLint location, GLuint const &value) { |
|
123 |
+ if (GLObject::debug()) |
|
124 |
+ check_supported_({3, 0}); |
|
125 |
+ __glewUniform1ui(location, value); |
|
126 |
+ } |
|
127 |
+}; |
|
128 |
+template <> struct GLObject::DataTraits<glm::vec2> { |
|
129 |
+ auto static constexpr name = "glm::vec2"; |
|
130 |
+ auto static constexpr columns = GLint{1}; |
|
131 |
+ auto static constexpr rows = GLint{2}; |
|
132 |
+ auto static constexpr format = GLenum{0x8227}; |
|
133 |
+ auto static constexpr type = GLenum{0x1406}; |
|
134 |
+ auto static constexpr internal_format = GLenum{0x8230}; |
|
135 |
+ void static attrib(GLuint index, glm::vec2 const &value) { |
|
136 |
+ if (GLObject::debug()) |
|
137 |
+ check_supported_({2, 0}); |
|
138 |
+ __glewVertexAttrib2fv(index, glm::value_ptr(value)); |
|
139 |
+ } |
|
140 |
+ void static uniform(GLint location, glm::vec2 const &value) { |
|
141 |
+ if (GLObject::debug()) |
|
142 |
+ check_supported_({2, 0}); |
|
143 |
+ __glewUniform2fv(location, 1, glm::value_ptr(value)); |
|
144 |
+ } |
|
145 |
+}; |
|
146 |
+template <> struct GLObject::DataTraits<glm::vec3> { |
|
147 |
+ auto static constexpr name = "glm::vec3"; |
|
148 |
+ auto static constexpr columns = GLint{1}; |
|
149 |
+ auto static constexpr rows = GLint{3}; |
|
150 |
+ auto static constexpr format = GLenum{0x1907}; |
|
151 |
+ auto static constexpr type = GLenum{0x1406}; |
|
152 |
+ auto static constexpr internal_format = GLenum{0x8815}; |
|
153 |
+ void static attrib(GLuint index, glm::vec3 const &value) { |
|
154 |
+ if (GLObject::debug()) |
|
155 |
+ check_supported_({2, 0}); |
|
156 |
+ __glewVertexAttrib3fv(index, glm::value_ptr(value)); |
|
157 |
+ } |
|
158 |
+ void static uniform(GLint location, glm::vec3 const &value) { |
|
159 |
+ if (GLObject::debug()) |
|
160 |
+ check_supported_({2, 0}); |
|
161 |
+ __glewUniform3fv(location, 1, glm::value_ptr(value)); |
|
162 |
+ } |
|
163 |
+}; |
|
164 |
+template <> struct GLObject::DataTraits<glm::vec4> { |
|
165 |
+ auto static constexpr name = "glm::vec4"; |
|
166 |
+ auto static constexpr columns = GLint{1}; |
|
167 |
+ auto static constexpr rows = GLint{4}; |
|
168 |
+ auto static constexpr format = GLenum{0x1908}; |
|
169 |
+ auto static constexpr type = GLenum{0x1406}; |
|
170 |
+ auto static constexpr internal_format = GLenum{0x8814}; |
|
171 |
+ void static attrib(GLuint index, glm::vec4 const &value) { |
|
172 |
+ if (GLObject::debug()) |
|
173 |
+ check_supported_({2, 0}); |
|
174 |
+ __glewVertexAttrib4fv(index, glm::value_ptr(value)); |
|
175 |
+ } |
|
176 |
+ void static uniform(GLint location, glm::vec4 const &value) { |
|
177 |
+ if (GLObject::debug()) |
|
178 |
+ check_supported_({2, 0}); |
|
179 |
+ __glewUniform4fv(location, 1, glm::value_ptr(value)); |
|
180 |
+ } |
|
181 |
+}; |
|
182 |
+template <> struct GLObject::DataTraits<glm::ivec2> { |
|
183 |
+ auto static constexpr name = "glm::ivec2"; |
|
184 |
+ auto static constexpr columns = GLint{1}; |
|
185 |
+ auto static constexpr rows = GLint{2}; |
|
186 |
+ auto static constexpr format = GLenum{0x8227}; |
|
187 |
+ auto static constexpr type = GLenum{0x1404}; |
|
188 |
+ auto static constexpr internal_format = GLenum{0x823B}; |
|
189 |
+ void static attrib(GLuint index, glm::ivec2 const &value) { |
|
190 |
+ if (GLObject::debug()) |
|
191 |
+ check_supported_({3, 0}); |
|
192 |
+ __glewVertexAttribI2iv(index, glm::value_ptr(value)); |
|
193 |
+ } |
|
194 |
+ void static uniform(GLint location, glm::ivec2 const &value) { |
|
195 |
+ if (GLObject::debug()) |
|
196 |
+ check_supported_({2, 0}); |
|
197 |
+ __glewUniform2iv(location, 1, glm::value_ptr(value)); |
|
198 |
+ } |
|
199 |
+}; |
|
200 |
+template <> struct GLObject::DataTraits<glm::ivec3> { |
|
201 |
+ auto static constexpr name = "glm::ivec3"; |
|
202 |
+ auto static constexpr columns = GLint{1}; |
|
203 |
+ auto static constexpr rows = GLint{3}; |
|
204 |
+ auto static constexpr format = GLenum{0x1907}; |
|
205 |
+ auto static constexpr type = GLenum{0x1404}; |
|
206 |
+ auto static constexpr internal_format = GLenum{0x8D83}; |
|
207 |
+ void static attrib(GLuint index, glm::ivec3 const &value) { |
|
208 |
+ if (GLObject::debug()) |
|
209 |
+ check_supported_({3, 0}); |
|
210 |
+ __glewVertexAttribI3iv(index, glm::value_ptr(value)); |
|
211 |
+ } |
|
212 |
+ void static uniform(GLint location, glm::ivec3 const &value) { |
|
213 |
+ if (GLObject::debug()) |
|
214 |
+ check_supported_({2, 0}); |
|
215 |
+ __glewUniform3iv(location, 1, glm::value_ptr(value)); |
|
216 |
+ } |
|
217 |
+}; |
|
218 |
+template <> struct GLObject::DataTraits<glm::ivec4> { |
|
219 |
+ auto static constexpr name = "glm::ivec4"; |
|
220 |
+ auto static constexpr columns = GLint{1}; |
|
221 |
+ auto static constexpr rows = GLint{4}; |
|
222 |
+ auto static constexpr format = GLenum{0x1908}; |
|
223 |
+ auto static constexpr type = GLenum{0x1404}; |
|
224 |
+ auto static constexpr internal_format = GLenum{0x8D82}; |
|
225 |
+ void static attrib(GLuint index, glm::ivec4 const &value) { |
|
226 |
+ if (GLObject::debug()) |
|
227 |
+ check_supported_({3, 0}); |
|
228 |
+ __glewVertexAttribI4iv(index, glm::value_ptr(value)); |
|
229 |
+ } |
|
230 |
+ void static uniform(GLint location, glm::ivec4 const &value) { |
|
231 |
+ if (GLObject::debug()) |
|
232 |
+ check_supported_({2, 0}); |
|
233 |
+ __glewUniform4iv(location, 1, glm::value_ptr(value)); |
|
234 |
+ } |
|
235 |
+}; |
|
236 |
+template <> struct GLObject::DataTraits<glm::uvec2> { |
|
237 |
+ auto static constexpr name = "glm::uvec2"; |
|
238 |
+ auto static constexpr columns = GLint{1}; |
|
239 |
+ auto static constexpr rows = GLint{2}; |
|
240 |
+ auto static constexpr format = GLenum{0x8227}; |
|
241 |
+ auto static constexpr type = GLenum{0x1405}; |
|
242 |
+ auto static constexpr internal_format = GLenum{0x823C}; |
|
243 |
+ void static attrib(GLuint index, glm::uvec2 const &value) { |
|
244 |
+ if (GLObject::debug()) |
|
245 |
+ check_supported_({3, 0}); |
|
246 |
+ __glewVertexAttribI2uiv(index, glm::value_ptr(value)); |
|
247 |
+ } |
|
248 |
+ void static uniform(GLint location, glm::uvec2 const &value) { |
|
249 |
+ if (GLObject::debug()) |
|
250 |
+ check_supported_({3, 0}); |
|
251 |
+ __glewUniform2uiv(location, 1, glm::value_ptr(value)); |
|
252 |
+ } |
|
253 |
+}; |
|
254 |
+template <> struct GLObject::DataTraits<glm::uvec3> { |
|
255 |
+ auto static constexpr name = "glm::uvec3"; |
|
256 |
+ auto static constexpr columns = GLint{1}; |
|
257 |
+ auto static constexpr rows = GLint{3}; |
|
258 |
+ auto static constexpr format = GLenum{0x1907}; |
|
259 |
+ auto static constexpr type = GLenum{0x1405}; |
|
260 |
+ auto static constexpr internal_format = GLenum{0x8D71}; |
|
261 |
+ void static attrib(GLuint index, glm::uvec3 const &value) { |
|
262 |
+ if (GLObject::debug()) |
|
263 |
+ check_supported_({3, 0}); |
|
264 |
+ __glewVertexAttribI3uiv(index, glm::value_ptr(value)); |
|
265 |
+ } |
|
266 |
+ void static uniform(GLint location, glm::uvec3 const &value) { |
|
267 |
+ if (GLObject::debug()) |
|
268 |
+ check_supported_({3, 0}); |
|
269 |
+ __glewUniform3uiv(location, 1, glm::value_ptr(value)); |
|
270 |
+ } |
|
271 |
+}; |
|
272 |
+template <> struct GLObject::DataTraits<glm::uvec4> { |
|
273 |
+ auto static constexpr name = "glm::uvec4"; |
|
274 |
+ auto static constexpr columns = GLint{1}; |
|
275 |
+ auto static constexpr rows = GLint{4}; |
|
276 |
+ auto static constexpr format = GLenum{0x1908}; |
|
277 |
+ auto static constexpr type = GLenum{0x1405}; |
|
278 |
+ auto static constexpr internal_format = GLenum{0x8D70}; |
|
279 |
+ void static attrib(GLuint index, glm::uvec4 const &value) { |
|
280 |
+ if (GLObject::debug()) |
|
281 |
+ check_supported_({3, 0}); |
|
282 |
+ __glewVertexAttribI4uiv(index, glm::value_ptr(value)); |
|
283 |
+ } |
|
284 |
+ void static uniform(GLint location, glm::uvec4 const &value) { |
|
285 |
+ if (GLObject::debug()) |
|
286 |
+ check_supported_({3, 0}); |
|
287 |
+ __glewUniform4uiv(location, 1, glm::value_ptr(value)); |
|
288 |
+ } |
|
289 |
+}; |
|
290 |
+template <> struct GLObject::DataTraits<glm::mat2> { |
|
291 |
+ auto static constexpr name = "glm::mat2"; |
|
292 |
+ auto static constexpr columns = GLint{2}; |
|
293 |
+ auto static constexpr rows = GLint{2}; |
|
294 |
+ auto static constexpr format = GLenum{0x8227}; |
|
295 |
+ auto static constexpr type = GLenum{0x1406}; |
|
296 |
+ auto static constexpr internal_format = GLenum{0x8230}; |
|
297 |
+ void static attrib(GLuint index, glm::mat2 const &value) { |
|
298 |
+ if (GLObject::debug()) |
|
299 |
+ check_supported_({2, 0}); |
|
300 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
301 |
+ __glewVertexAttrib2fv(index + column, |
|
302 |
+ glm::value_ptr(value) + (column * rows)); |
|
303 |
+ } |
|
304 |
+ void static uniform(GLint location, glm::mat2 const &value) { |
|
305 |
+ if (GLObject::debug()) |
|
306 |
+ check_supported_({2, 0}); |
|
307 |
+ __glewUniformMatrix2fv(location, 1, 0, glm::value_ptr(value)); |
|
308 |
+ } |
|
309 |
+}; |
|
310 |
+template <> struct GLObject::DataTraits<glm::mat2x3> { |
|
311 |
+ auto static constexpr name = "glm::mat2x3"; |
|
312 |
+ auto static constexpr columns = GLint{2}; |
|
313 |
+ auto static constexpr rows = GLint{3}; |
|
314 |
+ auto static constexpr format = GLenum{0x1907}; |
|
315 |
+ auto static constexpr type = GLenum{0x1406}; |
|
316 |
+ auto static constexpr internal_format = GLenum{0x8815}; |
|
317 |
+ void static attrib(GLuint index, glm::mat2x3 const &value) { |
|
318 |
+ if (GLObject::debug()) |
|
319 |
+ check_supported_({2, 0}); |
|
320 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
321 |
+ __glewVertexAttrib3fv(index + column, |
|
322 |
+ glm::value_ptr(value) + (column * rows)); |
|
323 |
+ } |
|
324 |
+ void static uniform(GLint location, glm::mat2x3 const &value) { |
|
325 |
+ if (GLObject::debug()) |
|
326 |
+ check_supported_({2, 1}); |
|
327 |
+ __glewUniformMatrix2x3fv(location, 1, 0, glm::value_ptr(value)); |
|
328 |
+ } |
|
329 |
+}; |
|
330 |
+template <> struct GLObject::DataTraits<glm::mat2x4> { |
|
331 |
+ auto static constexpr name = "glm::mat2x4"; |
|
332 |
+ auto static constexpr columns = GLint{2}; |
|
333 |
+ auto static constexpr rows = GLint{4}; |
|
334 |
+ auto static constexpr format = GLenum{0x1908}; |
|
335 |
+ auto static constexpr type = GLenum{0x1406}; |
|
336 |
+ auto static constexpr internal_format = GLenum{0x8814}; |
|
337 |
+ void static attrib(GLuint index, glm::mat2x4 const &value) { |
|
338 |
+ if (GLObject::debug()) |
|
339 |
+ check_supported_({2, 0}); |
|
340 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
341 |
+ __glewVertexAttrib4fv(index + column, |
|
342 |
+ glm::value_ptr(value) + (column * rows)); |
|
343 |
+ } |
|
344 |
+ void static uniform(GLint location, glm::mat2x4 const &value) { |
|
345 |
+ if (GLObject::debug()) |
|
346 |
+ check_supported_({2, 1}); |
|
347 |
+ __glewUniformMatrix2x4fv(location, 1, 0, glm::value_ptr(value)); |
|
348 |
+ } |
|
349 |
+}; |
|
350 |
+template <> struct GLObject::DataTraits<glm::mat3x2> { |
|
351 |
+ auto static constexpr name = "glm::mat3x2"; |
|
352 |
+ auto static constexpr columns = GLint{3}; |
|
353 |
+ auto static constexpr rows = GLint{2}; |
|
354 |
+ auto static constexpr format = GLenum{0x8227}; |
|
355 |
+ auto static constexpr type = GLenum{0x1406}; |
|
356 |
+ auto static constexpr internal_format = GLenum{0x8230}; |
|
357 |
+ void static attrib(GLuint index, glm::mat3x2 const &value) { |
|
358 |
+ if (GLObject::debug()) |
|
359 |
+ check_supported_({2, 0}); |
|
360 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
361 |
+ __glewVertexAttrib2fv(index + column, |
|
362 |
+ glm::value_ptr(value) + (column * rows)); |
|
363 |
+ } |
|
364 |
+ void static uniform(GLint location, glm::mat3x2 const &value) { |
|
365 |
+ if (GLObject::debug()) |
|
366 |
+ check_supported_({2, 1}); |
|
367 |
+ __glewUniformMatrix3x2fv(location, 1, 0, glm::value_ptr(value)); |
|
368 |
+ } |
|
369 |
+}; |
|
370 |
+template <> struct GLObject::DataTraits<glm::mat3> { |
|
371 |
+ auto static constexpr name = "glm::mat3"; |
|
372 |
+ auto static constexpr columns = GLint{3}; |
|
373 |
+ auto static constexpr rows = GLint{3}; |
|
374 |
+ auto static constexpr format = GLenum{0x1907}; |
|
375 |
+ auto static constexpr type = GLenum{0x1406}; |
|
376 |
+ auto static constexpr internal_format = GLenum{0x8815}; |
|
377 |
+ void static attrib(GLuint index, glm::mat3 const &value) { |
|
378 |
+ if (GLObject::debug()) |
|
379 |
+ check_supported_({2, 0}); |
|
380 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
381 |
+ __glewVertexAttrib3fv(index + column, |
|
382 |
+ glm::value_ptr(value) + (column * rows)); |
|
383 |
+ } |
|
384 |
+ void static uniform(GLint location, glm::mat3 const &value) { |
|
385 |
+ if (GLObject::debug()) |
|
386 |
+ check_supported_({2, 0}); |
|
387 |
+ __glewUniformMatrix3fv(location, 1, 0, glm::value_ptr(value)); |
|
388 |
+ } |
|
389 |
+}; |
|
390 |
+template <> struct GLObject::DataTraits<glm::mat3x4> { |
|
391 |
+ auto static constexpr name = "glm::mat3x4"; |
|
392 |
+ auto static constexpr columns = GLint{3}; |
|
393 |
+ auto static constexpr rows = GLint{4}; |
|
394 |
+ auto static constexpr format = GLenum{0x1908}; |
|
395 |
+ auto static constexpr type = GLenum{0x1406}; |
|
396 |
+ auto static constexpr internal_format = GLenum{0x8814}; |
|
397 |
+ void static attrib(GLuint index, glm::mat3x4 const &value) { |
|
398 |
+ if (GLObject::debug()) |
|
399 |
+ check_supported_({2, 0}); |
|
400 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
401 |
+ __glewVertexAttrib4fv(index + column, |
|
402 |
+ glm::value_ptr(value) + (column * rows)); |
|
403 |
+ } |
|
404 |
+ void static uniform(GLint location, glm::mat3x4 const &value) { |
|
405 |
+ if (GLObject::debug()) |
|
406 |
+ check_supported_({2, 1}); |
|
407 |
+ __glewUniformMatrix3x4fv(location, 1, 0, glm::value_ptr(value)); |
|
408 |
+ } |
|
409 |
+}; |
|
410 |
+template <> struct GLObject::DataTraits<glm::mat4x2> { |
|
411 |
+ auto static constexpr name = "glm::mat4x2"; |
|
412 |
+ auto static constexpr columns = GLint{4}; |
|
413 |
+ auto static constexpr rows = GLint{2}; |
|
414 |
+ auto static constexpr format = GLenum{0x8227}; |
|
415 |
+ auto static constexpr type = GLenum{0x1406}; |
|
416 |
+ auto static constexpr internal_format = GLenum{0x8230}; |
|
417 |
+ void static attrib(GLuint index, glm::mat4x2 const &value) { |
|
418 |
+ if (GLObject::debug()) |
|
419 |
+ check_supported_({2, 0}); |
|
420 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
421 |
+ __glewVertexAttrib2fv(index + column, |
|
422 |
+ glm::value_ptr(value) + (column * rows)); |
|
423 |
+ } |
|
424 |
+ void static uniform(GLint location, glm::mat4x2 const &value) { |
|
425 |
+ if (GLObject::debug()) |
|
426 |
+ check_supported_({2, 1}); |
|
427 |
+ __glewUniformMatrix4x2fv(location, 1, 0, glm::value_ptr(value)); |
|
428 |
+ } |
|
429 |
+}; |
|
430 |
+template <> struct GLObject::DataTraits<glm::mat4x3> { |
|
431 |
+ auto static constexpr name = "glm::mat4x3"; |
|
432 |
+ auto static constexpr columns = GLint{4}; |
|
433 |
+ auto static constexpr rows = GLint{3}; |
|
434 |
+ auto static constexpr format = GLenum{0x1907}; |
|
435 |
+ auto static constexpr type = GLenum{0x1406}; |
|
436 |
+ auto static constexpr internal_format = GLenum{0x8815}; |
|
437 |
+ void static attrib(GLuint index, glm::mat4x3 const &value) { |
|
438 |
+ if (GLObject::debug()) |
|
439 |
+ check_supported_({2, 0}); |
|
440 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
441 |
+ __glewVertexAttrib3fv(index + column, |
|
442 |
+ glm::value_ptr(value) + (column * rows)); |
|
443 |
+ } |
|
444 |
+ void static uniform(GLint location, glm::mat4x3 const &value) { |
|
445 |
+ if (GLObject::debug()) |
|
446 |
+ check_supported_({2, 1}); |
|
447 |
+ __glewUniformMatrix4x3fv(location, 1, 0, glm::value_ptr(value)); |
|
448 |
+ } |
|
449 |
+}; |
|
450 |
+template <> struct GLObject::DataTraits<glm::mat4> { |
|
451 |
+ auto static constexpr name = "glm::mat4"; |
|
452 |
+ auto static constexpr columns = GLint{4}; |
|
453 |
+ auto static constexpr rows = GLint{4}; |
|
454 |
+ auto static constexpr format = GLenum{0x1908}; |
|
455 |
+ auto static constexpr type = GLenum{0x1406}; |
|
456 |
+ auto static constexpr internal_format = GLenum{0x8814}; |
|
457 |
+ void static attrib(GLuint index, glm::mat4 const &value) { |
|
458 |
+ if (GLObject::debug()) |
|
459 |
+ check_supported_({2, 0}); |
|
460 |
+ for (auto column = GLuint{0}; column < columns; ++column) |
|
461 |
+ __glewVertexAttrib4fv(index + column, |
|
462 |
+ glm::value_ptr(value) + (column * rows)); |
|
463 |
+ } |
|
464 |
+ void static uniform(GLint location, glm::mat4 const &value) { |
|
465 |
+ if (GLObject::debug()) |
|
466 |
+ check_supported_({2, 0}); |
|
467 |
+ __glewUniformMatrix4fv(location, 1, 0, glm::value_ptr(value)); |
|
468 |
+ } |
|
469 |
+}; |
0 | 470 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,356 @@ |
1 |
+#ifndef GLOBJECT_HPP_ |
|
2 |
+#define GLOBJECT_HPP_ |
|
3 |
+ |
|
4 |
+ |
|
5 |
+#include <array> |
|
6 |
+#include <functional> |
|
7 |
+#include <stdexcept> |
|
8 |
+#include <string> |
|
9 |
+#include <utility> |
|
10 |
+#include <vector> |
|
11 |
+ |
|
12 |
+#ifndef GLOBJECT_LOADER |
|
13 |
+#define GLOBJECT_LOADER <GL/glew.h> |
|
14 |
+#endif |
|
15 |
+// cppcheck-suppress preprocessorErrorDirective |
|
16 |
+#include GLOBJECT_LOADER |
|
17 |
+ |
|
18 |
+ |
|
19 |
+/// Getters and setters |
|
20 |
+ |
|
21 |
+#define GLOBJECT_GET_(TYPE, NAME, STATIC, CONST) \ |
|
22 |
+ TYPE STATIC const & NAME() CONST \ |
|
23 |
+ { \ |
|
24 |
+ return NAME##_; \ |
|
25 |
+ } |
|
26 |
+ |
|
27 |
+#define GLOBJECT_SET_(TYPE, NAME, STATIC, CONST) \ |
|
28 |
+ template<typename Type> \ |
|
29 |
+ TYPE STATIC NAME(Type && NAME) \ |
|
30 |
+ { \ |
|
31 |
+ auto NAME##_old = std::move (NAME##_); \ |
|
32 |
+ NAME##_ = std::forward<Type>(NAME); \ |
|
33 |
+ return NAME##_old; \ |
|
34 |
+ } |
|
35 |
+ |
|
36 |
+#define GLOBJECT_THREAD(NAME, INIT) \ |
|
37 |
+ decltype(NAME) thread_local NAME INIT; |
|
38 |
+ |
|
39 |
+#define GLOBJECT_GET( TYPE, NAME) GLOBJECT_GET_(TYPE, NAME,, const) |
|
40 |
+#define GLOBJECT_SET( TYPE, NAME) GLOBJECT_SET_(TYPE, NAME,, const) |
|
41 |
+#define GLOBJECT_GET_THREAD(TYPE, NAME) GLOBJECT_GET_(TYPE, NAME, static,) |
|
42 |
+#define GLOBJECT_SET_THREAD(TYPE, NAME) GLOBJECT_SET_(TYPE, NAME, static,) |
|
43 |
+ |
|
44 |
+#define GLOBJECT_ACCESS(TYPE, NAME) \ |
|
45 |
+ GLOBJECT_GET(TYPE, NAME) \ |
|
46 |
+ GLOBJECT_SET(TYPE, NAME) |
|
47 |
+ |
|
48 |
+#define GLOBJECT_ACCESS_THREAD(TYPE, NAME) \ |
|
49 |
+ GLOBJECT_GET_THREAD(TYPE, NAME) \ |
|
50 |
+ GLOBJECT_SET_THREAD(TYPE, NAME) |
|
51 |
+ |
|
52 |
+/// Debug |
|
53 |
+ |
|
54 |
+#ifndef GLOBJECT_DEBUG |
|
55 |
+#define GLOBJECT_DEBUG 1 |
|
56 |
+#endif |
|
57 |
+ |
|
58 |
+#if GLOBJECT_DEBUG |
|
59 |
+#define GLOBJECT_DEBUG_IF(D) if (GLObject::debug() >= D) |
|
60 |
+#else |
|
61 |
+#define GLOBJECT_DEBUG_IF(D) if (false) |
|
62 |
+#endif |
|
63 |
+ |
|
64 |
+ |
|
65 |
+/// Class |
|
66 |
+ |
|
67 |
+class GLObject |
|
68 |
+{ |
|
69 |
+public: |
|
70 |
+ |
|
71 |
+ /// Core |
|
72 |
+ |
|
73 |
+ using Version = std::array<GLint, 2>; |
|
74 |
+ |
|
75 |
+ bool static supported( |
|
76 |
+ Version version_min, |
|
77 |
+ std::string const & extension = {} |
|
78 |
+ ); |
|
79 |
+ |
|
80 |
+ GLint static get_integer(GLenum name); |
|
81 |
+ |
|
82 |
+ GLOBJECT_GET(GLuint, object) |
|
83 |
+ |
|
84 |
+ operator GLuint() const { return object(); } |
|
85 |
+ |
|
86 |
+ /// Data |
|
87 |
+ |
|
88 |
+ template<typename Data> |
|
89 |
+ struct DataTraits; |
|
90 |
+ |
|
91 |
+ /// Path |
|
92 |
+ |
|
93 |
+ using Path = std::string; |
|
94 |
+ using Paths = std::vector<Path>; |
|
95 |
+ |
|
96 |
+ /// Debug |
|
97 |
+ |
|
98 |
+ using DebugCallback = std::function<void (std::string const & message)>; |
|
99 |
+ using DebugObjects = std::vector<GLObject *>; |
|
100 |
+ |
|
101 |
+ GLOBJECT_ACCESS_THREAD(int, debug) |
|
102 |
+ GLOBJECT_ACCESS_THREAD(DebugCallback, debug_callback) |
|
103 |
+ GLOBJECT_GET_THREAD (DebugObjects, debug_objects) |
|
104 |
+ |
|
105 |
+ std::string debug_name() const; |
|
106 |
+ std::string virtual debug_info() const; |
|
107 |
+ std::string static debug_objects_name(); |
|
108 |
+ std::string static debug_objects_info(); |
|
109 |
+ |
|
110 |
+ /// Exceptions |
|
111 |
+ |
|
112 |
+ struct Exception : std::runtime_error |
|
113 |
+ { |
|
114 |
+ using std::runtime_error::runtime_error; |
|
115 |
+ }; |
|
116 |
+ |
|
117 |
+protected: |
|
118 |
+ |
|
119 |
+ /// Special member functions |
|
120 |
+ |
|
121 |
+ using GLGenObjects = void (*)(GLsizei n, GLuint * objects); |
|
122 |
+ using GLDeleteObjects = void (*)(GLsizei n, GLuint const * objects); |
|
123 |
+ |
|
124 |
+ using GLCreateObject = GLuint (*)(); |
|
125 |
+ using GLDeleteObject = void (*)(GLuint); |
|
126 |
+ |
|
127 |
+ template<GLCreateObject gl_create_object> |
|
128 |
+ void static gl_create_object_(GLsizei n, GLuint * objects); |
|
129 |
+ |
|
130 |
+ template<GLDeleteObject gl_delete_object> |
|
131 |
+ void static gl_delete_object_(GLsizei n, GLuint * objects); |
|
132 |
+ |
|
133 |
+ explicit GLObject( |
|
134 |
+ GLGenObjects gl_gen_objects, |
|
135 |
+ GLDeleteObjects gl_delete_objects, |
|
136 |
+ GLenum object_type, |
|
137 |
+ std::string object_label |
|
138 |
+ ); |
|
139 |
+ virtual ~GLObject(); |
|
140 |
+ GLObject(GLObject && other) noexcept; |
|
141 |
+ GLObject(GLObject const &) = delete; |
|
142 |
+ GLObject & operator=(GLObject &&) = delete; |
|
143 |
+ GLObject & operator=(GLObject const &) = delete; |
|
144 |
+ |
|
145 |
+ /// Path |
|
146 |
+ |
|
147 |
+ Path static path_prefix_( |
|
148 |
+ Path const & path, |
|
149 |
+ Path const & prefix |
|
150 |
+ ); |
|
151 |
+ |
|
152 |
+ /// TGA |
|
153 |
+ |
|
154 |
+ class TGA |
|
155 |
+ { |
|
156 |
+ public: |
|
157 |
+ using Size = std::array<GLsizei, 2>; |
|
158 |
+ using Data = std::vector<GLubyte>; |
|
159 |
+ explicit TGA(Size size, Data data); |
|
160 |
+ TGA static read (Path const & path); |
|
161 |
+ void write(Path const & path) const; |
|
162 |
+ Size size() const; |
|
163 |
+ Data const & data(); |
|
164 |
+ private: |
|
165 |
+ std::string static str_size_(Size size); |
|
166 |
+ void check_header_() const; |
|
167 |
+ void check_data_() const; |
|
168 |
+ private: |
|
169 |
+ // NOLINTNEXTLINE |
|
170 |
+ struct Header : std::array<GLubyte, 18> |
|
171 |
+ { |
|
172 |
+ explicit Header(Size size); |
|
173 |
+ }; |
|
174 |
+ Header header_; |
|
175 |
+ Data data_; |
|
176 |
+ }; |
|
177 |
+ |
|
178 |
+ /// Check |
|
179 |
+ |
|
180 |
+ void static check_path_(Path const & path); |
|
181 |
+ void static check_error_(GLenum error); |
|
182 |
+ void static check_supported_( |
|
183 |
+ Version version_min, |
|
184 |
+ std::string const & extension = {} |
|
185 |
+ ); |
|
186 |
+ void static check_format_( |
|
187 |
+ GLenum format, |
|
188 |
+ GLenum format_expected |
|
189 |
+ ); |
|
190 |
+ void static check_type_( |
|
191 |
+ GLenum type, |
|
192 |
+ GLenum type_expected |
|
193 |
+ ); |
|
194 |
+ void static check_internal_format_( |
|
195 |
+ GLenum internal_format |
|
196 |
+ ); |
|
197 |
+ |
|
198 |
+ |
|
199 |
+ /// Fail |
|
200 |
+ |
|
201 |
+ [[noreturn]] void fail_action_(std::string const & action) const; |
|
202 |
+ |
|
203 |
+ /// String |
|
204 |
+ |
|
205 |
+ std::string static str_path_ (Path const & path); |
|
206 |
+ std::string static str_paths_ (Paths const & paths); |
|
207 |
+ std::string static str_enum_ (GLenum name); |
|
208 |
+ std::string static str_error_ (GLenum error); |
|
209 |
+ std::string static str_format_ (GLenum format); |
|
210 |
+ std::string static str_type_ (GLenum type); |
|
211 |
+ std::string static str_internal_format_(GLenum internal_format); |
|
212 |
+ |
|
213 |
+private: |
|
214 |
+ |
|
215 |
+ /// Debug |
|
216 |
+ |
|
217 |
+ void debug_label_() const; |
|
218 |
+ |
|
219 |
+ void static debug_objects_push_back_(GLObject * debug_object); |
|
220 |
+ void static debug_objects_erase_ (GLObject * debug_object); |
|
221 |
+ |
|
222 |
+ /// String |
|
223 |
+ |
|
224 |
+ std::string static str_object_type_(GLenum object_type); |
|
225 |
+ |
|
226 |
+private: |
|
227 |
+ |
|
228 |
+ /// Special member functions |
|
229 |
+ |
|
230 |
+ GLDeleteObjects const gl_delete_objects_; |
|
231 |
+ |
|
232 |
+ /// Core |
|
233 |
+ |
|
234 |
+ auto static constexpr object_pseudo_ = (GLuint)-1; |
|
235 |
+ |
|
236 |
+ GLenum const object_type_; |
|
237 |
+ std::string object_label_; |
|
238 |
+ GLuint object_; |
|
239 |
+ |
|
240 |
+ /// Debug |
|
241 |
+ |
|
242 |
+ int static thread_local debug_; |
|
243 |
+ DebugCallback static thread_local debug_callback_; |
|
244 |
+ DebugObjects static thread_local debug_objects_; |
|
245 |
+}; |
|
246 |
+ |
|
247 |
+ |
|
248 |
+/// Special member functions |
|
249 |
+ |
|
250 |
+template<GLObject::GLCreateObject gl_create_object> |
|
251 |
+void GLObject::gl_create_object_(GLsizei n, GLuint * objects) |
|
252 |
+{ |
|
253 |
+ for (auto i = GLsizei{0}; i < n; ++i) |
|
254 |
+ objects[i] = gl_create_object(); |
|
255 |
+} |
|
256 |
+ |
|
257 |
+template<GLObject::GLDeleteObject gl_delete_object> |
|
258 |
+void GLObject::gl_delete_object_(GLsizei n, GLuint * objects) |
|
259 |
+{ |
|
260 |
+ for (auto i = GLsizei{0}; i < n; ++i) |
|
261 |
+ gl_delete_object(objects[i]); |
|
262 |
+} |
|
263 |
+ |
|
264 |
+/// Data |
|
265 |
+ |
|
266 |
+#define GLOBJECT_DATA( \ |
|
267 |
+ DATA, \ |
|
268 |
+ V1A, \ |
|
269 |
+ V2A, \ |
|
270 |
+ V1U, \ |
|
271 |
+ V2U, \ |
|
272 |
+ COLUMNS, \ |
|
273 |
+ ROWS, \ |
|
274 |
+ ATTRIB, \ |
|
275 |
+ UNIFORM, \ |
|
276 |
+ SUFFIX, \ |
|
277 |
+ FORMAT, \ |
|
278 |
+ TYPE, \ |
|
279 |
+ INTERNAL_FORMAT, \ |
|
280 |
+ VALUE, \ |
|
281 |
+ FOR_COLUMNS, \ |
|
282 |
+ PLUS_COLUMN, \ |
|
283 |
+ PLUS_COLUMN_TIMES_ROWS, \ |
|
284 |
+ ... \ |
|
285 |
+) \ |
|
286 |
+ template<> \ |
|
287 |
+ struct GLObject::DataTraits<DATA> \ |
|
288 |
+ { \ |
|
289 |
+ auto static constexpr name = #DATA; \ |
|
290 |
+ auto static constexpr columns = GLint {COLUMNS}; \ |
|
291 |
+ auto static constexpr rows = GLint {ROWS}; \ |
|
292 |
+ auto static constexpr format = GLenum{FORMAT}; \ |
|
293 |
+ auto static constexpr type = GLenum{TYPE}; \ |
|
294 |
+ auto static constexpr internal_format = GLenum{INTERNAL_FORMAT}; \ |
|
295 |
+ void static attrib(GLuint index, DATA const & value) \ |
|
296 |
+ { \ |
|
297 |
+ GLOBJECT_DEBUG_IF(1) \ |
|
298 |
+ check_supported_({V1A, V2A}); \ |
|
299 |
+ FOR_COLUMNS \ |
|
300 |
+ glVertexAttrib##ATTRIB##SUFFIX( \ |
|
301 |
+ index PLUS_COLUMN, \ |
|
302 |
+ VALUE PLUS_COLUMN_TIMES_ROWS \ |
|
303 |
+ ); \ |
|
304 |
+ } \ |
|
305 |
+ void static uniform(GLint location, DATA const & value) \ |
|
306 |
+ { \ |
|
307 |
+ GLOBJECT_DEBUG_IF(1) \ |
|
308 |
+ check_supported_({V1U, V2U}); \ |
|
309 |
+ glUniform##UNIFORM##SUFFIX( \ |
|
310 |
+ location, \ |
|
311 |
+ __VA_ARGS__ \ |
|
312 |
+ VALUE \ |
|
313 |
+ ); \ |
|
314 |
+ } \ |
|
315 |
+ }; |
|
316 |
+ |
|
317 |
+// GLOBJECT_DATA(DATA , V1A, V2A, V1U, V2U, COLUMNS, ROWS, ATTRIB, UNIFORM , SUFFIX , FORMAT, TYPE, INTERNAL_FORMAT , VALUE, FOR_COLUMNS , PLUS_COLUMN, PLUS_COLUMN_TIMES_ROWS, ... ) |
|
318 |
+#define GLOBJECT_DATA_SCALAR( DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE ) GLOBJECT_DATA(DATA , V1A, V2A, V1U, V2U, 1 , 1 , ATTRIB, , 1##SUFFIX , GL_RED, TYPE, GL_R ##INTERNAL, value, , , , ) |
|
319 |
+#define GLOBJECT_DATA_VECTOR_N( DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, FORMAT, N ) GLOBJECT_DATA(DATA##N , V1A, V2A, V1U, V2U, 1 , N , ATTRIB, , N##SUFFIX##v, FORMAT, TYPE, FORMAT##INTERNAL, VALUE, , , , 1, ) |
|
320 |
+#define GLOBJECT_DATA_MATRIX_N( DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, FORMAT, N ) GLOBJECT_DATA(DATA##N , V1A, V2A, V1U, V2U, N , N , ATTRIB, Matrix , N##SUFFIX##v, FORMAT, TYPE, FORMAT##INTERNAL, VALUE, for (auto column = GLuint{0}; column < columns; ++column), + column , + (column * rows) , 1, TRANSPOSE,) |
|
321 |
+#define GLOBJECT_DATA_MATRIX_N_M(DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, FORMAT, N, M) GLOBJECT_DATA(DATA##N##x##M, V1A, V2A, V1U, V2U, N , M , ATTRIB, Matrix##N##x, M##SUFFIX##v, FORMAT, TYPE, FORMAT##INTERNAL, VALUE, for (auto column = GLuint{0}; column < columns; ++column), + column , + (column * rows) , 1, TRANSPOSE,) |
|
322 |
+ |
|
323 |
+#define GLOBJECT_DATA_VECTOR( DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE ) \ |
|
324 |
+ GLOBJECT_DATA_VECTOR_N( DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, GL_RG, 2 ) \ |
|
325 |
+ GLOBJECT_DATA_VECTOR_N( DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, GL_RGB, 3 ) \ |
|
326 |
+ GLOBJECT_DATA_VECTOR_N( DATA, V1A, V2A, V1U, V2U, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, GL_RGBA, 4 ) |
|
327 |
+ |
|
328 |
+#define GLOBJECT_DATA_MATRIX( DATA, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE ) \ |
|
329 |
+ GLOBJECT_DATA_MATRIX_N( DATA, 2, 0, 2, 0, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RG, 2 ) \ |
|
330 |
+ GLOBJECT_DATA_MATRIX_N_M( DATA, 2, 0, 2, 1, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RGB, 2, 3) \ |
|
331 |
+ GLOBJECT_DATA_MATRIX_N_M( DATA, 2, 0, 2, 1, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RGBA, 2, 4) \ |
|
332 |
+ GLOBJECT_DATA_MATRIX_N_M( DATA, 2, 0, 2, 1, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RG, 3, 2) \ |
|
333 |
+ GLOBJECT_DATA_MATRIX_N( DATA, 2, 0, 2, 0, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RGB, 3 ) \ |
|
334 |
+ GLOBJECT_DATA_MATRIX_N_M( DATA, 2, 0, 2, 1, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RGBA, 3, 4) \ |
|
335 |
+ GLOBJECT_DATA_MATRIX_N_M( DATA, 2, 0, 2, 1, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RG, 4, 2) \ |
|
336 |
+ GLOBJECT_DATA_MATRIX_N_M( DATA, 2, 0, 2, 1, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RGB, 4, 3) \ |
|
337 |
+ GLOBJECT_DATA_MATRIX_N( DATA, 2, 0, 2, 0, ATTRIB, SUFFIX, INTERNAL, TYPE, VALUE, TRANSPOSE, GL_RGBA, 4 ) |
|
338 |
+ |
|
339 |
+GLOBJECT_DATA_SCALAR( GLfloat, 2, 0, 2, 0, , f, 32F, GL_FLOAT ) |
|
340 |
+GLOBJECT_DATA_SCALAR( GLbyte, 3, 0, 2, 0, I, i, 8I, GL_BYTE ) |
|
341 |
+GLOBJECT_DATA_SCALAR( GLshort, 3, 0, 2, 0, I, i, 16I, GL_SHORT ) |
|
342 |
+GLOBJECT_DATA_SCALAR( GLint, 3, 0, 2, 0, I, i, 32I, GL_INT ) |
|
343 |
+GLOBJECT_DATA_SCALAR( GLubyte, 3, 0, 3, 0, I, ui, 8UI, GL_UNSIGNED_BYTE ) |
|
344 |
+GLOBJECT_DATA_SCALAR( GLushort, 3, 0, 3, 0, I, ui, 16UI, GL_UNSIGNED_SHORT ) |
|
345 |
+GLOBJECT_DATA_SCALAR( GLuint, 3, 0, 3, 0, I, ui, 32UI, GL_UNSIGNED_INT ) |
|
346 |
+ |
|
347 |
+#ifdef GLM_VERSION |
|
348 |
+ #include <glm/gtc/type_ptr.hpp> |
|
349 |
+ GLOBJECT_DATA_VECTOR( glm::vec, 2, 0, 2, 0, , f, 32F, GL_FLOAT, glm::value_ptr(value) ) |
|
350 |
+ GLOBJECT_DATA_VECTOR( glm::ivec, 3, 0, 2, 0, I, i, 32I, GL_INT, glm::value_ptr(value) ) |
|
351 |
+ GLOBJECT_DATA_VECTOR( glm::uvec, 3, 0, 3, 0, I, ui, 32UI, GL_UNSIGNED_INT, glm::value_ptr(value) ) |
|
352 |
+ GLOBJECT_DATA_MATRIX( glm::mat, , f, 32F, GL_FLOAT, glm::value_ptr(value), GL_FALSE ) |
|
353 |
+#endif |
|
354 |
+ |
|
355 |
+ |
|
356 |
+#endif // GLOBJECT_HPP_ |
0 | 357 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,952 @@ |
1 |
+#include <globject.hpp> |
|
2 |
+ |
|
3 |
+#include <algorithm> |
|
4 |
+#include <array> |
|
5 |
+#include <cerrno> |
|
6 |
+#include <cstdio> |
|
7 |
+#include <cstring> |
|
8 |
+#include <fstream> |
|
9 |
+#include <iostream> |
|
10 |
+#include <iterator> |
|
11 |
+#include <sstream> |
|
12 |
+#include <string> |
|
13 |
+#include <unordered_set> |
|
14 |
+ |
|
15 |
+// NOLINTNEXTLINE |
|
16 |
+#define STR_EXCEPTION GLObject::Exception |
|
17 |
+#include <str.hpp> |
|
18 |
+ |
|
19 |
+ |
|
20 |
+/// Special member functions |
|
21 |
+ |
|
22 |
+ |
|
23 |
+GLObject::GLObject( |
|
24 |
+ GLGenObjects gl_gen_objects, |
|
25 |
+ GLDeleteObjects gl_delete_objects, |
|
26 |
+ GLenum object_type, |
|
27 |
+ // cppcheck-suppress passedByValue |
|
28 |
+ std::string object_label |
|
29 |
+) |
|
30 |
+: |
|
31 |
+ gl_delete_objects_{gl_delete_objects}, |
|
32 |
+ object_type_ {object_type}, |
|
33 |
+ object_label_ {std::move(object_label)}, |
|
34 |
+ object_ {0} |
|
35 |
+{ |
|
36 |
+ try |
|
37 |
+ { |
|
38 |
+ if (gl_gen_objects) |
|
39 |
+ gl_gen_objects(1, &object_); |
|
40 |
+ else |
|
41 |
+ object_ = object_pseudo_; |
|
42 |
+ check_error_(glGetError()); |
|
43 |
+ GLOBJECT_DEBUG_IF(1) |
|
44 |
+ { |
|
45 |
+ debug_label_(); |
|
46 |
+ debug_objects_push_back_(this); |
|
47 |
+ debug_callback()("Create " + debug_name()); |
|
48 |
+ } |
|
49 |
+ } |
|
50 |
+ catch (...) |
|
51 |
+ { |
|
52 |
+ if (gl_delete_objects_) |
|
53 |
+ gl_delete_objects_(1, &object_); |
|
54 |
+ fail_action_("create"); |
|
55 |
+ } |
|
56 |
+} |
|
57 |
+ |
|
58 |
+ |
|
59 |
+GLObject::GLObject(GLObject && other) noexcept |
|
60 |
+: |
|
61 |
+ gl_delete_objects_{other.gl_delete_objects_}, |
|
62 |
+ object_type_ {other.object_type_}, |
|
63 |
+ object_label_ {std::move(other.object_label_)}, |
|
64 |
+ object_ {other.object_} |
|
65 |
+{ |
|
66 |
+ other.object_ = 0; |
|
67 |
+ GLOBJECT_DEBUG_IF(1) |
|
68 |
+ { |
|
69 |
+ debug_objects_erase_(&other); |
|
70 |
+ debug_objects_push_back_(this); |
|
71 |
+ debug_callback()("Move " + debug_name()); |
|
72 |
+ } |
|
73 |
+} |
|
74 |
+ |
|
75 |
+ |
|
76 |
+GLObject::~GLObject() |
|
77 |
+{ |
|
78 |
+ if (gl_delete_objects_) |
|
79 |
+ gl_delete_objects_(1, &object_); |
|
80 |
+ GLOBJECT_DEBUG_IF(1) |
|
81 |
+ { |
|
82 |
+ debug_objects_erase_(this); |
|
83 |
+ debug_callback()("Destroy " + debug_name()); |
|
84 |
+ } |
|
85 |
+} |
|
86 |
+ |
|
87 |
+ |
|
88 |
+/// Core |
|
89 |
+ |
|
90 |
+ |
|
91 |
+bool GLObject::supported( |
|
92 |
+ Version version_min, |
|
93 |
+ std::string const & extension |
|
94 |
+) |
|
95 |
+{ |
|
96 |
+ auto static version = Version{0, 0}; |
|
97 |
+ auto static extensions = std::unordered_set<std::string>{}; |
|
98 |
+ if (extension.size() && extension.rfind("GL_", 0) == extension.npos) |
|
99 |
+ STR_THROW("Failed to parse extension \"" << extension << "\"."); |
|
100 |
+ if (version == Version{0, 0}) |
|
101 |
+ { |
|
102 |
+ auto const * version_str = (char const *)glGetString(GL_VERSION); |
|
103 |
+ if (!version_str) |
|
104 |
+ return false; |
|
105 |
+ // NOLINTNEXTLINE |
|
106 |
+ if (2 != std::sscanf(version_str, "%d.%d", &version[0], &version[1])) |
|
107 |
+ STR_THROW("Failed to parse version \"" << version_str << "\"."); |
|
108 |
+ if (version[0] >= 3) |
|
109 |
+ { |
|
110 |
+ auto extension_count = get_integer(GL_NUM_EXTENSIONS); |
|
111 |
+ for (auto i = 0; i < extension_count; ++i) |
|
112 |
+ extensions.insert( |
|
113 |
+ (char const *)glGetStringi(GL_EXTENSIONS, (GLuint)i) |
|
114 |
+ ); |
|
115 |
+ } |
|
116 |
+ else |
|
117 |
+ { |
|
118 |
+ auto istream = std::istringstream( |
|
119 |
+ (char const *)glGetString(GL_EXTENSIONS) |
|
120 |
+ ); |
|
121 |
+ std::copy( |
|
122 |
+ std::istream_iterator<std::string>(istream), |
|
123 |
+ std::istream_iterator<std::string>(), |
|
124 |
+ std::inserter(extensions, extensions.end()) |
|
125 |
+ ); |
|
126 |
+ } |
|
127 |
+ } |
|
128 |
+ if |
|
129 |
+ ( |
|
130 |
+ (version_min != Version{0, 0}) && |
|
131 |
+ ( |
|
132 |
+ (version[0] > version_min[0]) || |
|
133 |
+ ( |
|
134 |
+ version[0] == version_min[0] && |
|
135 |
+ version[1] >= version_min[1] |
|
136 |
+ ) |
|
137 |
+ ) |
|
138 |
+ ) |
|
139 |
+ return true; |
|
140 |
+ if |
|
141 |
+ ( |
|
142 |
+ extension.size() && |
|
143 |
+ extensions.find(extension) != extensions.end() |
|
144 |
+ ) |
|
145 |
+ return true; |
|
146 |
+ return false; |
|
147 |
+} |
|
148 |
+ |
|
149 |
+ |
|
150 |
+GLint GLObject::get_integer(GLenum name) |
|
151 |
+try |
|
152 |
+{ |
|
153 |
+ auto value = GLint{}; |
|
154 |
+ glGetIntegerv(name, &value); |
|
155 |
+ GLOBJECT_DEBUG_IF(1) |
|
156 |
+ check_error_(glGetError()); |
|
157 |
+ return value; |
|
158 |
+} |
|
159 |
+catch (...) |
|
160 |
+{ |
|
161 |
+ STR_THROW_NESTED("Failed to get integer " << str_enum_(name) << ":"); |
|
162 |
+} |
|
163 |
+ |
|
164 |
+ |
|
165 |
+/// Path |
|
166 |
+ |
|
167 |
+ |
|
168 |
+GLObject::Path GLObject::path_prefix_( |
|
169 |
+ Path const & path, |
|
170 |
+ Path const & prefix |
|
171 |
+) |
|
172 |
+{ |
|
173 |
+ if (prefix.empty() || path[0] == '/') |
|
174 |
+ return path; |
|
175 |
+ return STR(prefix << "/" << path); |
|
176 |
+} |
|
177 |
+ |
|
178 |
+ |
|
179 |
+/// TGA |
|
180 |
+ |
|
181 |
+ |
|
182 |
+GLObject::TGA::TGA(Size size, Data data) |
|
183 |
+try |
|
184 |
+: |
|
185 |
+ header_{size}, |
|
186 |
+ data_{std::move(data)} |
|
187 |
+{ |
|
188 |
+ check_data_(); |
|
189 |
+} |
|
190 |
+catch (...) |
|
191 |
+{ |
|
192 |
+ STR_THROW_NESTED("Failed to create TGA " << str_size_(size) << ":"); |
|
193 |
+} |
|
194 |
+ |
|
195 |
+ |
|
196 |
+GLObject::TGA GLObject::TGA::read(Path const & path) |
|
197 |
+try |
|
198 |
+{ |
|
199 |
+ auto tga = TGA({}, {}); |
|
200 |
+ auto istream = std::ifstream(path, std::ios::binary); |
|
201 |
+ istream.read( |
|
202 |
+ (char *) tga.header_.data(), |
|
203 |
+ (std::streamsize)tga.header_.size() |
|
204 |
+ ); |
|
205 |
+ tga.check_header_(); |
|
206 |
+ tga.data_.resize((std::size_t)(4 * tga.size()[0] * tga.size()[1])); |
|
207 |
+ istream.read( |
|
208 |
+ (char *) tga.data_.data(), |
|
209 |
+ (std::streamsize)tga.data_.size() |
|
210 |
+ ); |
|
211 |
+ istream.close(); |
|
212 |
+ if (!istream) |
|
213 |
+ // NOLINTNEXTLINE |
|
214 |
+ STR_THROW(std::strerror(errno)); |
|
215 |
+ return tga; |
|
216 |
+} |
|
217 |
+catch (...) |
|
218 |
+{ |
|
219 |
+ STR_THROW_NESTED("Failed to read TGA " << str_path_(path) << ":"); |
|
220 |
+} |
|
221 |
+ |
|
222 |
+ |
|
223 |
+void GLObject::TGA::write(Path const & path) const |
|
224 |
+try |
|
225 |
+{ |
|
226 |
+ check_data_(); |
|
227 |
+ auto ostream = std::ofstream(path, std::ios::binary); |
|
228 |
+ ostream.write((char *)header_.data(), (std::streamsize)header_.size()); |
|
229 |
+ ostream.write((char *)data_ .data(), (std::streamsize)data_ .size()); |
|
230 |
+ ostream.close(); |
|
231 |
+ if (!ostream) |
|
232 |
+ // NOLINTNEXTLINE |
|
233 |
+ STR_THROW(std::strerror(errno)); |
|
234 |
+} |
|
235 |
+catch (...) |
|
236 |
+{ |
|
237 |
+ STR_THROW_NESTED("Failed to write TGA " << str_path_(path) << ":"); |
|
238 |
+} |
|
239 |
+ |
|
240 |
+ |
|
241 |
+GLObject::TGA::Data const & GLObject::TGA::data() |
|
242 |
+{ |
|
243 |
+ return data_; |
|
244 |
+} |
|
245 |
+ |
|
246 |
+ |
|
247 |
+GLObject::TGA::Size GLObject::TGA::size() const |
|
248 |
+{ |
|
249 |
+ return { |
|
250 |
+ (GLsizei)(header_[12]) << 0 | // NOLINT |
|
251 |
+ (GLsizei)(header_[13]) << 8, // NOLINT |
|
252 |
+ (GLsizei)(header_[14]) << 0 | // NOLINT |
|
253 |
+ (GLsizei)(header_[15]) << 8, // NOLINT |
|
254 |
+ }; |
|
255 |
+} |
|
256 |
+ |
|
257 |
+ |
|
258 |
+GLObject::TGA::Header::Header(Size size) |
|
259 |
+: |
|
260 |
+ std::array<GLubyte, 18>{ // NOLINT |
|
261 |
+ 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, // NOLINT |
|
262 |
+ (GLubyte)(size[0] >> 0), // NOLINT |
|
263 |
+ (GLubyte)(size[0] >> 8), // NOLINT |
|
264 |
+ (GLubyte)(size[1] >> 0), // NOLINT |
|
265 |
+ (GLubyte)(size[1] >> 8), // NOLINT |
|
266 |
+ 32, 8, // NOLINT |
|
267 |
+ } |
|
268 |
+{ |
|
269 |
+} |
|
270 |
+ |
|
271 |
+ |
|
272 |
+std::string GLObject::TGA::str_size_(Size size) |
|
273 |
+{ |
|
274 |
+ return STR("{" << STR_JOIN(", ", it, it, size) << "}"); |
|
275 |
+} |
|
276 |
+ |
|
277 |
+ |
|
278 |
+void GLObject::TGA::check_header_() const |
|
279 |
+{ |
|
280 |
+ auto header = Header(size()); |
|
281 |
+ if (header_ != header) |
|
282 |
+ STR_THROW( |
|
283 |
+ "Expected TGA header" << " " << |
|
284 |
+ "[" << STR_JOIN(", ", byte, byte, header) << "]" << ", " << |
|
285 |
+ "got" << " " << |
|
286 |
+ "[" << STR_JOIN(", ", byte, byte, header_) << "]" << "." |
|
287 |
+ ); |
|
288 |
+} |
|
289 |
+ |
|
290 |
+ |
|
291 |
+void GLObject::TGA::check_data_() const |
|
292 |
+{ |
|
293 |
+ auto data_size = (std::size_t)(4 * size()[0] * size()[1]); |
|
294 |
+ if (data_size != data_.size()) |
|
295 |
+ STR_THROW( |
|
296 |
+ "Expected TGA data size " << data_size << ", " << |
|
297 |
+ "got " << data_.size() << "." |
|
298 |
+ ); |
|
299 |
+} |
|
300 |
+ |
|
301 |
+ |
|
302 |
+/// Debug |
|
303 |
+ |
|
304 |
+ |
|
305 |
+GLOBJECT_THREAD(GLObject::debug_, {1}) |
|
306 |
+GLOBJECT_THREAD(GLObject::debug_objects_, {}) |
|
307 |
+GLOBJECT_THREAD(GLObject::debug_callback_, {[](std::string const & debug) |
|
308 |
+{ |
|
309 |
+ std::cerr << debug << std::endl; |
|
310 |
+}}) |
|
311 |
+ |
|
312 |
+ |
|
313 |
+std::string GLObject::debug_name() const |
|
314 |
+{ |
|
315 |
+ return STR_JOIN(" ", it, it, { |
|
316 |
+ object_type_ == 0 ? "<GLObject>" : |
|
317 |
+ str_object_type_(object_type_), |
|
318 |
+ object_label_, |
|
319 |
+ object_ == 0 ? "<INVALID>" : |
|
320 |
+ object_ == object_pseudo_ ? "<PSEUDO>" : |
|
321 |
+ STR(object_), |
|
322 |
+ }); |
|
323 |
+} |
|
324 |
+ |
|
325 |
+ |
|
326 |
+void GLObject::debug_label_() const |
|
327 |
+{ |
|
328 |
+ if |
|
329 |
+ ( |
|
330 |
+ object_type_ && |
|
331 |
+ object_label_.size() && |
|
332 |
+ object_ |
|
333 |
+ ) |
|
334 |
+ { |
|
335 |
+ if (supported({4, 3}, "GL_KHR_debug")) |
|
336 |
+ { |
|
337 |
+ auto static object_label_length_max = get_integer( |
|
338 |
+ GL_MAX_LABEL_LENGTH |
|
339 |
+ ); |
|
340 |
+ auto object_label_length = std::min( |
|
341 |
+ (GLsizei)object_label_length_max, |
|
342 |
+ (GLsizei)object_label_.length() |
|
343 |
+ ); |
|
344 |
+ glObjectLabel( |
|
345 |
+ object_type_, |
|
346 |
+ object_, |
|
347 |
+ object_label_length, |
|
348 |
+ object_label_.c_str() |
|
349 |
+ ); |
|
350 |
+ } |
|
351 |
+ } |
|
352 |
+} |
|
353 |
+ |
|
354 |
+ |
|
355 |
+std::string static debug_objects_data_( |
|
356 |
+ std::string (GLObject::*debug_data)() const |
|
357 |
+) |
|
358 |
+{ |
|
359 |
+ auto const & objects = GLObject::debug_objects(); |
|
360 |
+ auto header = STR("GLObjects: " << objects.size()); |
|
361 |
+ auto data = STR_JOIN( |
|
362 |
+ "\n", |
|
363 |
+ object, |
|
364 |
+ " " << (object->*debug_data)(), |
|
365 |
+ objects |
|
366 |
+ ); |
|
367 |
+ return STR_JOIN("\n", it, it, {header, data}); |
|
368 |
+} |
|
369 |
+ |
|
370 |
+ |
|
371 |
+std::string GLObject::debug_objects_name() |
|
372 |
+{ |
|
373 |
+ return debug_objects_data_(&GLObject::debug_name); |
|
374 |
+} |
|
375 |
+ |
|
376 |
+ |
|
377 |
+std::string GLObject::debug_objects_info() |
|
378 |
+{ |
|
379 |
+ return debug_objects_data_(&GLObject::debug_info); |
|
380 |
+} |
|
381 |
+ |
|
382 |
+ |
|
383 |
+std::string GLObject::debug_info() const |
|
384 |
+{ |
|
385 |
+ return debug_name(); |
|
386 |
+} |
|
387 |
+ |
|
388 |
+ |
|
389 |
+void GLObject::debug_objects_push_back_(GLObject * debug_object) |
|
390 |
+{ |
|
391 |
+ debug_objects_.push_back(debug_object); |
|
392 |
+} |
|
393 |
+ |
|
394 |
+ |
|
395 |
+void GLObject::debug_objects_erase_(GLObject * debug_object) |
|
396 |
+{ |
|
397 |
+ debug_objects_.erase( |
|
398 |
+ std::remove( |
|
399 |
+ debug_objects_.begin(), |
|
400 |
+ debug_objects_.end(), |
|
401 |
+ debug_object |
|
402 |
+ ), |
|
403 |
+ debug_objects_.end() |
|
404 |
+ ); |
|
405 |
+} |
|
406 |
+ |
|
407 |
+ |
|
408 |
+/// Check |
|
409 |
+ |
|
410 |
+ |
|
411 |
+void GLObject::check_path_(std::string const & path) |
|
412 |
+{ |
|
413 |
+ if (!path.size()) |
|
414 |
+ STR_THROW( |
|
415 |
+ "Expected " << "non-empty path" << ", " << |
|
416 |
+ "got " << "\"" << path << "\"" << "." |
|
417 |
+ ); |
|
418 |
+} |
|
419 |
+ |
|
420 |
+ |
|
421 |
+void GLObject::check_error_(GLenum error) |
|
422 |
+{ |
|
423 |
+ if (error != GL_NO_ERROR) |
|
424 |
+ STR_THROW( |
|
425 |
+ "Expected " << "no error" << ", " << |
|
426 |
+ "got " << str_error_(error) << "." |
|
427 |
+ ); |
|
428 |
+} |
|
429 |
+ |
|
430 |
+ |
|
431 |
+void GLObject::check_supported_( |
|
432 |
+ Version version_min, |
|
433 |
+ std::string const & extension |
|
434 |
+) |
|
435 |
+{ |
|
436 |
+ if (!supported(version_min, extension)) |
|
437 |
+ STR_THROW( |
|
438 |
+ "Expected GL version " << |
|
439 |
+ STR_JOIN(".", it, it, version_min) << |
|
440 |
+ (extension.size() ? STR(" or extension " << extension) : "") << " " |
|
441 |
+ "got " << glGetString(GL_VERSION) << "." |
|
442 |
+ ); |
|
443 |
+} |
|
444 |
+ |
|
445 |
+ |
|
446 |
+void GLObject::check_format_( |
|
447 |
+ GLenum format, |
|
448 |
+ GLenum format_expected |
|
449 |
+) |
|
450 |
+{ |
|
451 |
+ if (format != format_expected) |
|
452 |
+ STR_THROW( |
|
453 |
+ "Expected format " << str_format_(format_expected) << ", " << |
|
454 |
+ "got " << str_format_(format) << "." |
|
455 |
+ ); |
|
456 |
+} |
|
457 |
+ |
|
458 |
+ |
|
459 |
+void GLObject::check_type_( |
|
460 |
+ GLenum type, |
|
461 |
+ GLenum type_expected |
|
462 |
+) |
|
463 |
+{ |
|
464 |
+ if (type != type_expected) |
|
465 |
+ STR_THROW( |
|
466 |
+ "Expected type " << str_type_(type_expected) << ", " << |
|
467 |
+ "got " << str_type_(type) << "." |
|
468 |
+ ); |
|
469 |
+} |
|
470 |
+ |
|
471 |
+ |
|
472 |
+void GLObject::check_internal_format_(GLenum internal_format) |
|
473 |
+{ |
|
474 |
+ switch (internal_format) |
|
475 |
+ { |
|
476 |
+ case GL_RED: |
|
477 |
+ case GL_RGB: |
|
478 |
+ case GL_RGBA: |
|
479 |
+ case GL_DEPTH_COMPONENT: |
|
480 |
+ case GL_STENCIL_INDEX: |
|
481 |
+ case GL_R3_G3_B2: |
|
482 |
+ check_supported_({1, 0}); |
|
483 |
+ return; |
|
484 |
+ case GL_RGB4: |
|
485 |
+ case GL_RGB5: |
|
486 |
+ case GL_RGB8: |
|
487 |
+ case GL_RGB10: |
|
488 |
+ case GL_RGB12: |
|
489 |
+ case GL_RGB16: |
|
490 |
+ case GL_RGBA2: |
|
491 |
+ case GL_RGBA4: |
|
492 |
+ case GL_RGBA8: |
|
493 |
+ case GL_RGBA12: |
|
494 |
+ case GL_RGBA16: |
|
495 |
+ case GL_RGB5_A1: |
|
496 |
+ case GL_RGB10_A2: |
|
497 |
+ check_supported_({1, 1}, "GL_EXT_texture"); |
|
498 |
+ return; |
|
499 |
+ case GL_COMPRESSED_RGB: |
|
500 |
+ case GL_COMPRESSED_RGBA: |
|
501 |
+ check_supported_({1, 3}, "GL_ARB_texture_compression"); |
|
502 |
+ return; |
|
503 |
+ case GL_DEPTH_COMPONENT16: |
|
504 |
+ case GL_DEPTH_COMPONENT24: |
|
505 |
+ case GL_DEPTH_COMPONENT32: |
|
506 |
+ check_supported_({1, 4}, "GL_ARB_depth_texture"); |
|
507 |
+ return; |
|
508 |
+ case GL_SRGB: |
|
509 |
+ case GL_SRGB8: |
|
510 |
+ case GL_SRGB_ALPHA: |
|
511 |
+ case GL_SRGB8_ALPHA8: |
|
512 |
+ case GL_COMPRESSED_SRGB: |
|
513 |
+ case GL_COMPRESSED_SRGB_ALPHA: |
|
514 |
+ check_supported_({2, 1}, "GL_EXT_texture_sRGB"); |
|
515 |
+ return; |
|
516 |
+ case GL_SR8_EXT: |
|
517 |
+ check_supported_({}, "GL_EXT_texture_sRGB_R8"); |
|
518 |
+ return; |
|
519 |
+ case GL_SRG8_EXT: |
|
520 |
+ check_supported_({}, "GL_EXT_texture_sRGB_RG8"); |
|
521 |
+ return; |
|
522 |
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: |
|
523 |
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: |
|
524 |
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: |
|
525 |
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: |
|
526 |
+ check_supported_({}, "GL_EXT_texture_compression_s3tc"); |
|
527 |
+ return; |
|
528 |
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: |
|
529 |
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: |
|
530 |
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: |
|
531 |
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: |
|
532 |
+ check_supported_({}, "GL_EXT_texture_sRGB"); |
|
533 |
+ check_supported_({}, "GL_EXT_texture_compression_s3tc"); |
|
534 |
+ return; |
|
535 |
+ case GL_COMPRESSED_RED: |
|
536 |
+ case GL_COMPRESSED_RG: |
|
537 |
+ check_supported_({3, 0}); |
|
538 |
+ return; |
|
539 |
+ case GL_COMPRESSED_RED_RGTC1: |
|
540 |
+ case GL_COMPRESSED_SIGNED_RED_RGTC1: |
|
541 |
+ case GL_COMPRESSED_RG_RGTC2: |
|
542 |
+ case GL_COMPRESSED_SIGNED_RG_RGTC2: |
|
543 |
+ check_supported_({3, 0}, "GL_ARB_texture_compression_rgtc"); |
|
544 |
+ return; |
|
545 |
+ case GL_RGB16F: |
|
546 |
+ case GL_RGB32F: |
|
547 |
+ case GL_RGBA16F: |
|
548 |
+ case GL_RGBA32F: |
|
549 |
+ check_supported_({3, 0}, "GL_ARB_texture_float"); |
|
550 |
+ return; |
|
551 |
+ case GL_RGB8I: |
|
552 |
+ case GL_RGB16I: |
|
553 |
+ case GL_RGB32I: |
|
554 |
+ case GL_RGB8UI: |
|
555 |
+ case GL_RGB16UI: |
|
556 |
+ case GL_RGB32UI: |
|
557 |
+ case GL_RGBA8I: |
|
558 |
+ case GL_RGBA16I: |
|
559 |
+ case GL_RGBA32I: |
|
560 |
+ case GL_RGBA8UI: |
|
561 |
+ case GL_RGBA16UI: |
|
562 |
+ case GL_RGBA32UI: |
|
563 |
+ check_supported_({3, 0}, "GL_EXT_texture_integer"); |
|
564 |
+ return; |
|
565 |
+ case GL_R16F: |
|
566 |
+ case GL_R32F: |
|
567 |
+ case GL_RG16F: |
|
568 |
+ case GL_RG32F: |
|
569 |
+ case GL_R8: |
|
570 |
+ case GL_R8I: |
|
571 |
+ case GL_R8UI: |
|
572 |
+ case GL_R16: |
|
573 |
+ case GL_R16I: |
|
574 |
+ case GL_R16UI: |
|
575 |
+ case GL_R32I: |
|
576 |
+ case GL_R32UI: |
|
577 |
+ case GL_RG: |
|
578 |
+ case GL_RG8: |
|
579 |
+ case GL_RG8I: |
|
580 |
+ case GL_RG8UI: |
|
581 |
+ case GL_RG16: |
|
582 |
+ case GL_RG16I: |
|
583 |
+ case GL_RG16UI: |
|
584 |
+ case GL_RG32I: |
|
585 |
+ case GL_RG32UI: |
|
586 |
+ check_supported_({3, 0}, "GL_ARB_texture_rg"); |
|
587 |
+ return; |
|
588 |
+ case GL_R11F_G11F_B10F: |
|
589 |
+ check_supported_({3, 0}, "GL_EXT_packed_float"); |
|
590 |
+ return; |
|
591 |
+ case GL_RGB9_E5: |
|
592 |
+ check_supported_({3, 0}, "GL_EXT_texture_shared_exponent"); |
|
593 |
+ return; |
|
594 |
+ case GL_DEPTH_STENCIL: |
|
595 |
+ case GL_DEPTH24_STENCIL8: |
|
596 |
+ check_supported_({3, 0}, "GL_EXT_packed_depth_stencil"); |
|
597 |
+ return; |
|
598 |
+ case GL_DEPTH32F_STENCIL8: |
|
599 |
+ case GL_DEPTH_COMPONENT32F: |
|
600 |
+ check_supported_({3, 0}, "GL_ARB_depth_buffer_float"); |
|
601 |
+ return; |
|
602 |
+ case GL_STENCIL_INDEX8: |
|
603 |
+ check_supported_({3, 0}, "GL_ARB_texture_stencil8"); |
|
604 |
+ return; |
|
605 |
+ case GL_STENCIL_INDEX1: |
|
606 |
+ case GL_STENCIL_INDEX4: |
|
607 |
+ case GL_STENCIL_INDEX16: |
|
608 |
+ check_supported_({3, 0}, "GL_ARB_framebuffer_object"); |
|
609 |
+ return; |
|
610 |
+ case GL_R8_SNORM: |
|
611 |
+ case GL_R16_SNORM: |
|
612 |
+ case GL_RG8_SNORM: |
|
613 |
+ case GL_RG16_SNORM: |
|
614 |
+ case GL_RGB8_SNORM: |
|
615 |
+ case GL_RGB16_SNORM: |
|
616 |
+ case GL_RGBA8_SNORM: |
|
617 |
+ case GL_RGBA16_SNORM: |
|
618 |
+ check_supported_({3, 1}, "GL_EXT_texture_snorm"); |
|
619 |
+ return; |
|
620 |
+ case GL_RGB10_A2UI: |
|
621 |
+ check_supported_({3, 3}, "GL_ARB_texture_rgb10_a2ui"); |
|
622 |
+ return; |
|
623 |
+ case GL_RGB565: |
|
624 |
+ check_supported_({4, 1}, "GL_ARB_ES2_compatibility"); |
|
625 |
+ return; |
|
626 |
+ case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: |
|
627 |
+ case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: |
|
628 |
+ case GL_COMPRESSED_RGBA_BPTC_UNORM: |
|
629 |
+ case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: |
|
630 |
+ check_supported_({4, 2}, "GL_ARB_texture_compression_bptc"); |
|
631 |
+ return; |
|
632 |
+ case GL_COMPRESSED_R11_EAC: |
|
633 |
+ case GL_COMPRESSED_RG11_EAC: |
|
634 |
+ case GL_COMPRESSED_SIGNED_R11_EAC: |
|
635 |
+ case GL_COMPRESSED_SIGNED_RG11_EAC: |
|
636 |
+ case GL_COMPRESSED_RGB8_ETC2: |
|
637 |
+ case GL_COMPRESSED_SRGB8_ETC2: |
|
638 |
+ case GL_COMPRESSED_RGBA8_ETC2_EAC: |
|
639 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: |
|
640 |
+ case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
|
641 |
+ case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: |
|
642 |
+ check_supported_({4, 2}, "GL_ARB_ES3_compatibility"); |
|
643 |
+ return; |
|
644 |
+ case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: |
|
645 |
+ case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: |
|
646 |
+ case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: |
|
647 |
+ case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: |
|
648 |
+ case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: |
|
649 |
+ case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: |
|
650 |
+ case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: |
|
651 |
+ case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: |
|
652 |
+ case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: |
|
653 |
+ case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: |
|
654 |
+ case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: |
|
655 |
+ case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: |
|
656 |
+ case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: |
|
657 |
+ case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: |
|
658 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: |
|
659 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: |
|
660 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: |
|
661 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: |
|
662 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: |
|
663 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: |
|
664 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: |
|
665 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: |
|
666 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: |
|
667 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: |
|
668 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: |
|
669 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: |
|
670 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: |
|
671 |
+ case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: |
|
672 |
+ check_supported_({4, 2}, "GL_KHR_texture_compression_astc_ldr"); |
|
673 |
+ return; |
|
674 |
+ default: |
|
675 |
+ STR_THROW( |
|
676 |
+ "Expected " << "supported internal format" << ", " |
|
677 |
+ "got " << str_internal_format_(internal_format) << "." |
|
678 |
+ ); |
|
679 |
+ } |
|
680 |
+} |
|
681 |
+ |
|
682 |
+ |
|
683 |
+/// Fail |
|
684 |
+ |
|
685 |
+ |
|
686 |
+void GLObject::fail_action_(std::string const & action) const |
|
687 |
+{ |
|
688 |
+ STR_THROW_NESTED("Failed to " << action << " " << debug_name() << ":"); |
|
689 |
+} |
|
690 |
+ |
|
691 |
+ |
|
692 |
+/// String |
|
693 |
+ |
|
694 |
+ |
|
695 |
+std::string GLObject::str_path_(Path const & path) |
|
696 |
+{ |
|
697 |
+ return STR("\"" << path << "\""); |
|
698 |
+} |
|
699 |
+ |
|
700 |
+ |
|
701 |
+std::string GLObject::str_paths_(Paths const & paths) |
|
702 |
+{ |
|
703 |
+ return STR_JOIN(", ", path, str_path_(path), paths); |
|
704 |
+} |
|
705 |
+ |
|
706 |
+ |
|
707 |
+std::string GLObject::str_enum_(GLenum name) |
|
708 |
+{ |
|
709 |
+ return STR(std::hex << std::showbase << name); |
|
710 |
+} |
|
711 |
+ |
|
712 |
+ |
|
713 |
+std::string GLObject::str_error_(GLenum error) |
|
714 |
+{ |
|
715 |
+ switch (error) |
|
716 |
+ { |
|
717 |
+ STR_CASE(GL_NO_ERROR) |
|
718 |
+ STR_CASE(GL_INVALID_ENUM) |
|
719 |
+ STR_CASE(GL_INVALID_VALUE) |
|
720 |
+ STR_CASE(GL_INVALID_OPERATION) |
|
721 |
+ STR_CASE(GL_INVALID_FRAMEBUFFER_OPERATION) |
|
722 |
+ STR_CASE(GL_OUT_OF_MEMORY) |
|
723 |
+ STR_CASE(GL_STACK_UNDERFLOW) |
|
724 |
+ STR_CASE(GL_STACK_OVERFLOW) |
|
725 |
+ default: |
|
726 |
+ return str_enum_(error); |
|
727 |
+ } |
|
728 |
+} |
|
729 |
+ |
|
730 |
+ |
|
731 |
+std::string GLObject::str_object_type_(GLenum object_type) |
|
732 |
+{ |
|
733 |
+ switch (object_type) |
|
734 |
+ { |
|
735 |
+ STR_CASE(GL_BUFFER) |
|
736 |
+ STR_CASE(GL_SHADER) |
|
737 |
+ STR_CASE(GL_PROGRAM) |
|
738 |
+ STR_CASE(GL_VERTEX_ARRAY) |
|
739 |
+ STR_CASE(GL_QUERY) |
|
740 |
+ STR_CASE(GL_PROGRAM_PIPELINE) |
|
741 |
+ STR_CASE(GL_TRANSFORM_FEEDBACK) |
|
742 |
+ STR_CASE(GL_SAMPLER) |
|
743 |
+ STR_CASE(GL_TEXTURE) |
|
744 |
+ STR_CASE(GL_RENDERBUFFER) |
|
745 |
+ STR_CASE(GL_FRAMEBUFFER) |
|
746 |
+ default: |
|
747 |
+ return str_enum_(object_type); |
|
748 |
+ } |
|
749 |
+} |
|
750 |
+ |
|
751 |
+ |
|
752 |
+std::string GLObject::str_format_(GLenum format) |
|
753 |
+{ |
|
754 |
+ switch (format) |
|
755 |
+ { |
|
756 |
+ STR_CASE(GL_RED) |
|
757 |
+ STR_CASE(GL_R) |
|
758 |
+ STR_CASE(GL_RG) |
|
759 |
+ STR_CASE(GL_RGB) |
|
760 |
+ STR_CASE(GL_RGBA) |
|
761 |
+ STR_CASE(GL_BGR) |
|
762 |
+ STR_CASE(GL_BGRA) |
|
763 |
+ STR_CASE(GL_DEPTH_COMPONENT) |
|
764 |
+ STR_CASE(GL_STENCIL_INDEX) |
|
765 |
+ default: |
|
766 |
+ return str_enum_(format); |
|
767 |
+ } |
|
768 |
+} |
|
769 |
+ |
|
770 |
+ |
|
771 |
+std::string GLObject::str_type_(GLenum type) |
|
772 |
+{ |
|
773 |
+ switch (type) |
|
774 |
+ { |
|
775 |
+ STR_CASE(GL_FLOAT) |
|
776 |
+ STR_CASE(GL_BYTE) |
|
777 |
+ STR_CASE(GL_SHORT) |
|
778 |
+ STR_CASE(GL_INT) |
|
779 |
+ STR_CASE(GL_UNSIGNED_BYTE) |
|
780 |
+ STR_CASE(GL_UNSIGNED_SHORT) |
|
781 |
+ STR_CASE(GL_UNSIGNED_INT) |
|
782 |
+ STR_CASE(GL_UNSIGNED_BYTE_3_3_2) |
|
783 |
+ STR_CASE(GL_UNSIGNED_BYTE_2_3_3_REV) |
|
784 |
+ STR_CASE(GL_UNSIGNED_SHORT_5_6_5) |
|
785 |
+ STR_CASE(GL_UNSIGNED_SHORT_5_6_5_REV) |
|
786 |
+ STR_CASE(GL_UNSIGNED_SHORT_4_4_4_4) |
|
787 |
+ STR_CASE(GL_UNSIGNED_SHORT_4_4_4_4_REV) |
|
788 |
+ STR_CASE(GL_UNSIGNED_SHORT_5_5_5_1) |
|
789 |
+ STR_CASE(GL_UNSIGNED_SHORT_1_5_5_5_REV) |
|
790 |
+ STR_CASE(GL_UNSIGNED_INT_8_8_8_8) |
|
791 |
+ STR_CASE(GL_UNSIGNED_INT_8_8_8_8_REV) |
|
792 |
+ STR_CASE(GL_UNSIGNED_INT_10_10_10_2) |
|
793 |
+ STR_CASE(GL_UNSIGNED_INT_2_10_10_10_REV) |
|
794 |
+ default: |
|
795 |
+ return str_enum_(type); |
|
796 |
+ } |
|
797 |
+} |
|
798 |
+ |
|
799 |
+ |
|
800 |
+std::string GLObject::str_internal_format_(GLenum internal_format) |
|
801 |
+{ |
|
802 |
+ switch (internal_format) |
|
803 |
+ { |
|
804 |
+ STR_CASE(GL_RED) |
|
805 |
+ STR_CASE(GL_RGB) |
|
806 |
+ STR_CASE(GL_RGBA) |
|
807 |
+ STR_CASE(GL_DEPTH_COMPONENT) |
|
808 |
+ STR_CASE(GL_STENCIL_INDEX) |
|
809 |
+ STR_CASE(GL_R3_G3_B2) |
|
810 |
+ STR_CASE(GL_RGB4) |
|
811 |
+ STR_CASE(GL_RGB5) |
|
812 |
+ STR_CASE(GL_RGB8) |
|
813 |
+ STR_CASE(GL_RGB10) |
|
814 |
+ STR_CASE(GL_RGB12) |
|
815 |
+ STR_CASE(GL_RGB16) |
|
816 |
+ STR_CASE(GL_RGBA2) |
|
817 |
+ STR_CASE(GL_RGBA4) |
|
818 |
+ STR_CASE(GL_RGBA8) |
|
819 |
+ STR_CASE(GL_RGBA12) |
|
820 |
+ STR_CASE(GL_RGBA16) |
|
821 |
+ STR_CASE(GL_RGB5_A1) |
|
822 |
+ STR_CASE(GL_RGB10_A2) |
|
823 |
+ STR_CASE(GL_COMPRESSED_RGB) |
|
824 |
+ STR_CASE(GL_COMPRESSED_RGBA) |
|
825 |
+ STR_CASE(GL_DEPTH_COMPONENT16) |
|
826 |
+ STR_CASE(GL_DEPTH_COMPONENT24) |
|
827 |
+ STR_CASE(GL_DEPTH_COMPONENT32) |
|
828 |
+ STR_CASE(GL_SRGB) |
|
829 |
+ STR_CASE(GL_SRGB8) |
|
830 |
+ STR_CASE(GL_SRGB_ALPHA) |
|
831 |
+ STR_CASE(GL_SRGB8_ALPHA8) |
|
832 |
+ STR_CASE(GL_COMPRESSED_SRGB) |
|
833 |
+ STR_CASE(GL_COMPRESSED_SRGB_ALPHA) |
|
834 |
+ STR_CASE(GL_SR8_EXT) |
|
835 |
+ STR_CASE(GL_SRG8_EXT) |
|
836 |
+ STR_CASE(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) |
|
837 |
+ STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) |
|
838 |
+ STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) |
|
839 |
+ STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) |
|
840 |
+ STR_CASE(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) |
|
841 |
+ STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) |
|
842 |
+ STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT) |
|
843 |
+ STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) |
|
844 |
+ STR_CASE(GL_COMPRESSED_RED) |
|
845 |
+ STR_CASE(GL_COMPRESSED_RG) |
|
846 |
+ STR_CASE(GL_COMPRESSED_RED_RGTC1) |
|
847 |
+ STR_CASE(GL_COMPRESSED_SIGNED_RED_RGTC1) |
|
848 |
+ STR_CASE(GL_COMPRESSED_RG_RGTC2) |
|
849 |
+ STR_CASE(GL_COMPRESSED_SIGNED_RG_RGTC2) |
|
850 |
+ STR_CASE(GL_RGB16F) |
|
851 |
+ STR_CASE(GL_RGB32F) |
|
852 |
+ STR_CASE(GL_RGBA16F) |
|
853 |
+ STR_CASE(GL_RGBA32F) |
|
854 |
+ STR_CASE(GL_RGB8I) |
|
855 |
+ STR_CASE(GL_RGB16I) |
|
856 |
+ STR_CASE(GL_RGB32I) |
|
857 |
+ STR_CASE(GL_RGB8UI) |
|
858 |
+ STR_CASE(GL_RGB16UI) |
|
859 |
+ STR_CASE(GL_RGB32UI) |
|
860 |
+ STR_CASE(GL_RGBA8I) |
|
861 |
+ STR_CASE(GL_RGBA16I) |
|
862 |
+ STR_CASE(GL_RGBA32I) |
|
863 |
+ STR_CASE(GL_RGBA8UI) |
|
864 |
+ STR_CASE(GL_RGBA16UI) |
|
865 |
+ STR_CASE(GL_RGBA32UI) |
|
866 |
+ STR_CASE(GL_R16F) |
|
867 |
+ STR_CASE(GL_R32F) |
|
868 |
+ STR_CASE(GL_RG16F) |
|
869 |
+ STR_CASE(GL_RG32F) |
|
870 |
+ STR_CASE(GL_R8) |
|
871 |
+ STR_CASE(GL_R8I) |
|
872 |
+ STR_CASE(GL_R8UI) |
|
873 |
+ STR_CASE(GL_R16) |
|
874 |
+ STR_CASE(GL_R16I) |
|
875 |
+ STR_CASE(GL_R16UI) |
|
876 |
+ STR_CASE(GL_R32I) |
|
877 |
+ STR_CASE(GL_R32UI) |
|
878 |
+ STR_CASE(GL_RG) |
|
879 |
+ STR_CASE(GL_RG8) |
|
880 |
+ STR_CASE(GL_RG8I) |
|
881 |
+ STR_CASE(GL_RG8UI) |
|
882 |
+ STR_CASE(GL_RG16) |
|
883 |
+ STR_CASE(GL_RG16I) |
|
884 |
+ STR_CASE(GL_RG16UI) |
|
885 |
+ STR_CASE(GL_RG32I) |
|
886 |
+ STR_CASE(GL_RG32UI) |
|
887 |
+ STR_CASE(GL_R11F_G11F_B10F) |
|
888 |
+ STR_CASE(GL_RGB9_E5) |
|
889 |
+ STR_CASE(GL_DEPTH_STENCIL) |
|
890 |
+ STR_CASE(GL_DEPTH24_STENCIL8) |
|
891 |
+ STR_CASE(GL_DEPTH32F_STENCIL8) |
|
892 |
+ STR_CASE(GL_DEPTH_COMPONENT32F) |
|
893 |
+ STR_CASE(GL_STENCIL_INDEX8) |
|
894 |
+ STR_CASE(GL_STENCIL_INDEX1) |
|
895 |
+ STR_CASE(GL_STENCIL_INDEX4) |
|
896 |
+ STR_CASE(GL_STENCIL_INDEX16) |
|
897 |
+ STR_CASE(GL_R8_SNORM) |
|
898 |
+ STR_CASE(GL_R16_SNORM) |
|
899 |
+ STR_CASE(GL_RG8_SNORM) |
|
900 |
+ STR_CASE(GL_RG16_SNORM) |
|
901 |
+ STR_CASE(GL_RGB8_SNORM) |
|
902 |
+ STR_CASE(GL_RGB16_SNORM) |
|
903 |
+ STR_CASE(GL_RGBA8_SNORM) |
|
904 |
+ STR_CASE(GL_RGBA16_SNORM) |
|
905 |
+ STR_CASE(GL_RGB10_A2UI) |
|
906 |
+ STR_CASE(GL_RGB565) |
|
907 |
+ STR_CASE(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) |
|
908 |
+ STR_CASE(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) |
|
909 |
+ STR_CASE(GL_COMPRESSED_RGBA_BPTC_UNORM) |
|
910 |
+ STR_CASE(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) |
|
911 |
+ STR_CASE(GL_COMPRESSED_R11_EAC) |
|
912 |
+ STR_CASE(GL_COMPRESSED_RG11_EAC) |
|
913 |
+ STR_CASE(GL_COMPRESSED_SIGNED_R11_EAC) |
|
914 |
+ STR_CASE(GL_COMPRESSED_SIGNED_RG11_EAC) |
|
915 |
+ STR_CASE(GL_COMPRESSED_RGB8_ETC2) |
|
916 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ETC2) |
|
917 |
+ STR_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC) |
|
918 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) |
|
919 |
+ STR_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) |
|
920 |
+ STR_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) |
|
921 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_4x4_KHR) |
|
922 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_5x4_KHR) |
|
923 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_5x5_KHR) |
|
924 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_6x5_KHR) |
|
925 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_6x6_KHR) |
|
926 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x5_KHR) |
|
927 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x6_KHR) |
|
928 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x8_KHR) |
|
929 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x5_KHR) |
|
930 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x6_KHR) |
|
931 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x8_KHR) |
|
932 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x10_KHR) |
|
933 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_12x10_KHR) |
|
934 |
+ STR_CASE(GL_COMPRESSED_RGBA_ASTC_12x12_KHR) |
|
935 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) |
|
936 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) |
|
937 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) |
|
938 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) |
|
939 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) |
|
940 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) |
|
941 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) |
|
942 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) |
|
943 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) |
|
944 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) |
|
945 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) |
|
946 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) |
|
947 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) |
|
948 |
+ STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) |
|
949 |
+ default: |
|
950 |
+ return str_enum_(internal_format); |
|
951 |
+ } |
|
952 |
+} |
0 | 953 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,76 @@ |
1 |
+#include <iostream> |
|
2 |
+#include <string> |
|
3 |
+#include <utility> |
|
4 |
+ |
|
5 |
+#include <glm/glm.hpp> |
|
6 |
+ |
|
7 |
+#include <globject.hpp> |
|
8 |
+ |
|
9 |
+ |
|
10 |
+class GLObjectTest : public GLObject |
|
11 |
+{ |
|
12 |
+public: |
|
13 |
+ explicit GLObjectTest() |
|
14 |
+ : |
|
15 |
+ GLObject( |
|
16 |
+ nullptr, |
|
17 |
+ nullptr, |
|
18 |
+ 0, |
|
19 |
+ "GLObjectTest" |
|
20 |
+ ) |
|
21 |
+ { |
|
22 |
+ std::cout |
|
23 |
+ << "glm::mat4x3:" << "\n" |
|
24 |
+ << " name: " << DataTraits<glm::mat4x3>::name << "\n" |
|
25 |
+ << " columns: " << DataTraits<glm::mat4x3>::columns << "\n" |
|
26 |
+ << " rows: " << DataTraits<glm::mat4x3>::rows << "\n" |
|
27 |
+ << " format: " << str_enum_(DataTraits<glm::mat4x3>::format) << "\n" |
|
28 |
+ << " type: " << str_enum_(DataTraits<glm::mat4x3>::type) << "\n" |
|
29 |
+ << " internal_format: " << str_enum_(DataTraits<glm::mat4x3>::internal_format) << "\n"; |
|
30 |
+ |
|
31 |
+ std::cout |
|
32 |
+ << path_prefix_("path", "") << "\n" |
|
33 |
+ << path_prefix_("path", "prefix") << "\n"; |
|
34 |
+ |
|
35 |
+ // NOLINTNEXTLINE |
|
36 |
+ TGA tga({1, 1}, {0, 0, 255, 127}); |
|
37 |
+ std::cout |
|
38 |
+ << "TGA:" << "\n" |
|
39 |
+ << " size: " << tga.size()[0] << ", " << tga.size()[1] << "\n" |
|
40 |
+ << " data size: " << tga.data().size() << "\n"; |
|
41 |
+ |
|
42 |
+ std::cout |
|
43 |
+ << str_path_ ("path") << "\n" |
|
44 |
+ << str_paths_ ({"path1", "path2"}) << "\n" |
|
45 |
+ << str_enum_ (0x01) << "\n" |
|
46 |
+ << str_error_ (GL_NO_ERROR) << "\n"; |
|
47 |
+ } |
|
48 |
+}; |
|
49 |
+ |
|
50 |
+ |
|
51 |
+int main() |
|
52 |
+{ |
|
53 |
+ std::cout |
|
54 |
+ << "Supported 1.0: " |
|
55 |
+ << GLObject::supported({1, 0}) |
|
56 |
+ << "\n"; |
|
57 |
+ std::cout |
|
58 |
+ << "GL_ACTIVE_TEXTURE: " |
|
59 |
+ << GLObject::get_integer(GL_ACTIVE_TEXTURE) |
|
60 |
+ << "\n"; |
|
61 |
+ GLObject::debug_callback()("Debug callback"); |
|
62 |
+ |
|
63 |
+ auto const print_debug_objects_info = []() |
|
64 |
+ { |
|
65 |
+ std::cout << GLObject::debug_objects_info() << "\n"; |
|
66 |
+ }; |
|
67 |
+ print_debug_objects_info(); |
|
68 |
+ { |
|
69 |
+ auto object_test_moved = GLObjectTest{}; |
|
70 |
+ auto object_test = std::move(object_test_moved); |
|
71 |
+ print_debug_objects_info(); |
|
72 |
+ } |
|
73 |
+ print_debug_objects_info(); |
|
74 |
+ |
|
75 |
+ return 0; |
|
76 |
+} |