Browse code

Add ValueID

Robert Cranston authored on 28/02/2023 02:16:10
Showing 4 changed files

... ...
@@ -80,6 +80,10 @@ on the following types.
80 80
 -   `GLenum       internal_format_compressed`
81 81
 -   `GLenum       internal_format_compressed_srgb`
82 82
 -   `bool         integer`
83
+-   `GLenum       id`
84
+
85
+`id` is guaranteed to be unique to this `Value` and is equal to `glsl` for all
86
+`Value`s except `GL{,u}{byte,short}`, for which it is equal to `type`.
83 87
 
84 88
 `GLTraits::Value` contains the following `static` member functions.
85 89
 
... ...
@@ -126,6 +130,20 @@ automatically by `vertex_attrib{,_pointer}(...)` above.
126 130
 specializations of `GLTraits::Value`. Consult the source for the definitions
127 131
 and usage examples.
128 132
 
133
+The [empty][] `struct GLTraits::ValueID<GLenum id>` is template specialized on
134
+the different values of `GLTraits::Value<Value>::id`.
135
+
136
+`GLTraits::ValueID` contains the following type definitions.
137
+
138
+-   `Value`. An alias for the template type parameter for which
139
+    `GLTraits::Value<Value>::id == id` holds.
140
+
141
+`GLTraits::ValueID` provides a compile time mapping from `GLenum id` back to
142
+the type `Value`. E.g. `GLTraits::ValueID<GL_FLOAT>::Value` is an alias for
143
+`GLfloat`. This works for all supported types, including those provided by
144
+[GLM][] if enabled, e.g. `GLTraits::ValueID<GL_FLOAT_VEC3>::Value` would be an
145
+alias for `glm::vec3`.
146
+
129 147
 [empty]: https://en.cppreference.com/w/cpp/types/is_empty
130 148
 [uniform]: https://www.khronos.org/opengl/wiki/Uniform_(GLSL)
131 149
 [shader]: https://www.khronos.org/opengl/wiki/Shader
... ...
@@ -3,6 +3,8 @@ class GLTraits
3 3
 
4 4
   public:
5 5
     template <typename> struct Value;
6
+
7
+    template <GLenum id> struct ValueID;
6 8
 };
7 9
 
8 10
 template <> struct GLTraits::Value<GLfloat>
... ...
@@ -20,6 +22,10 @@ template <> struct GLTraits::Value<GLfloat>
20 22
     auto static constexpr internal_format_compressed_srgb =
21 23
         GLenum{GL_COMPRESSED_SRGB};
22 24
     auto static constexpr integer = bool(*"");
25
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
26
+                                       sizeof(GLfloat) < sizeof(GLint)
27
+                                   ? type
28
+                                   : glsl;
23 29
     void static uniform(GLint location, GLfloat const & value)
24 30
     {
25 31
         if (GLBase::debug() >= 1)
... ...
@@ -56,6 +62,11 @@ template <> struct GLTraits::Value<GLfloat>
56 62
     }
57 63
 };
58 64
 
65
+template <> struct GLTraits::ValueID<GLTraits::Value<GLfloat>::id>
66
+{
67
+    using Value = GLfloat;
68
+};
69
+
59 70
 template <> struct GLTraits::Value<bool>
60 71
 {
61 72
     auto static constexpr name                 = "bool";
... ...
@@ -71,6 +82,10 @@ template <> struct GLTraits::Value<bool>
71 82
     auto static constexpr internal_format_compressed_srgb =
72 83
         GLenum{GL_COMPRESSED_SRGB};
73 84
     auto static constexpr integer = bool(*"_INTEGER");
85
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
86
+                                       sizeof(bool) < sizeof(GLint)
87
+                                   ? type
88
+                                   : glsl;
74 89
     void static uniform(GLint location, bool const & value)
75 90
     {
76 91
         if (GLBase::debug() >= 1)
... ...
@@ -106,6 +121,11 @@ template <> struct GLTraits::Value<bool>
106 121
     }
107 122
 };
108 123
 
124
+template <> struct GLTraits::ValueID<GLTraits::Value<bool>::id>
125
+{
126
+    using Value = bool;
127
+};
128
+
109 129
 template <> struct GLTraits::Value<GLbyte>
110 130
 {
111 131
     auto static constexpr name                 = "GLbyte";
... ...
@@ -121,6 +141,10 @@ template <> struct GLTraits::Value<GLbyte>
121 141
     auto static constexpr internal_format_compressed_srgb =
122 142
         GLenum{GL_COMPRESSED_SRGB};
123 143
     auto static constexpr integer = bool(*"_INTEGER");
144
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
145
+                                       sizeof(GLbyte) < sizeof(GLint)
146
+                                   ? type
147
+                                   : glsl;
124 148
     void static uniform(GLint location, GLbyte const & value)
125 149
     {
126 150
         if (GLBase::debug() >= 1)
... ...
@@ -156,6 +180,11 @@ template <> struct GLTraits::Value<GLbyte>
156 180
     }
157 181
 };
158 182
 
183
+template <> struct GLTraits::ValueID<GLTraits::Value<GLbyte>::id>
184
+{
185
+    using Value = GLbyte;
186
+};
187
+
159 188
 template <> struct GLTraits::Value<GLshort>
160 189
 {
161 190
     auto static constexpr name                 = "GLshort";
... ...
@@ -171,6 +200,10 @@ template <> struct GLTraits::Value<GLshort>
171 200
     auto static constexpr internal_format_compressed_srgb =
172 201
         GLenum{GL_COMPRESSED_SRGB};
173 202
     auto static constexpr integer = bool(*"_INTEGER");
203
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
204
+                                       sizeof(GLshort) < sizeof(GLint)
205
+                                   ? type
206
+                                   : glsl;
174 207
     void static uniform(GLint location, GLshort const & value)
175 208
     {
176 209
         if (GLBase::debug() >= 1)
... ...
@@ -206,6 +239,11 @@ template <> struct GLTraits::Value<GLshort>
206 239
     }
207 240
 };
