... | ... |
@@ -154,6 +154,56 @@ alias for `glm::vec3`. |
154 | 154 |
[`glDisableVertexAttribArray`]: https://registry.khronos.org/OpenGL-Refpages/gl4/html/glEnableVertexAttribArray.xhtml |
155 | 155 |
[`glEnableVertexAttribArray`]: https://registry.khronos.org/OpenGL-Refpages/gl4/html/glEnableVertexAttribArray.xhtml |
156 | 156 |
|
157 |
+### Object |
|
158 |
+ |
|
159 |
+The [empty][] `struct GLTraits::Object<GLenum object_type>` is template |
|
160 |
+specialized on the following values. |
|
161 |
+ |
|
162 |
+- `GL_TEXTURE` |
|
163 |
+- `GL_BUFFER` |
|
164 |
+- `GL_QUERY` |
|
165 |
+- `GL_PROGRAM` |
|
166 |
+- `GL_SHADER` |
|
167 |
+- `GL_VERTEX_ARRAY` |
|
168 |
+- `GL_FRAMEBUFFER` |
|
169 |
+- `GL_RENDERBUFFER` |
|
170 |
+- `GL_SAMPLER` |
|
171 |
+- `GL_TRANSFORM_FEEDBACK` |
|
172 |
+- `GL_PROGRAM_PIPELINE` |
|
173 |
+ |
|
174 |
+`GLTraits::Object` contains the following `static constexpr` member variables. |
|
175 |
+ |
|
176 |
+- `char const name[]` |
|
177 |
+ |
|
178 |
+`GLTraits::Object` contains the following `static` member functions. |
|
179 |
+ |
|
180 |
+- ```cpp |
|
181 |
+ template<typename... Args> |
|
182 |
+ void gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
183 |
+ ``` |
|
184 |
+ |
|
185 |
+ Generalization of `glGen*s` and `glCreate`. |
|
186 |
+ |
|
187 |
+- ```cpp |
|
188 |
+ void delete_objects(GLsizei n, GLuint * objects) |
|
189 |
+ ``` |
|
190 |
+ |
|
191 |
+ Generalization of `glDelete*s` and `glDelete*`. |
|
192 |
+ |
|
193 |
+For `object_types` equal to `GL_SHADER`, `GL_PROGRAM`, and |
|
194 |
+`GL_PROGRAM_PIPELINE`, `GLTraits::Object` additionally contains the following |
|
195 |
+`static` member functions. |
|
196 |
+ |
|
197 |
+- ```cpp |
|
198 |
+ std::string info_log(GLuint object) |
|
199 |
+ ``` |
|
200 |
+ |
|
201 |
+ Generalization of `glGet*InfoLog`. |
|
202 |
+ |
|
203 |
+`GLTRAITS_OBJECT*` macros are defined to ease the definition of new template |
|
204 |
+specializations of `GLTraits::Object`. Consult the source for the definitions |
|
205 |
+and usage examples. |
|
206 |
+ |
|
157 | 207 |
## Building |
158 | 208 |
|
159 | 209 |
See [`BUILDING.md`][]. |
... | ... |
@@ -5,6 +5,8 @@ class GLTraits |
5 | 5 |
template <typename> struct Value; |
6 | 6 |
|
7 | 7 |
template <GLenum id> struct ValueID; |
8 |
+ |
|
9 |
+ template <GLenum object_type> struct Object; |
|
8 | 10 |
}; |
9 | 11 |
|
10 | 12 |
template <> struct GLTraits::Value<GLfloat> |
... | ... |
@@ -2382,3 +2384,252 @@ template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4>::id> |
2382 | 2384 |
using Value = glm::dmat4; |
2383 | 2385 |
}; |
2384 | 2386 |
|
2387 |
+template <> struct GLTraits::Object<GL_TEXTURE> |
|
2388 |
+{ |
|
2389 |
+ auto static constexpr name = "GL_" |
|
2390 |
+ "TEXTURE"; |
|
2391 |
+ template <typename... Args> |
|
2392 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2393 |
+ { |
|
2394 |
+ if (GLBase::debug() >= 1) |
|
2395 |
+ GLBase::check_supported({1, 1}, {}); |
|
2396 |
+ glGenTextures(n, objects, args...); |
|
2397 |
+ } |
|
2398 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2399 |
+ { |
|
2400 |
+ if (GLBase::debug() >= 1) |
|
2401 |
+ GLBase::check_supported({1, 1}, {}); |
|
2402 |
+ glDeleteTextures(n, objects); |
|
2403 |
+ } |
|
2404 |
+}; |
|
2405 |
+ |
|
2406 |
+template <> struct GLTraits::Object<GL_BUFFER> |
|
2407 |
+{ |
|
2408 |
+ auto static constexpr name = "GL_" |
|
2409 |
+ "BUFFER"; |
|
2410 |
+ template <typename... Args> |
|
2411 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2412 |
+ { |
|
2413 |
+ if (GLBase::debug() >= 1) |
|
2414 |
+ GLBase::check_supported({1, 5}, {}); |
|
2415 |
+ glGenBuffers(n, objects, args...); |
|
2416 |
+ } |
|
2417 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2418 |
+ { |
|
2419 |
+ if (GLBase::debug() >= 1) |
|
2420 |
+ GLBase::check_supported({1, 5}, {}); |
|
2421 |
+ glDeleteBuffers(n, objects); |
|
2422 |
+ } |
|
2423 |
+}; |
|
2424 |
+ |
|
2425 |
+template <> struct GLTraits::Object<GL_QUERY> |
|
2426 |
+{ |
|
2427 |
+ auto static constexpr name = "GL_" |
|
2428 |
+ "QUERY"; |
|
2429 |
+ template <typename... Args> |
|
2430 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2431 |
+ { |
|
2432 |
+ if (GLBase::debug() >= 1) |
|
2433 |
+ GLBase::check_supported({1, 5}, {}); |
|
2434 |
+ glGenQueries(n, objects, args...); |
|
2435 |
+ } |
|
2436 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2437 |
+ { |
|
2438 |
+ if (GLBase::debug() >= 1) |
|
2439 |
+ GLBase::check_supported({1, 5}, {}); |
|
2440 |
+ glDeleteQueries(n, objects); |
|
2441 |
+ } |
|
2442 |
+}; |
|
2443 |
+ |
|
2444 |
+template <> struct GLTraits::Object<GL_PROGRAM> |
|
2445 |
+{ |
|
2446 |
+ auto static constexpr name = "GL_" |
|
2447 |
+ "PROGRAM"; |
|
2448 |
+ template <typename... Args> |
|
2449 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2450 |
+ { |
|
2451 |
+ if (GLBase::debug() >= 1) |
|
2452 |
+ GLBase::check_supported({2, 0}, {}); |
|
2453 |
+ while (n--) |
|
2454 |
+ objects[n] = glCreateProgram(args...); |
|
2455 |
+ } |
|
2456 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2457 |
+ { |
|
2458 |
+ if (GLBase::debug() >= 1) |
|
2459 |
+ GLBase::check_supported({2, 0}, {}); |
|
2460 |
+ while (n--) |
|
2461 |
+ glDeleteProgram(objects[n]); |
|
2462 |
+ } |
|
2463 |
+ std::string static info_log(GLuint object) |
|
2464 |
+ { |
|
2465 |
+ if (GLBase::debug() >= 1) |
|
2466 |
+ GLBase::check_supported({2, 0}, {}); |
|
2467 |
+ auto length = GLint{}; |
|
2468 |
+ glGetProgramiv(object, GL_INFO_LOG_LENGTH, &length); |
|
2469 |
+ if (length != 0) |
|
2470 |
+ --length; |
|
2471 |
+ auto info_log = std::string((std::size_t)length, char{}); |
|
2472 |
+ glGetProgramInfoLog(object, length + 1, nullptr, &info_log[0]); |
|
2473 |
+ return info_log; |
|
2474 |
+ } |
|
2475 |
+}; |
|
2476 |
+ |
|
2477 |
+template <> struct GLTraits::Object<GL_SHADER> |
|
2478 |
+{ |
|
2479 |
+ auto static constexpr name = "GL_" |
|
2480 |
+ "SHADER"; |
|
2481 |
+ template <typename... Args> |
|
2482 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2483 |
+ { |
|
2484 |
+ if (GLBase::debug() >= 1) |
|
2485 |
+ GLBase::check_supported({2, 0}, {}); |
|
2486 |
+ while (n--) |
|
2487 |
+ objects[n] = glCreateShader(args...); |
|
2488 |
+ } |
|
2489 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2490 |
+ { |
|
2491 |
+ if (GLBase::debug() >= 1) |
|
2492 |
+ GLBase::check_supported({2, 0}, {}); |
|
2493 |
+ while (n--) |
|
2494 |
+ glDeleteShader(objects[n]); |
|
2495 |
+ } |
|
2496 |
+ std::string static info_log(GLuint object) |
|
2497 |
+ { |
|
2498 |
+ if (GLBase::debug() >= 1) |
|
2499 |
+ GLBase::check_supported({2, 0}, {}); |
|
2500 |
+ auto length = GLint{}; |
|
2501 |
+ glGetShaderiv(object, GL_INFO_LOG_LENGTH, &length); |
|
2502 |
+ if (length != 0) |
|
2503 |
+ --length; |
|
2504 |
+ auto info_log = std::string((std::size_t)length, char{}); |
|
2505 |
+ glGetShaderInfoLog(object, length + 1, nullptr, &info_log[0]); |
|
2506 |
+ return info_log; |
|
2507 |
+ } |
|
2508 |
+}; |
|
2509 |
+ |
|
2510 |
+template <> struct GLTraits::Object<GL_VERTEX_ARRAY> |
|
2511 |
+{ |
|
2512 |
+ auto static constexpr name = "GL_" |
|
2513 |
+ "VERTEX_ARRAY"; |
|
2514 |
+ template <typename... Args> |
|
2515 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2516 |
+ { |
|
2517 |
+ if (GLBase::debug() >= 1) |
|
2518 |
+ GLBase::check_supported({3, 0}, "GL_ARB_vertex_array_object"); |
|
2519 |
+ glGenVertexArrays(n, objects, args...); |
|
2520 |
+ } |
|
2521 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2522 |
+ { |
|
2523 |
+ if (GLBase::debug() >= 1) |
|
2524 |
+ GLBase::check_supported({3, 0}, "GL_ARB_vertex_array_object"); |
|
2525 |
+ glDeleteVertexArrays(n, objects); |
|
2526 |
+ } |
|
2527 |
+}; |
|
2528 |
+ |
|
2529 |
+template <> struct GLTraits::Object<GL_FRAMEBUFFER> |
|
2530 |
+{ |
|
2531 |
+ auto static constexpr name = "GL_" |
|
2532 |
+ "FRAMEBUFFER"; |
|
2533 |
+ template <typename... Args> |
|
2534 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2535 |
+ { |
|
2536 |
+ if (GLBase::debug() >= 1) |
|
2537 |
+ GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); |
|
2538 |
+ glGenFramebuffers(n, objects, args...); |
|
2539 |
+ } |
|
2540 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2541 |
+ { |
|
2542 |
+ if (GLBase::debug() >= 1) |
|
2543 |
+ GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); |
|
2544 |
+ glDeleteFramebuffers(n, objects); |
|
2545 |
+ } |
|
2546 |
+}; |
|
2547 |
+ |
|
2548 |
+template <> struct GLTraits::Object<GL_RENDERBUFFER> |
|
2549 |
+{ |
|
2550 |
+ auto static constexpr name = "GL_" |
|
2551 |
+ "RENDERBUFFER"; |
|
2552 |
+ template <typename... Args> |
|
2553 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2554 |
+ { |
|
2555 |
+ if (GLBase::debug() >= 1) |
|
2556 |
+ GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); |
|
2557 |
+ glGenRenderbuffers(n, objects, args...); |
|
2558 |
+ } |
|
2559 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2560 |
+ { |
|
2561 |
+ if (GLBase::debug() >= 1) |
|
2562 |
+ GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); |
|
2563 |
+ glDeleteRenderbuffers(n, objects); |
|
2564 |
+ } |
|
2565 |
+}; |
|
2566 |
+ |
|
2567 |
+template <> struct GLTraits::Object<GL_SAMPLER> |
|
2568 |
+{ |
|
2569 |
+ auto static constexpr name = "GL_" |
|
2570 |
+ "SAMPLER"; |
|
2571 |
+ template <typename... Args> |
|
2572 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2573 |
+ { |
|
2574 |
+ if (GLBase::debug() >= 1) |
|
2575 |
+ GLBase::check_supported({3, 3}, "GL_ARB_sampler_objects"); |
|
2576 |
+ glGenSamplers(n, objects, args...); |
|
2577 |
+ } |
|
2578 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2579 |
+ { |
|
2580 |
+ if (GLBase::debug() >= 1) |
|
2581 |
+ GLBase::check_supported({3, 3}, "GL_ARB_sampler_objects"); |
|
2582 |
+ glDeleteSamplers(n, objects); |
|
2583 |
+ } |
|
2584 |
+}; |
|
2585 |
+ |
|
2586 |
+template <> struct GLTraits::Object<GL_TRANSFORM_FEEDBACK> |
|
2587 |
+{ |
|
2588 |
+ auto static constexpr name = "GL_" |
|
2589 |
+ "TRANSFORM_FEEDBACK"; |
|
2590 |
+ template <typename... Args> |
|
2591 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2592 |
+ { |
|
2593 |
+ if (GLBase::debug() >= 1) |
|
2594 |
+ GLBase::check_supported({4, 0}, "GL_ARB_transform_feedback2"); |
|
2595 |
+ glGenTransformFeedbacks(n, objects, args...); |
|
2596 |
+ } |
|
2597 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2598 |
+ { |
|
2599 |
+ if (GLBase::debug() >= 1) |
|
2600 |
+ GLBase::check_supported({4, 0}, "GL_ARB_transform_feedback2"); |
|
2601 |
+ glDeleteTransformFeedbacks(n, objects); |
|
2602 |
+ } |
|
2603 |
+}; |
|
2604 |
+ |
|
2605 |
+template <> struct GLTraits::Object<GL_PROGRAM_PIPELINE> |
|
2606 |
+{ |
|
2607 |
+ auto static constexpr name = "GL_" |
|
2608 |
+ "PROGRAM_PIPELINE"; |
|
2609 |
+ template <typename... Args> |
|
2610 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) |
|
2611 |
+ { |
|
2612 |
+ if (GLBase::debug() >= 1) |
|
2613 |
+ GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects"); |
|
2614 |
+ glGenProgramPipelines(n, objects, args...); |
|
2615 |
+ } |
|
2616 |
+ void static delete_objects(GLsizei n, GLuint const * objects) |
|
2617 |
+ { |
|
2618 |
+ if (GLBase::debug() >= 1) |
|
2619 |
+ GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects"); |
|
2620 |
+ glDeleteProgramPipelines(n, objects); |
|
2621 |
+ } |
|
2622 |
+ std::string static info_log(GLuint object) |
|
2623 |
+ { |
|
2624 |
+ if (GLBase::debug() >= 1) |
|
2625 |
+ GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects"); |
|
2626 |
+ auto length = GLint{}; |
|
2627 |
+ glGetProgramPipelineiv(object, GL_INFO_LOG_LENGTH, &length); |
|
2628 |
+ if (length != 0) |
|
2629 |
+ --length; |
|
2630 |
+ auto info_log = std::string((std::size_t)length, char{}); |
|
2631 |
+ glGetProgramPipelineInfoLog(object, length + 1, nullptr, &info_log[0]); |
|
2632 |
+ return info_log; |
|
2633 |
+ } |
|
2634 |
+}; |
|
2635 |
+ |
... | ... |
@@ -7,6 +7,7 @@ |
7 | 7 |
/// Includes |
8 | 8 |
|
9 | 9 |
#include <cstddef> |
10 |
+#include <string> |
|
10 | 11 |
|
11 | 12 |
#include <glbase.hpp> |
12 | 13 |
|
... | ... |
@@ -26,6 +27,11 @@ public: |
26 | 27 |
template<GLenum id> |
27 | 28 |
struct ValueID; |
28 | 29 |
|
30 |
+ //// Object |
|
31 |
+ |
|
32 |
+ template<GLenum object_type> |
|
33 |
+ struct Object; |
|
34 |
+ |
|
29 | 35 |
}; |
30 | 36 |
|
31 | 37 |
//// Helpers |
... | ... |
@@ -171,6 +177,80 @@ GLTRAITS_VALUE_VECTOR( glm::dvec, DOUBLE, glm::value_ptr, , |
171 | 177 |
GLTRAITS_VALUE_MATRIX( glm::dmat, DOUBLE, glm::value_ptr, GL_FALSE, , d, L, , OMIT, 4, 0, 4, 1, "GL_ARB_gpu_shader_fp64", "GL_ARB_vertex_attrib_64bit") |
172 | 178 |
#endif |
173 | 179 |
|
180 |
+//// Object |
|
181 |
+ |
|
182 |
+#define GLTRAITS_OBJECT_( \ |
|
183 |
+ OBJECT_TYPE, OBJECT, \ |
|
184 |
+ GEN_OBJECTS, DELETE_OBJECTS, \ |
|
185 |
+ INFO_LOG_ARGS, \ |
|
186 |
+ V1, V2, EXT \ |
|
187 |
+) \ |
|
188 |
+ template<> \ |
|
189 |
+ struct GLTraits::Object<GL_##OBJECT_TYPE> \ |
|
190 |
+ { \ |
|
191 |
+ auto static constexpr name = "GL_" #OBJECT_TYPE; \ |
|
192 |
+ template<typename... Args> \ |
|
193 |
+ void static gen_objects(GLsizei n, GLuint * objects, Args... args) \ |
|
194 |
+ { \ |
|
195 |
+ if (GLBase::debug() >= 1) \ |
|
196 |
+ GLBase::check_supported({V1, V2}, EXT); \ |
|
197 |
+ GEN_OBJECTS; \ |
|
198 |
+ } \ |
|
199 |
+ void static delete_objects(GLsizei n, GLuint const * objects) \ |
|
200 |
+ { \ |
|
201 |
+ if (GLBase::debug() >= 1) \ |
|
202 |
+ GLBase::check_supported({V1, V2}, EXT); \ |
|
203 |
+ DELETE_OBJECTS; \ |
|
204 |
+ } \ |
|
205 |
+ GLTRAITS_##INFO_LOG_ARGS( \ |
|
206 |
+ std::string static info_log(GLuint object) \ |
|
207 |
+ { \ |
|
208 |
+ if (GLBase::debug() >= 1) \ |
|
209 |
+ GLBase::check_supported({V1, V2}, EXT); \ |
|
210 |
+ auto length = GLint{}; \ |
|
211 |
+ glGet##OBJECT##iv(object, GL_INFO_LOG_LENGTH, &length); \ |
|
212 |
+ if (length != 0) \ |
|
213 |
+ --length; \ |
|
214 |
+ auto info_log = std::string((std::size_t)length, char{}); \ |
|
215 |
+ glGet##OBJECT##InfoLog( \ |
|
216 |
+ object, \ |
|
217 |
+ length+1, \ |
|
218 |
+ nullptr, \ |
|
219 |
+ &info_log[0] \ |
|
220 |
+ ); \ |
|
221 |
+ return info_log; \ |
|
222 |
+ } \ |
|
223 |
+ ) \ |
|
224 |
+ }; |
|
225 |
+ |
|
226 |
+#define GLTRAITS_OBJECT(OBJECT_TYPE, OBJECT, OBJECTS, ...) \ |
|
227 |
+ GLTRAITS_OBJECT_( \ |
|
228 |
+ OBJECT_TYPE, OBJECT, \ |
|
229 |
+ glGen##OBJECTS(n, objects, args...), \ |
|
230 |
+ glDelete##OBJECTS(n, objects), \ |
|
231 |
+ __VA_ARGS__ \ |
|
232 |
+ ) |
|
233 |
+ |
|
234 |
+#define GLTRAITS_OBJECT_GLSL(OBJECT_TYPE, OBJECT, OBJECTS, ...) \ |
|
235 |
+ GLTRAITS_OBJECT_( \ |
|
236 |
+ OBJECT_TYPE, OBJECT, \ |
|
237 |
+ while (n--) objects[n] = glCreate##OBJECT(args...), \ |
|
238 |
+ while (n--) glDelete##OBJECT(objects[n]), \ |
|
239 |
+ __VA_ARGS__ \ |
|
240 |
+ ) |
|
241 |
+ |
|
242 |
+GLTRAITS_OBJECT( TEXTURE, Texture, Textures, OMIT, 1, 1, {}) |
|
243 |
+GLTRAITS_OBJECT( BUFFER, Buffer, Buffers, OMIT, 1, 5, {}) |
|
244 |
+GLTRAITS_OBJECT( QUERY, Query, Queries, OMIT, 1, 5, {}) |
|
245 |
+GLTRAITS_OBJECT_GLSL(PROGRAM, Program, Programs, KEEP, 2, 0, {}) |
|
246 |
+GLTRAITS_OBJECT_GLSL(SHADER, Shader, Shaders, KEEP, 2, 0, {}) |
|
247 |
+GLTRAITS_OBJECT( VERTEX_ARRAY, VertexArray, VertexArrays, OMIT, 3, 0, "GL_ARB_vertex_array_object") |
|
248 |
+GLTRAITS_OBJECT( FRAMEBUFFER, Framebuffer, Framebuffers, OMIT, 3, 0, "GL_ARB_framebuffer_object") |
|
249 |
+GLTRAITS_OBJECT( RENDERBUFFER, Renderbuffer, Renderbuffers, OMIT, 3, 0, "GL_ARB_framebuffer_object") |
|
250 |
+GLTRAITS_OBJECT( SAMPLER, Sampler, Samplers, OMIT, 3, 3, "GL_ARB_sampler_objects") |
|
251 |
+GLTRAITS_OBJECT( TRANSFORM_FEEDBACK, TransformFeedback, TransformFeedbacks, OMIT, 4, 0, "GL_ARB_transform_feedback2") |
|
252 |
+GLTRAITS_OBJECT( PROGRAM_PIPELINE, ProgramPipeline, ProgramPipelines, KEEP, 4, 1, "GL_ARB_separate_shader_objects") |
|
253 |
+ |
|
174 | 254 |
|
175 | 255 |
/// Guards |
176 | 256 |
|
... | ... |
@@ -61,6 +61,26 @@ struct GLTraitsTest : protected GLBase |
61 | 61 |
<< " " << GLTraits::Value<typename Traits::Value>::name << "\n"; |
62 | 62 |
} |
63 | 63 |
|
64 |
+ template<GLenum object_type, typename... Args> |
|
65 |
+ void static test_object() |
|
66 |
+ { |
|
67 |
+ using Traits = GLTraits::Object<object_type>; |
|
68 |
+ static_assert( |
|
69 |
+ std::is_empty<Traits>::value, |
|
70 |
+ "GLTraits::Object must be empty" |
|
71 |
+ ); |
|
72 |
+ #define GLTRAITS_TEST_OBJECT(NAME) \ |
|
73 |
+ << std::left << std::setw(33) \ |
|
74 |
+ << " " #NAME ":" \ |
|
75 |
+ << (void *)Traits::NAME \ |
|
76 |
+ << "\n" |
|
77 |
+ std::cout |
|
78 |
+ << "Object<" << Traits::name << ">" << "\n" |
|
79 |
+ GLTRAITS_TEST_OBJECT(template gen_objects<Args...>) |
|
80 |
+ GLTRAITS_TEST_OBJECT(delete_objects) |
|
81 |
+ GLTRAITS_TEST_OBJECT(info_log); |
|
82 |
+ } |
|
83 |
+ |
|
64 | 84 |
}; |
65 | 85 |
|
66 | 86 |
|
... | ... |
@@ -81,4 +101,7 @@ int main() |
81 | 101 |
GLTraitsTest::test_value_id<GL_FLOAT_MAT4x3>(); |
82 | 102 |
GLTraitsTest::test_value_id<GL_UNSIGNED_INT_VEC2>(); |
83 | 103 |
GLTraitsTest::test_value_id<GL_DOUBLE_VEC2>(); |
104 |
+ |
|
105 |
+ GLTraitsTest::test_object<GL_SHADER, GLenum>(); |
|
106 |
+ GLTraitsTest::test_object<GL_PROGRAM_PIPELINE>(); |
|
84 | 107 |
} |