208 241
 
242
+template <> struct GLTraits::ValueID<GLTraits::Value<GLshort>::id>
243
+{
244
+    using Value = GLshort;
245
+};
246
+
209 247
 template <> struct GLTraits::Value<GLint>
210 248
 {
211 249
     auto static constexpr name                 = "GLint";
... ...
@@ -221,6 +259,10 @@ template <> struct GLTraits::Value<GLint>
221 259
     auto static constexpr internal_format_compressed_srgb =
222 260
         GLenum{GL_COMPRESSED_SRGB};
223 261
     auto static constexpr integer = bool(*"_INTEGER");
262
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
263
+                                       sizeof(GLint) < sizeof(GLint)
264
+                                   ? type
265
+                                   : glsl;
224 266
     void static uniform(GLint location, GLint const & value)
225 267
     {
226 268
         if (GLBase::debug() >= 1)
... ...
@@ -256,6 +298,11 @@ template <> struct GLTraits::Value<GLint>
256 298
     }
257 299
 };
258 300
 
301
+template <> struct GLTraits::ValueID<GLTraits::Value<GLint>::id>
302
+{
303
+    using Value = GLint;
304
+};
305
+
259 306
 template <> struct GLTraits::Value<GLubyte>
260 307
 {
261 308
     auto static constexpr name                 = "GLubyte";
... ...
@@ -271,6 +318,10 @@ template <> struct GLTraits::Value<GLubyte>
271 318
     auto static constexpr internal_format_compressed_srgb =
272 319
         GLenum{GL_COMPRESSED_SRGB};
273 320
     auto static constexpr integer = bool(*"_INTEGER");
321
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
322
+                                       sizeof(GLubyte) < sizeof(GLint)
323
+                                   ? type
324
+                                   : glsl;
274 325
     void static uniform(GLint location, GLubyte const & value)
275 326
     {
276 327
         if (GLBase::debug() >= 1)
... ...
@@ -306,6 +357,11 @@ template <> struct GLTraits::Value<GLubyte>
306 357
     }
307 358
 };
308 359
 
360
+template <> struct GLTraits::ValueID<GLTraits::Value<GLubyte>::id>
361
+{
362
+    using Value = GLubyte;
363
+};
364
+
309 365
 template <> struct GLTraits::Value<GLushort>
310 366
 {
311 367
     auto static constexpr name                 = "GLushort";
... ...
@@ -321,6 +377,10 @@ template <> struct GLTraits::Value<GLushort>
321 377
     auto static constexpr internal_format_compressed_srgb =
322 378
         GLenum{GL_COMPRESSED_SRGB};
323 379
     auto static constexpr integer = bool(*"_INTEGER");
380
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
381
+                                       sizeof(GLushort) < sizeof(GLint)
382
+                                   ? type
383
+                                   : glsl;
324 384
     void static uniform(GLint location, GLushort const & value)
325 385
     {
326 386
         if (GLBase::debug() >= 1)
... ...
@@ -356,6 +416,11 @@ template <> struct GLTraits::Value<GLushort>
356 416
     }
357 417
 };
358 418
 
419
+template <> struct GLTraits::ValueID<GLTraits::Value<GLushort>::id>
420
+{
421
+    using Value = GLushort;
422
+};
423
+
359 424
 template <> struct GLTraits::Value<GLuint>
360 425
 {
361 426
     auto static constexpr name                 = "GLuint";
... ...
@@ -371,6 +436,10 @@ template <> struct GLTraits::Value<GLuint>
371 436
     auto static constexpr internal_format_compressed_srgb =
372 437
         GLenum{GL_COMPRESSED_SRGB};
373 438
     auto static constexpr integer = bool(*"_INTEGER");
439
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
440
+                                       sizeof(GLuint) < sizeof(GLint)
441
+                                   ? type
442
+                                   : glsl;
374 443
     void static uniform(GLint location, GLuint const & value)
375 444
     {
376 445
         if (GLBase::debug() >= 1)
... ...
@@ -406,6 +475,11 @@ template <> struct GLTraits::Value<GLuint>
406 475
     }
407 476
 };
408 477
 
478
+template <> struct GLTraits::ValueID<GLTraits::Value<GLuint>::id>
479
+{
480
+    using Value = GLuint;
481
+};
482
+
409 483
 template <> struct GLTraits::Value<GLdouble>
410 484
 {
411 485
     auto static constexpr name                 = "GLdouble";
... ...
@@ -421,6 +495,10 @@ template <> struct GLTraits::Value<GLdouble>
421 495
     auto static constexpr internal_format_compressed_srgb =
422 496
         GLenum{GL_COMPRESSED_SRGB};
423 497
     auto static constexpr integer = bool(*"");
498
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
499
+                                       sizeof(GLdouble) < sizeof(GLint)
500
+                                   ? type
501
+                                   : glsl;
424 502
     void static uniform(GLint location, GLdouble const & value)
425 503
     {
426 504
         if (GLBase::debug() >= 1)
... ...
@@ -456,6 +534,11 @@ template <> struct GLTraits::Value<GLdouble>
456 534
     }
457 535
 };
458 536
 
537
+template <> struct GLTraits::ValueID<GLTraits::Value<GLdouble>::id>
538
+{
539
+    using Value = GLdouble;
540
+};
541
+
459 542
 
460 543
 template <> struct GLTraits::Value<glm::vec2>
461 544
 {
... ...
@@ -472,6 +555,10 @@ template <> struct GLTraits::Value<glm::vec2>
472 555
     auto static constexpr internal_format_compressed_srgb =
473 556
         GLenum{GL_COMPRESSED_SRGB};
474 557
     auto static constexpr integer = bool(*"");
558
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
559
+                                       sizeof(glm::vec2) < sizeof(GLint)
560
+                                   ? type
561
+                                   : glsl;
475 562
     void static uniform(GLint location, glm::vec2 const & value)
476 563
     {
477 564
         if (GLBase::debug() >= 1)
... ...
@@ -510,6 +597,11 @@ template <> struct GLTraits::Value<glm::vec2>
510 597
     }
511 598
 };
512 599
 
600
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec2>::id>
601
+{
602
+    using Value = glm::vec2;
603
+};
604
+
513 605
 template <> struct GLTraits::Value<glm::vec3>
514 606
 {
515 607
     auto static constexpr name                 = "glm::vec3";
... ...
@@ -525,6 +617,10 @@ template <> struct GLTraits::Value<glm::vec3>
525 617
     auto static constexpr internal_format_compressed_srgb =
526 618
         GLenum{GL_COMPRESSED_SRGB};
527 619
     auto static constexpr integer = bool(*"");
620
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
621
+                                       sizeof(glm::vec3) < sizeof(GLint)
622
+                                   ? type
623
+                                   : glsl;
528 624
     void static uniform(GLint location, glm::vec3 const & value)
529 625
     {
530 626
         if (GLBase::debug() >= 1)
... ...
@@ -563,6 +659,11 @@ template <> struct GLTraits::Value<glm::vec3>
563 659
     }
564 660
 };
565 661
 
662
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec3>::id>
663
+{
664
+    using Value = glm::vec3;
665
+};
666
+
566 667
 template <> struct GLTraits::Value<glm::vec4>
567 668
 {
568 669
     auto static constexpr name                 = "glm::vec4";
... ...
@@ -578,6 +679,10 @@ template <> struct GLTraits::Value<glm::vec4>
578 679
     auto static constexpr internal_format_compressed_srgb =
579 680
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
580 681
     auto static constexpr integer = bool(*"");
682
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
683
+                                       sizeof(glm::vec4) < sizeof(GLint)
684
+                                   ? type
685
+                                   : glsl;
581 686
     void static uniform(GLint location, glm::vec4 const & value)
582 687
     {
583 688
         if (GLBase::debug() >= 1)
... ...
@@ -616,6 +721,11 @@ template <> struct GLTraits::Value<glm::vec4>
616 721
     }
617 722
 };
618 723
 
724
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec4>::id>
725
+{
726
+    using Value = glm::vec4;
727
+};
728
+
619 729
 template <> struct GLTraits::Value<glm::mat2>
620 730
 {
621 731
     auto static constexpr name                 = "glm::mat2";
... ...
@@ -631,6 +741,10 @@ template <> struct GLTraits::Value<glm::mat2>
631 741
     auto static constexpr internal_format_compressed_srgb =
632 742
         GLenum{GL_COMPRESSED_SRGB};
633 743
     auto static constexpr integer = bool(*"");
744
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
745
+                                       sizeof(glm::mat2) < sizeof(GLint)
746
+                                   ? type
747
+                                   : glsl;
634 748
     void static uniform(GLint location, glm::mat2 const & value)
635 749
     {
636 750
         if (GLBase::debug() >= 1)
... ...
@@ -669,6 +783,11 @@ template <> struct GLTraits::Value<glm::mat2>
669 783
     }
670 784
 };
671 785
 
786
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2>::id>
787
+{
788
+    using Value = glm::mat2;
789
+};
790
+
672 791
 template <> struct GLTraits::Value<glm::mat2x3>
673 792
 {
674 793
     auto static constexpr name                 = "glm::mat2x3";
... ...
@@ -684,6 +803,10 @@ template <> struct GLTraits::Value<glm::mat2x3>
684 803
     auto static constexpr internal_format_compressed_srgb =
685 804
         GLenum{GL_COMPRESSED_SRGB};
686 805
     auto static constexpr integer = bool(*"");
806
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
807
+                                       sizeof(glm::mat2x3) < sizeof(GLint)
808
+                                   ? type
809
+                                   : glsl;
687 810
     void static uniform(GLint location, glm::mat2x3 const & value)
688 811
     {
689 812
         if (GLBase::debug() >= 1)
... ...
@@ -722,6 +845,11 @@ template <> struct GLTraits::Value<glm::mat2x3>
722 845
     }
723 846
 };
724 847
 
848
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2x3>::id>
849
+{
850
+    using Value = glm::mat2x3;
851
+};
852
+
725 853
 template <> struct GLTraits::Value<glm::mat2x4>
726 854
 {
727 855
     auto static constexpr name                 = "glm::mat2x4";
... ...
@@ -737,6 +865,10 @@ template <> struct GLTraits::Value<glm::mat2x4>
737 865
     auto static constexpr internal_format_compressed_srgb =
738 866
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
739 867
     auto static constexpr integer = bool(*"");
868
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
869
+                                       sizeof(glm::mat2x4) < sizeof(GLint)
870
+                                   ? type
871
+                                   : glsl;
740 872
     void static uniform(GLint location, glm::mat2x4 const & value)
741 873
     {
742 874
         if (GLBase::debug() >= 1)
... ...
@@ -775,6 +907,11 @@ template <> struct GLTraits::Value<glm::mat2x4>
775 907
     }
776 908
 };
777 909
 
910
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2x4>::id>
911
+{
912
+    using Value = glm::mat2x4;
913
+};
914
+
778 915
 template <> struct GLTraits::Value<glm::mat3x2>
779 916
 {
780 917
     auto static constexpr name                 = "glm::mat3x2";
... ...
@@ -790,6 +927,10 @@ template <> struct GLTraits::Value<glm::mat3x2>
790 927
     auto static constexpr internal_format_compressed_srgb =
791 928
         GLenum{GL_COMPRESSED_SRGB};
792 929
     auto static constexpr integer = bool(*"");
930
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
931
+                                       sizeof(glm::mat3x2) < sizeof(GLint)
932
+                                   ? type
933
+                                   : glsl;
793 934
     void static uniform(GLint location, glm::mat3x2 const & value)
794 935
     {
795 936
         if (GLBase::debug() >= 1)
... ...
@@ -828,6 +969,11 @@ template <> struct GLTraits::Value<glm::mat3x2>
828 969
     }
829 970
 };
830 971
 
972
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3x2>::id>
973
+{
974
+    using Value = glm::mat3x2;
975
+};
976
+
831 977
 template <> struct GLTraits::Value<glm::mat3>
832 978
 {
833 979
     auto static constexpr name                 = "glm::mat3";
... ...
@@ -843,6 +989,10 @@ template <> struct GLTraits::Value<glm::mat3>
843 989
     auto static constexpr internal_format_compressed_srgb =
844 990
         GLenum{GL_COMPRESSED_SRGB};
845 991
     auto static constexpr integer = bool(*"");
992
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
993
+                                       sizeof(glm::mat3) < sizeof(GLint)
994
+                                   ? type
995
+                                   : glsl;
846 996
     void static uniform(GLint location, glm::mat3 const & value)
847 997
     {
848 998
         if (GLBase::debug() >= 1)
... ...
@@ -881,6 +1031,11 @@ template <> struct GLTraits::Value<glm::mat3>
881 1031
     }
882 1032
 };
883 1033
 
1034
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3>::id>
1035
+{
1036
+    using Value = glm::mat3;
1037
+};
1038
+
884 1039
 template <> struct GLTraits::Value<glm::mat3x4>
885 1040
 {
886 1041
     auto static constexpr name                 = "glm::mat3x4";
... ...
@@ -896,6 +1051,10 @@ template <> struct GLTraits::Value<glm::mat3x4>
896 1051
     auto static constexpr internal_format_compressed_srgb =
897 1052
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
898 1053
     auto static constexpr integer = bool(*"");
1054
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1055
+                                       sizeof(glm::mat3x4) < sizeof(GLint)
1056
+                                   ? type
1057
+                                   : glsl;
899 1058
     void static uniform(GLint location, glm::mat3x4 const & value)
900 1059
     {
901 1060
         if (GLBase::debug() >= 1)
... ...
@@ -934,6 +1093,11 @@ template <> struct GLTraits::Value<glm::mat3x4>
934 1093
     }
935 1094
 };
936 1095
 
1096
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3x4>::id>
1097
+{
1098
+    using Value = glm::mat3x4;
1099
+};
1100
+
937 1101
 template <> struct GLTraits::Value<glm::mat4x2>
938 1102
 {
939 1103
     auto static constexpr name                 = "glm::mat4x2";
... ...
@@ -949,6 +1113,10 @@ template <> struct GLTraits::Value<glm::mat4x2>
949 1113
     auto static constexpr internal_format_compressed_srgb =
950 1114
         GLenum{GL_COMPRESSED_SRGB};
951 1115
     auto static constexpr integer = bool(*"");
1116
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1117
+                                       sizeof(glm::mat4x2) < sizeof(GLint)
1118
+                                   ? type
1119
+                                   : glsl;
952 1120
     void static uniform(GLint location, glm::mat4x2 const & value)
953 1121
     {
954 1122
         if (GLBase::debug() >= 1)
... ...
@@ -987,6 +1155,11 @@ template <> struct GLTraits::Value<glm::mat4x2>
987 1155
     }
988 1156
 };
989 1157
 
1158
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4x2>::id>
1159
+{
1160
+    using Value = glm::mat4x2;
1161
+};
1162
+
990 1163
 template <> struct GLTraits::Value<glm::mat4x3>
991 1164
 {
992 1165
     auto static constexpr name                 = "glm::mat4x3";
... ...
@@ -1002,6 +1175,10 @@ template <> struct GLTraits::Value<glm::mat4x3>
1002 1175
     auto static constexpr internal_format_compressed_srgb =
1003 1176
         GLenum{GL_COMPRESSED_SRGB};
1004 1177
     auto static constexpr integer = bool(*"");
1178
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1179
+                                       sizeof(glm::mat4x3) < sizeof(GLint)
1180
+                                   ? type
1181
+                                   : glsl;
1005 1182
     void static uniform(GLint location, glm::mat4x3 const & value)
1006 1183
     {
1007 1184
         if (GLBase::debug() >= 1)
... ...
@@ -1040,6 +1217,11 @@ template <> struct GLTraits::Value<glm::mat4x3>
1040 1217
     }
1041 1218
 };
1042 1219
 
1220
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4x3>::id>
1221
+{
1222
+    using Value = glm::mat4x3;
1223
+};
1224
+
1043 1225
 template <> struct GLTraits::Value<glm::mat4>
1044 1226
 {
1045 1227
     auto static constexpr name                 = "glm::mat4";
... ...
@@ -1055,6 +1237,10 @@ template <> struct GLTraits::Value<glm::mat4>
1055 1237
     auto static constexpr internal_format_compressed_srgb =
1056 1238
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1057 1239
     auto static constexpr integer = bool(*"");
1240
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1241
+                                       sizeof(glm::mat4) < sizeof(GLint)
1242
+                                   ? type
1243
+                                   : glsl;
1058 1244
     void static uniform(GLint location, glm::mat4 const & value)
1059 1245
     {
1060 1246
         if (GLBase::debug() >= 1)
... ...
@@ -1093,6 +1279,11 @@ template <> struct GLTraits::Value<glm::mat4>
1093 1279
     }
1094 1280
 };
1095 1281
 
1282
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4>::id>
1283
+{
1284
+    using Value = glm::mat4;
1285
+};
1286
+
1096 1287
 template <> struct GLTraits::Value<glm::ivec2>
1097 1288
 {
1098 1289
     auto static constexpr name                 = "glm::ivec2";
... ...
@@ -1108,6 +1299,10 @@ template <> struct GLTraits::Value<glm::ivec2>
1108 1299
     auto static constexpr internal_format_compressed_srgb =
1109 1300
         GLenum{GL_COMPRESSED_SRGB};
1110 1301
     auto static constexpr integer = bool(*"_INTEGER");
1302
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1303
+                                       sizeof(glm::ivec2) < sizeof(GLint)
1304
+                                   ? type
1305
+                                   : glsl;
1111 1306
     void static uniform(GLint location, glm::ivec2 const & value)
1112 1307
     {
1113 1308
         if (GLBase::debug() >= 1)
... ...
@@ -1145,6 +1340,11 @@ template <> struct GLTraits::Value<glm::ivec2>
1145 1340
     }
1146 1341
 };
1147 1342
 
1343
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec2>::id>
1344
+{
1345
+    using Value = glm::ivec2;
1346
+};
1347
+
1148 1348
 template <> struct GLTraits::Value<glm::ivec3>
1149 1349
 {
1150 1350
     auto static constexpr name                 = "glm::ivec3";
... ...
@@ -1160,6 +1360,10 @@ template <> struct GLTraits::Value<glm::ivec3>
1160 1360
     auto static constexpr internal_format_compressed_srgb =
1161 1361
         GLenum{GL_COMPRESSED_SRGB};
1162 1362
     auto static constexpr integer = bool(*"_INTEGER");
1363
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1364
+                                       sizeof(glm::ivec3) < sizeof(GLint)
1365
+                                   ? type
1366
+                                   : glsl;
1163 1367
     void static uniform(GLint location, glm::ivec3 const & value)
1164 1368
     {
1165 1369
         if (GLBase::debug() >= 1)
... ...
@@ -1197,6 +1401,11 @@ template <> struct GLTraits::Value<glm::ivec3>
1197 1401
     }
1198 1402
 };
1199 1403
 
1404
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec3>::id>
1405
+{
1406
+    using Value = glm::ivec3;
1407
+};
1408
+
1200 1409
 template <> struct GLTraits::Value<glm::ivec4>
1201 1410
 {
1202 1411
     auto static constexpr name                 = "glm::ivec4";
... ...
@@ -1212,6 +1421,10 @@ template <> struct GLTraits::Value<glm::ivec4>
1212 1421
     auto static constexpr internal_format_compressed_srgb =
1213 1422
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1214 1423
     auto static constexpr integer = bool(*"_INTEGER");
1424
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1425
+                                       sizeof(glm::ivec4) < sizeof(GLint)
1426
+                                   ? type
1427
+                                   : glsl;
1215 1428
     void static uniform(GLint location, glm::ivec4 const & value)
1216 1429
     {
1217 1430
         if (GLBase::debug() >= 1)
... ...
@@ -1249,6 +1462,11 @@ template <> struct GLTraits::Value<glm::ivec4>
1249 1462
     }
1250 1463
 };
1251 1464
 
1465
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec4>::id>
1466
+{
1467
+    using Value = glm::ivec4;
1468
+};
1469
+
1252 1470
 template <> struct GLTraits::Value<glm::uvec2>
1253 1471
 {
1254 1472
     auto static constexpr name                 = "glm::uvec2";
... ...
@@ -1264,6 +1482,10 @@ template <> struct GLTraits::Value<glm::uvec2>
1264 1482
     auto static constexpr internal_format_compressed_srgb =
1265 1483
         GLenum{GL_COMPRESSED_SRGB};
1266 1484
     auto static constexpr integer = bool(*"_INTEGER");
1485
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1486
+                                       sizeof(glm::uvec2) < sizeof(GLint)
1487
+                                   ? type
1488
+                                   : glsl;
1267 1489
     void static uniform(GLint location, glm::uvec2 const & value)
1268 1490
     {
1269 1491
         if (GLBase::debug() >= 1)
... ...
@@ -1301,6 +1523,11 @@ template <> struct GLTraits::Value<glm::uvec2>
1301 1523
     }
1302 1524
 };
1303 1525
 
1526
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec2>::id>
1527
+{
1528
+    using Value = glm::uvec2;
1529
+};
1530
+
1304 1531
 template <> struct GLTraits::Value<glm::uvec3>
1305 1532
 {
1306 1533
     auto static constexpr name                 = "glm::uvec3";
... ...
@@ -1316,6 +1543,10 @@ template <> struct GLTraits::Value<glm::uvec3>
1316 1543
     auto static constexpr internal_format_compressed_srgb =
1317 1544
         GLenum{GL_COMPRESSED_SRGB};
1318 1545
     auto static constexpr integer = bool(*"_INTEGER");
1546
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1547
+                                       sizeof(glm::uvec3) < sizeof(GLint)
1548
+                                   ? type
1549
+                                   : glsl;
1319 1550
     void static uniform(GLint location, glm::uvec3 const & value)
1320 1551
     {
1321 1552
         if (GLBase::debug() >= 1)
... ...
@@ -1353,6 +1584,11 @@ template <> struct GLTraits::Value<glm::uvec3>
1353 1584
     }
1354 1585
 };
1355 1586
 
1587
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec3>::id>
1588
+{
1589
+    using Value = glm::uvec3;
1590
+};
1591
+
1356 1592
 template <> struct GLTraits::Value<glm::uvec4>
1357 1593
 {
1358 1594
     auto static constexpr name                 = "glm::uvec4";
... ...
@@ -1368,6 +1604,10 @@ template <> struct GLTraits::Value<glm::uvec4>
1368 1604
     auto static constexpr internal_format_compressed_srgb =
1369 1605
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1370 1606
     auto static constexpr integer = bool(*"_INTEGER");
1607
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1608
+                                       sizeof(glm::uvec4) < sizeof(GLint)
1609
+                                   ? type
1610
+                                   : glsl;
1371 1611
     void static uniform(GLint location, glm::uvec4 const & value)
1372 1612
     {
1373 1613
         if (GLBase::debug() >= 1)
... ...
@@ -1405,6 +1645,11 @@ template <> struct GLTraits::Value<glm::uvec4>
1405 1645
     }
1406 1646
 };
1407 1647
 
1648
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec4>::id>
1649
+{
1650
+    using Value = glm::uvec4;
1651
+};
1652
+
1408 1653
 template <> struct GLTraits::Value<glm::dvec2>
1409 1654
 {
1410 1655
     auto static constexpr name                 = "glm::dvec2";
... ...
@@ -1420,6 +1665,10 @@ template <> struct GLTraits::Value<glm::dvec2>
1420 1665
     auto static constexpr internal_format_compressed_srgb =
1421 1666
         GLenum{GL_COMPRESSED_SRGB};
1422 1667
     auto static constexpr integer = bool(*"");
1668
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1669
+                                       sizeof(glm::dvec2) < sizeof(GLint)
1670
+                                   ? type
1671
+                                   : glsl;
1423 1672
     void static uniform(GLint location, glm::dvec2 const & value)
1424 1673
     {
1425 1674
         if (GLBase::debug() >= 1)
... ...
@@ -1457,6 +1706,11 @@ template <> struct GLTraits::Value<glm::dvec2>
1457 1706
     }
1458 1707
 };
1459 1708
 
1709
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec2>::id>
1710
+{
1711
+    using Value = glm::dvec2;
1712
+};
1713
+
1460 1714
 template <> struct GLTraits::Value<glm::dvec3>
1461 1715
 {
1462 1716
     auto static constexpr name                 = "glm::dvec3";
... ...
@@ -1472,6 +1726,10 @@ template <> struct GLTraits::Value<glm::dvec3>
1472 1726
     auto static constexpr internal_format_compressed_srgb =
1473 1727
         GLenum{GL_COMPRESSED_SRGB};
1474 1728
     auto static constexpr integer = bool(*"");
1729
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1730
+                                       sizeof(glm::dvec3) < sizeof(GLint)
1731
+                                   ? type
1732
+                                   : glsl;
1475 1733
     void static uniform(GLint location, glm::dvec3 const & value)
1476 1734
     {
1477 1735
         if (GLBase::debug() >= 1)
... ...
@@ -1509,6 +1767,11 @@ template <> struct GLTraits::Value<glm::dvec3>
1509 1767
     }
1510 1768
 };
1511 1769
 
1770
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec3>::id>
1771
+{
1772
+    using Value = glm::dvec3;
1773
+};
1774
+
1512 1775
 template <> struct GLTraits::Value<glm::dvec4>
1513 1776
 {
1514 1777
     auto static constexpr name                 = "glm::dvec4";
... ...
@@ -1524,6 +1787,10 @@ template <> struct GLTraits::Value<glm::dvec4>
1524 1787
     auto static constexpr internal_format_compressed_srgb =
1525 1788
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1526 1789
     auto static constexpr integer = bool(*"");
1790
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1791
+                                       sizeof(glm::dvec4) < sizeof(GLint)
1792
+                                   ? type
1793
+                                   : glsl;
1527 1794
     void static uniform(GLint location, glm::dvec4 const & value)
1528 1795
     {
1529 1796
         if (GLBase::debug() >= 1)
... ...
@@ -1561,6 +1828,11 @@ template <> struct GLTraits::Value<glm::dvec4>
1561 1828
     }
1562 1829
 };
1563 1830
 
1831
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec4>::id>
1832
+{
1833
+    using Value = glm::dvec4;
1834
+};
1835
+
1564 1836
 template <> struct GLTraits::Value<glm::dmat2>
1565 1837
 {
1566 1838
     auto static constexpr name                 = "glm::dmat2";
... ...
@@ -1576,6 +1848,10 @@ template <> struct GLTraits::Value<glm::dmat2>
1576 1848
     auto static constexpr internal_format_compressed_srgb =
1577 1849
         GLenum{GL_COMPRESSED_SRGB};
1578 1850
     auto static constexpr integer = bool(*"");
1851
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1852
+                                       sizeof(glm::dmat2) < sizeof(GLint)
1853
+                                   ? type
1854
+                                   : glsl;
1579 1855
     void static uniform(GLint location, glm::dmat2 const & value)
1580 1856
     {
1581 1857
         if (GLBase::debug() >= 1)
... ...
@@ -1613,6 +1889,11 @@ template <> struct GLTraits::Value<glm::dmat2>
1613 1889
     }
1614 1890
 };
1615 1891
 
1892
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2>::id>
1893
+{
1894
+    using Value = glm::dmat2;
1895
+};
1896
+
1616 1897
 template <> struct GLTraits::Value<glm::dmat2x3>
1617 1898
 {
1618 1899
     auto static constexpr name                 = "glm::dmat2x3";
... ...
@@ -1628,6 +1909,10 @@ template <> struct GLTraits::Value<glm::dmat2x3>
1628 1909
     auto static constexpr internal_format_compressed_srgb =
1629 1910
         GLenum{GL_COMPRESSED_SRGB};
1630 1911
     auto static constexpr integer = bool(*"");
1912
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1913
+                                       sizeof(glm::dmat2x3) < sizeof(GLint)
1914
+                                   ? type
1915
+                                   : glsl;
1631 1916
     void static uniform(GLint location, glm::dmat2x3 const & value)
1632 1917
     {
1633 1918
         if (GLBase::debug() >= 1)
... ...
@@ -1665,6 +1950,11 @@ template <> struct GLTraits::Value<glm::dmat2x3>
1665 1950
     }
1666 1951
 };
1667 1952
 
1953
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2x3>::id>
1954
+{
1955
+    using Value = glm::dmat2x3;
1956
+};
1957
+
1668 1958
 template <> struct GLTraits::Value<glm::dmat2x4>
1669 1959
 {
1670 1960
     auto static constexpr name                 = "glm::dmat2x4";
... ...
@@ -1680,6 +1970,10 @@ template <> struct GLTraits::Value<glm::dmat2x4>
1680 1970
     auto static constexpr internal_format_compressed_srgb =
1681 1971
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1682 1972
     auto static constexpr integer = bool(*"");
1973
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
1974
+                                       sizeof(glm::dmat2x4) < sizeof(GLint)
1975
+                                   ? type
1976
+                                   : glsl;
1683 1977
     void static uniform(GLint location, glm::dmat2x4 const & value)
1684 1978
     {
1685 1979
         if (GLBase::debug() >= 1)
... ...
@@ -1717,6 +2011,11 @@ template <> struct GLTraits::Value<glm::dmat2x4>
1717 2011
     }
1718 2012
 };
1719 2013
 
2014
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2x4>::id>
2015
+{
2016
+    using Value = glm::dmat2x4;
2017
+};
2018
+
1720 2019
 template <> struct GLTraits::Value<glm::dmat3x2>
1721 2020
 {
1722 2021
     auto static constexpr name                 = "glm::dmat3x2";
... ...
@@ -1732,6 +2031,10 @@ template <> struct GLTraits::Value<glm::dmat3x2>
1732 2031
     auto static constexpr internal_format_compressed_srgb =
1733 2032
         GLenum{GL_COMPRESSED_SRGB};
1734 2033
     auto static constexpr integer = bool(*"");
2034
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2035
+                                       sizeof(glm::dmat3x2) < sizeof(GLint)
2036
+                                   ? type
2037
+                                   : glsl;
1735 2038
     void static uniform(GLint location, glm::dmat3x2 const & value)
1736 2039
     {
1737 2040
         if (GLBase::debug() >= 1)
... ...
@@ -1769,6 +2072,11 @@ template <> struct GLTraits::Value<glm::dmat3x2>
1769 2072
     }
1770 2073
 };
1771 2074
 
2075
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3x2>::id>
2076
+{
2077
+    using Value = glm::dmat3x2;
2078
+};
2079
+
1772 2080
 template <> struct GLTraits::Value<glm::dmat3>
1773 2081
 {
1774 2082
     auto static constexpr name                 = "glm::dmat3";
... ...
@@ -1784,6 +2092,10 @@ template <> struct GLTraits::Value<glm::dmat3>
1784 2092
     auto static constexpr internal_format_compressed_srgb =
1785 2093
         GLenum{GL_COMPRESSED_SRGB};
1786 2094
     auto static constexpr integer = bool(*"");
2095
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2096
+                                       sizeof(glm::dmat3) < sizeof(GLint)
2097
+                                   ? type
2098
+                                   : glsl;
1787 2099
     void static uniform(GLint location, glm::dmat3 const & value)
1788 2100
     {
1789 2101
         if (GLBase::debug() >= 1)
... ...
@@ -1821,6 +2133,11 @@ template <> struct GLTraits::Value<glm::dmat3>
1821 2133
     }
1822 2134
 };
1823 2135
 
2136
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3>::id>
2137
+{
2138
+    using Value = glm::dmat3;
2139
+};
2140
+
1824 2141
 template <> struct GLTraits::Value<glm::dmat3x4>
1825 2142
 {
1826 2143
     auto static constexpr name                 = "glm::dmat3x4";
... ...
@@ -1836,6 +2153,10 @@ template <> struct GLTraits::Value<glm::dmat3x4>
1836 2153
     auto static constexpr internal_format_compressed_srgb =
1837 2154
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1838 2155
     auto static constexpr integer = bool(*"");
2156
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2157
+                                       sizeof(glm::dmat3x4) < sizeof(GLint)
2158
+                                   ? type
2159
+                                   : glsl;
1839 2160
     void static uniform(GLint location, glm::dmat3x4 const & value)
1840 2161
     {
1841 2162
         if (GLBase::debug() >= 1)
... ...
@@ -1873,6 +2194,11 @@ template <> struct GLTraits::Value<glm::dmat3x4>
1873 2194
     }
1874 2195
 };
1875 2196
 
2197
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3x4>::id>
2198
+{
2199
+    using Value = glm::dmat3x4;
2200
+};
2201
+
1876 2202
 template <> struct GLTraits::Value<glm::dmat4x2>
1877 2203
 {
1878 2204
     auto static constexpr name                 = "glm::dmat4x2";
... ...
@@ -1888,6 +2214,10 @@ template <> struct GLTraits::Value<glm::dmat4x2>
1888 2214
     auto static constexpr internal_format_compressed_srgb =
1889 2215
         GLenum{GL_COMPRESSED_SRGB};
1890 2216
     auto static constexpr integer = bool(*"");
2217
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2218
+                                       sizeof(glm::dmat4x2) < sizeof(GLint)
2219
+                                   ? type
2220
+                                   : glsl;
1891 2221
     void static uniform(GLint location, glm::dmat4x2 const & value)
1892 2222
     {
1893 2223
         if (GLBase::debug() >= 1)
... ...
@@ -1925,6 +2255,11 @@ template <> struct GLTraits::Value<glm::dmat4x2>
1925 2255
     }
1926 2256
 };
1927 2257
 
2258
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4x2>::id>
2259
+{
2260
+    using Value = glm::dmat4x2;
2261
+};
2262
+
1928 2263
 template <> struct GLTraits::Value<glm::dmat4x3>
1929 2264
 {
1930 2265
     auto static constexpr name                 = "glm::dmat4x3";
... ...
@@ -1940,6 +2275,10 @@ template <> struct GLTraits::Value<glm::dmat4x3>
1940 2275
     auto static constexpr internal_format_compressed_srgb =
1941 2276
         GLenum{GL_COMPRESSED_SRGB};
1942 2277
     auto static constexpr integer = bool(*"");
2278
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2279
+                                       sizeof(glm::dmat4x3) < sizeof(GLint)
2280
+                                   ? type
2281
+                                   : glsl;
1943 2282
     void static uniform(GLint location, glm::dmat4x3 const & value)
1944 2283
     {
1945 2284
         if (GLBase::debug() >= 1)
... ...
@@ -1977,6 +2316,11 @@ template <> struct GLTraits::Value<glm::dmat4x3>
1977 2316
     }
1978 2317
 };
1979 2318
 
2319
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4x3>::id>
2320
+{
2321
+    using Value = glm::dmat4x3;
2322
+};
2323
+
1980 2324
 template <> struct GLTraits::Value<glm::dmat4>
1981 2325
 {
1982 2326
     auto static constexpr name                 = "glm::dmat4";
... ...
@@ -1992,6 +2336,10 @@ template <> struct GLTraits::Value<glm::dmat4>
1992 2336
     auto static constexpr internal_format_compressed_srgb =
1993 2337
         GLenum{GL_COMPRESSED_SRGB_ALPHA};
1994 2338
     auto static constexpr integer = bool(*"");
2339
+    auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) &&
2340
+                                       sizeof(glm::dmat4) < sizeof(GLint)
2341
+                                   ? type
2342
+                                   : glsl;
1995 2343
     void static uniform(GLint location, glm::dmat4 const & value)
1996 2344
     {
1997 2345
         if (GLBase::debug() >= 1)
... ...
@@ -2029,3 +2377,8 @@ template <> struct GLTraits::Value<glm::dmat4>
2029 2377
     }
2030 2378
 };
2031 2379
 
2380
+template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4>::id>
2381
+{
2382
+    using Value = glm::dmat4;
2383
+};
2384
+
... ...
@@ -23,6 +23,9 @@ public:
23 23
     template<typename>
24 24
     struct Value;
25 25
 
26
+    template<GLenum id>
27
+    struct ValueID;
28
+
26 29
 };
27 30
 
28 31
 //// Helpers
... ...
@@ -69,6 +72,11 @@ public:
69 72
         auto static constexpr internal_format_compressed      = GLenum{GL_COMPRESSED_##FORMAT}; \
70 73
         auto static constexpr internal_format_compressed_srgb = GLenum{GLTRAITS_VALUE_COMPRESSED_S##FORMAT}; \
71 74
         auto static constexpr integer                         = bool(*#INTEGER); \
75
+        auto static constexpr id = \
76
+            (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && \
77
+            sizeof(VALUE) < sizeof(GLint) \
78
+                ? type \
79
+                : glsl; \
72 80
         void static uniform(GLint location, VALUE const & value) \
73 81
         { \
74 82
             if (GLBase::debug() >= 1) \
... ...
@@ -112,6 +120,11 @@ public:
112 120
                     (void const *)(offset + sizeof_column * column) \
113 121
                 ); \
114 122
         } \
123
+    }; \
124
+    template<> \
125
+    struct GLTraits::ValueID<GLTraits::Value<VALUE>::id> \
126
+    { \
127
+        using Value = VALUE; \
115 128
     };
116 129
 
117 130
 #define GLTRAITS_VALUE_SCALAR(                  VALUE, TYPE, GLSL,   INTERNAL, ...) GLTRAITS_VALUE(VALUE,          1, 1, GLSL,                RED,    TYPE, R     ##INTERNAL, OMIT, ,    ,  ,             __VA_ARGS__,)
... ...
@@ -26,6 +26,8 @@ struct GLTraitsTest : protected GLBase
26 26
             GLTRAITS_TEST_VALUE(#NAME, std::dec << Traits::NAME)
27 27
         #define GLTRAITS_TEST_VALUE_BOOL(NAME) \
28 28
             GLTRAITS_TEST_VALUE(#NAME, std::boolalpha << Traits::NAME)
29
+        #define GLTRAITS_TEST_VALUE_HEX(NAME) \
30
+            GLTRAITS_TEST_VALUE(#NAME, str_enum_(Traits::NAME))
29 31
         #define GLTRAITS_TEST_VALUE_ENUM(NAME, SUFFIX) \
30 32
             GLTRAITS_TEST_VALUE( \
31 33
                 #NAME #SUFFIX, \
... ...
@@ -42,7 +44,21 @@ struct GLTraitsTest : protected GLBase
42 44
             GLTRAITS_TEST_VALUE_ENUM(internal_format, _srgb)
43 45
             GLTRAITS_TEST_VALUE_ENUM(internal_format, _compressed)
44 46
             GLTRAITS_TEST_VALUE_ENUM(internal_format, _compressed_srgb)
45
-            GLTRAITS_TEST_VALUE_BOOL(integer);
47
+            GLTRAITS_TEST_VALUE_BOOL(integer)
48
+            GLTRAITS_TEST_VALUE_HEX(id);
49
+    }
50
+
51
+    template<GLenum id>
52
+    void static test_value_id()
53
+    {
54
+        using Traits = GLTraits::ValueID<id>;
55
+        static_assert(
56
+            std::is_empty<Traits>::value,
57
+            "GLTraits::ValueID must be empty"
58
+        );
59
+        std::cout
60
+            << "ValueID<" << str_enum_(id) << ">" << "\n"
61
+            << "  " << GLTraits::Value<typename Traits::Value>::name << "\n";
46 62
     }
47 63
 
48 64
 };
... ...
@@ -57,4 +73,12 @@ int main()
57 73
     GLTraitsTest::test_value<glm::mat4x3>();
58 74
     GLTraitsTest::test_value<glm::uvec2>();
59 75
     GLTraitsTest::test_value<glm::dvec2>();
76
+
77
+    GLTraitsTest::test_value_id<GL_FLOAT>();
78
+    GLTraitsTest::test_value_id<GL_BOOL>();
79
+    GLTraitsTest::test_value_id<GL_SHORT>();
80
+    GLTraitsTest::test_value_id<GL_DOUBLE>();
81
+    GLTraitsTest::test_value_id<GL_FLOAT_MAT4x3>();
82
+    GLTraitsTest::test_value_id<GL_UNSIGNED_INT_VEC2>();
83
+    GLTraitsTest::test_value_id<GL_DOUBLE_VEC2>();
60 84
 }