Browse code

Add implementation

Robert Cranston authored on 14/10/2022 20:41:19
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,1034 @@
1
+/// Includes
2
+
3
+
4
+#include <glbase.hpp>
5
+
6
+#include <algorithm>
7
+#include <array>
8
+#include <cstdio>
9
+#include <fstream>
10
+#include <iostream>
11
+#include <iterator>
12
+#include <sstream>
13
+#include <string>
14
+#include <unordered_set>
15
+
16
+#define STR_EXCEPTION GLBase::Exception
17
+#include <str.hpp>
18
+
19
+
20
+/// Base
21
+
22
+
23
+GLBASE_GLOBAL(GLBase::version_max_, {})
24
+
25
+
26
+bool GLBase::supported(
27
+    Version             version_min,
28
+    std::string const & extension
29
+)
30
+{
31
+    if (!extension.empty() && extension.rfind("GL_", 0) == std::string::npos)
32
+        STR_THROW("Failed to parse extension \"" << extension << "\".");
33
+    auto static thread_local version    = Version{};
34
+    auto static thread_local extensions = std::unordered_set<std::string>{};
35
+    if (version == Version{})
36
+    {
37
+        auto const * version_str = string(GL_VERSION);
38
+        if (!version_str)
39
+            return false;
40
+        // NOLINTNEXTLINE
41
+        if (std::sscanf(version_str, "%d.%d", &version[0], &version[1]) != 2)
42
+            STR_THROW("Failed to parse version \"" << version_str << "\".");
43
+        if (version[0] >= 3)
44
+        {
45
+            auto count = (GLuint)integer(GL_NUM_EXTENSIONS);
46
+            for (auto index = GLuint{0}; index < count; ++index)
47
+            {
48
+                auto const * extension_str = string(GL_EXTENSIONS, index);
49
+                if (extension_str)
50
+                    extensions.insert(extension_str);
51
+            }
52
+        }
53
+        else
54
+        {
55
+            auto const * extensions_str = string(GL_EXTENSIONS);
56
+            if (!extensions_str)
57
+                return false;
58
+            auto istream = std::istringstream(extensions_str);
59
+            using iterator = std::istream_iterator<std::string>;
60
+            std::copy(
61
+                iterator(istream),
62
+                iterator(),
63
+                std::inserter(extensions, extensions.end())
64
+            );
65
+        }
66
+    }
67
+    if (version_max() != Version{})
68
+        if
69
+        (
70
+            version_min[0] > version_max()[0] ||
71
+            (
72
+                version_min[0] == version_max()[0] &&
73
+                version_min[1] >  version_max()[1]
74
+            )
75
+        )
76
+            return false;
77
+    if (version_min != Version{})
78
+        if
79
+        (
80
+            version[0] > version_min[0] ||
81
+            (
82
+                version[0] == version_min[0] &&
83
+                version[1] >= version_min[1]
84
+            )
85
+        )
86
+            return true;
87
+    if (!extension.empty())
88
+        if (extensions.find(extension) != extensions.end())
89
+            return true;
90
+    return false;
91
+}
92
+
93
+
94
+char const * GLBase::string(GLenum name)
95
+try
96
+{
97
+    auto const * string = (char const *)glGetString(name);
98
+    check_error_(glGetError());
99
+    return string;
100
+}
101
+catch (...)
102
+{
103
+    fail_action_("get string", str_enum_(name));
104
+}
105
+
106
+
107
+char const * GLBase::string(GLenum name, GLuint index)
108
+try
109
+{
110
+    // if (debug() >= 1)
111
+    //     check_supported({3, 0});
112
+    auto const * string = (char const *)glGetStringi(name, index);
113
+    check_error_(glGetError());
114
+    return string;
115
+}
116
+catch (...)
117
+{
118
+    fail_action_("get string", STR(str_enum_(name) << "[" << index << "]"));
119
+}
120
+
121
+
122
+GLint GLBase::integer(GLenum name)
123
+try
124
+{
125
+    auto integer = GLint{};
126
+    glGetIntegerv(name, &integer);
127
+    check_error_(glGetError());
128
+    return integer;
129
+}
130
+catch (...)
131
+{
132
+    fail_action_("get integer", str_enum_(name));
133
+}
134
+
135
+
136
+/// Path
137
+
138
+
139
+GLBase::Path GLBase::path_prefix_(
140
+    Path const & path,
141
+    Path const & prefix
142
+)
143
+{
144
+    check_path_(path);
145
+    if (prefix.empty() || path[0] == '/')
146
+        return path;
147
+    return STR(prefix << "/" << path);
148
+}
149
+
150
+
151
+/// TGA
152
+
153
+
154
+GLBase::TGA_::TGA_(Size size, Data data, Path const & path)
155
+try
156
+:
157
+    size_{size},
158
+    data_{std::move(data)}
159
+{
160
+    check_data_size_();
161
+}
162
+catch (...)
163
+{
164
+    fail_action_("create", name_(path));
165
+}
166
+
167
+
168
+GLBase::TGA_ GLBase::TGA_::read(Path const & path)
169
+try
170
+{
171
+    auto istream = std::ifstream(path, std::ios::binary);
172
+    auto header  = Header_({});
173
+    istream.read((char *)header.data(), (std::streamsize)header.size());
174
+    check_header_(header);
175
+    auto size = header.tga_size();
176
+    auto data = Data(4 * (std::size_t)size[0] * (std::size_t)size[1]);
177
+    istream.read((char *)data.data(), (std::streamsize)data.size());
178
+    if (!istream)
179
+        STR_THROW_ERRNO();
180
+    if (!istream.eof())
181
+        STR_THROW("Garbage at end of file.");
182
+    return TGA_(size, std::move(data), path);;
183
+}
184
+catch (...)
185
+{
186
+    fail_action_("read", name_(path));
187
+}
188
+
189
+
190
+void GLBase::TGA_::write(Path const & path) const
191
+try
192
+{
193
+    auto header  = Header_(size());
194
+    auto ostream = std::ofstream(path, std::ios::binary);
195
+    ostream.write((char *)header.data(), (std::streamsize)header.size());
196
+    ostream.write((char *)data_ .data(), (std::streamsize)data_ .size());
197
+    if (!ostream)
198
+        STR_THROW_ERRNO();
199
+}
200
+catch (...)
201
+{
202
+    fail_action_("write", name_(path));
203
+}
204
+
205
+
206
+GLBase::TGA_::Header_::Header_(Size size)
207
+:
208
+    std::array<GLubyte, 18>{                // NOLINT
209
+        0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, // NOLINT
210
+        (GLubyte)(size[0] >> 0),            // NOLINT
211
+        (GLubyte)(size[0] >> 8),            // NOLINT
212
+        (GLubyte)(size[1] >> 0),            // NOLINT
213
+        (GLubyte)(size[1] >> 8),            // NOLINT
214
+        32, 0,                              // NOLINT
215
+    }
216
+{
217
+}
218
+
219
+
220
+GLBase::TGA_::Size GLBase::TGA_::Header_::tga_size() const
221
+{
222
+    return {
223
+        (GLsizei)((*this)[12]) << 0 | // NOLINT
224
+        (GLsizei)((*this)[13]) << 8,  // NOLINT
225
+        (GLsizei)((*this)[14]) << 0 | // NOLINT
226
+        (GLsizei)((*this)[15]) << 8,  // NOLINT
227
+    };
228
+}
229
+
230
+
231
+std::string GLBase::TGA_::name_(Path const & path)
232
+{
233
+    return STR("TGA" << " " << str_path_(path));
234
+}
235
+
236
+
237
+void GLBase::TGA_::check_header_(Header_ const & header)
238
+{
239
+    auto header_ = Header_(header.tga_size());
240
+    if (header != header_)
241
+        STR_THROW(
242
+            "Expected TGA header"                      << " " <<
243
+            "[" << STR_JOIN(", ", byte, byte, header_) << "]" << ", " <<
244
+            "got"                                      << " " <<
245
+            "[" << STR_JOIN(", ", byte, byte, header)  << "]" << "."
246
+        );
247
+}
248
+
249
+
250
+void GLBase::TGA_::check_data_size_() const
251
+{
252
+    auto size = this->size();
253
+    auto data_size = (std::size_t)(4 * size[0] * size[1]);
254
+    if (data_size != data_.size())
255
+        STR_THROW(
256
+            "Expected TGA data size " << data_size    << ", " <<
257
+            "got "                    << data_.size() << "."
258
+        );
259
+}
260
+
261
+
262
+//// Debug
263
+
264
+
265
+GLBASE_GLOBAL(GLBase::debug_,          {0})
266
+GLBASE_GLOBAL(GLBase::debug_callback_, {[](std::string const & message) {
267
+    std::cerr << message << std::endl;
268
+}})
269
+
270
+
271
+int GLBase::debug(int debug)
272
+{
273
+    auto debug_old = debug_;
274
+    debug_         = debug;
275
+    if (supported({4, 3}, "GL_KHR_debug"))
276
+    {
277
+        if (debug_old && !debug)
278
+            glDisable(GL_DEBUG_OUTPUT);
279
+        if (!debug_old && debug)
280
+        {
281
+            glEnable(GL_DEBUG_OUTPUT);
282
+            glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
283
+            glDebugMessageControl(
284
+                GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE,
285
+                0, nullptr,
286
+                GL_TRUE
287
+            );
288
+        }
289
+        if (debug_old >= 2 && debug < 2)
290
+            glDebugMessageControl(
291
+                GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
292
+                0, nullptr,
293
+                GL_FALSE
294
+            );
295
+        if (debug_old < 2 && debug >= 2)
296
+            glDebugMessageControl(
297
+                GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
298
+                0, nullptr,
299
+                GL_TRUE
300
+            );
301
+    }
302
+    return debug_old;
303
+}
304
+
305
+
306
+void GLBase::debug_action_(
307
+    std::string const & action,
308
+    std::string const & name
309
+)
310
+{
311
+    debug_message(STR("Trying to " << action << " " << name << "."));
312
+}
313
+
314
+
315
+/// Check
316
+
317
+
318
+void GLBase::check_path_(Path const & path)
319
+{
320
+    if (path.empty())
321
+        STR_THROW(
322
+            "Expected " << "non-empty path" << ", " <<
323
+            "got "      << str_path_(path)  << "."
324
+        );
325
+}
326
+
327
+
328
+void GLBase::check_error_(GLenum error)
329
+{
330
+    if (error != GL_NO_ERROR)
331
+        STR_THROW(
332
+            "Expected " << "no error"        << ", " <<
333
+            "got "      << str_error_(error) << "."
334
+        );
335
+}
336
+
337
+
338
+void GLBase::check_supported(
339
+    Version             version_min,
340
+    std::string const & extension
341
+)
342
+{
343
+    if (!supported(version_min, extension))
344
+    {
345
+        auto const * version_str = string(GL_VERSION);
346
+        STR_THROW(
347
+            "Expected OpenGL version >=" <<
348
+                STR_JOIN(".", it, it, version_min) <<
349
+                (
350
+                    !extension.empty()
351
+                        ? STR(" or extension " << extension)
352
+                        : ""
353
+                ) <<
354
+            ", " <<
355
+            "got " <<
356
+                (
357
+                    version_str
358
+                        ? version_str
359
+                        : "none (no current context?)"
360
+                ) <<
361
+            "."
362
+        );
363
+    }
364
+}
365
+
366
+
367
+void GLBase::check_type_(
368
+    GLenum type,
369
+    GLenum type_expected
370
+)
371
+{
372
+    if (type != type_expected)
373
+        STR_THROW(
374
+            "Expected type " << str_type_(type_expected) << ", " <<
375
+            "got "           << str_type_(type)          << "."
376
+        );
377
+}
378
+
379
+
380
+void GLBase::check_format_(
381
+    GLenum format,
382
+    GLenum format_expected
383
+)
384
+{
385
+    if (format != format_expected)
386
+        STR_THROW(
387
+            "Expected format " << str_format_(format_expected) << ", " <<
388
+            "got "             << str_format_(format)          << "."
389
+        );
390
+}
391
+
392
+
393
+void GLBase::check_internal_format_(GLenum internal_format)
394
+{
395
+    switch (internal_format)
396
+    {
397
+        case GL_RED:
398
+        case GL_RGB:
399
+        case GL_RGBA:
400
+        case GL_DEPTH_COMPONENT:
401
+        case GL_STENCIL_INDEX:
402
+            check_supported({1, 0});
403
+            return;
404
+        case GL_R3_G3_B2:
405
+            check_supported({1, 1});
406
+            return;
407
+        case GL_RGB4:
408
+        case GL_RGB5:
409
+        case GL_RGB8:
410
+        case GL_RGB10:
411
+        case GL_RGB12:
412
+        case GL_RGB16:
413
+        case GL_RGB5_A1:
414
+        case GL_RGB10_A2:
415
+        case GL_RGBA2:
416
+        case GL_RGBA4:
417
+        case GL_RGBA8:
418
+        case GL_RGBA12:
419
+        case GL_RGBA16:
420
+            check_supported({1, 1}, "GL_EXT_texture");
421
+            return;
422
+        case GL_RGB2_EXT:
423
+            check_supported({}, "GL_EXT_texture");
424
+            return;
425
+        case GL_COMPRESSED_RGB:
426
+        case GL_COMPRESSED_RGBA:
427
+            check_supported({1, 3}, "GL_ARB_texture_compression");
428
+            return;
429
+        case GL_DEPTH_COMPONENT16:
430
+        case GL_DEPTH_COMPONENT24:
431
+        case GL_DEPTH_COMPONENT32:
432
+            check_supported({1, 4}, "GL_ARB_depth_texture");
433
+            return;
434
+        case GL_SRGB:
435
+        case GL_SRGB8:
436
+        case GL_SRGB_ALPHA:
437
+        case GL_SRGB8_ALPHA8:
438
+        case GL_COMPRESSED_SRGB:
439
+        case GL_COMPRESSED_SRGB_ALPHA:
440
+            check_supported({2, 1}, "GL_EXT_texture_sRGB");
441
+            return;
442
+        case GL_SR8_EXT:
443
+            check_supported({}, "GL_EXT_texture_sRGB_R8");
444
+            return;
445
+        case GL_SRG8_EXT:
446
+            check_supported({}, "GL_EXT_texture_sRGB_RG8");
447
+            return;
448
+        case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
449
+        case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
450
+        case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
451
+        case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
452
+            check_supported({}, "GL_EXT_texture_compression_s3tc");
453
+            return;
454
+        case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
455
+        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
456
+        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
457
+        case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
458
+            check_supported({}, "GL_EXT_texture_sRGB");
459
+            check_supported({}, "GL_EXT_texture_compression_s3tc");
460
+            return;
461
+        case GL_COMPRESSED_RED:
462
+        case GL_COMPRESSED_RG:
463
+            check_supported({3, 0});
464
+            return;
465
+        case GL_COMPRESSED_RED_RGTC1:
466
+        case GL_COMPRESSED_RG_RGTC2:
467
+        case GL_COMPRESSED_SIGNED_RED_RGTC1:
468
+        case GL_COMPRESSED_SIGNED_RG_RGTC2:
469
+            check_supported({3, 0}, "GL_ARB_texture_compression_rgtc");
470
+            return;
471
+        case GL_RGB16F:
472
+        case GL_RGB32F:
473
+        case GL_RGBA16F:
474
+        case GL_RGBA32F:
475
+            check_supported({3, 0}, "GL_ARB_texture_float");
476
+            return;
477
+        case GL_RGB8I:
478
+        case GL_RGB8UI:
479
+        case GL_RGB16I:
480
+        case GL_RGB16UI:
481
+        case GL_RGB32I:
482
+        case GL_RGB32UI:
483
+        case GL_RGBA8I:
484
+        case GL_RGBA8UI:
485
+        case GL_RGBA16I:
486
+        case GL_RGBA16UI:
487
+        case GL_RGBA32I:
488
+        case GL_RGBA32UI:
489
+            check_supported({3, 0}, "GL_EXT_texture_integer");
490
+            return;
491
+        case GL_R8:
492
+        case GL_R8I:
493
+        case GL_R8UI:
494
+        case GL_R16:
495
+        case GL_R16I:
496
+        case GL_R16UI:
497
+        case GL_R32I:
498
+        case GL_R32UI:
499
+        case GL_R16F:
500
+        case GL_R32F:
501
+        case GL_RG:
502
+        case GL_RG8:
503
+        case GL_RG8I:
504
+        case GL_RG8UI:
505
+        case GL_RG16:
506
+        case GL_RG16I:
507
+        case GL_RG16UI:
508
+        case GL_RG32I:
509
+        case GL_RG32UI:
510
+        case GL_RG16F:
511
+        case GL_RG32F:
512
+            check_supported({3, 0}, "GL_ARB_texture_rg");
513
+            return;
514
+        case GL_R11F_G11F_B10F:
515
+            check_supported({3, 0}, "GL_EXT_packed_float");
516
+            return;
517
+        case GL_RGB9_E5:
518
+            check_supported({3, 0}, "GL_EXT_texture_shared_exponent");
519
+            return;
520
+        case GL_DEPTH_STENCIL:
521
+        case GL_DEPTH24_STENCIL8:
522
+            check_supported({3, 0}, "GL_EXT_packed_depth_stencil");
523
+            return;
524
+        case GL_DEPTH32F_STENCIL8:
525
+        case GL_DEPTH_COMPONENT32F:
526
+            check_supported({3, 0}, "GL_ARB_depth_buffer_float");
527
+            return;
528
+        case GL_STENCIL_INDEX1:
529
+        case GL_STENCIL_INDEX4:
530
+        case GL_STENCIL_INDEX8:
531
+        case GL_STENCIL_INDEX16:
532
+            check_supported({3, 0}, "GL_ARB_framebuffer_object");
533
+            return;
534
+        case GL_R8_SNORM:
535
+        case GL_R16_SNORM:
536
+        case GL_RG8_SNORM:
537
+        case GL_RG16_SNORM:
538
+        case GL_RGB8_SNORM:
539
+        case GL_RGB16_SNORM:
540
+        case GL_RGBA8_SNORM:
541
+        case GL_RGBA16_SNORM:
542
+            check_supported({3, 1}, "GL_EXT_texture_snorm");
543
+            return;
544
+        case GL_RGB10_A2UI:
545
+            check_supported({3, 3}, "GL_ARB_texture_rgb10_a2ui");
546
+            return;
547
+        case GL_RGB565:
548
+            check_supported({4, 1}, "GL_ARB_ES2_compatibility");
549
+            return;
550
+        case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT:
551
+        case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT:
552
+        case GL_COMPRESSED_RGBA_BPTC_UNORM:
553
+        case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM:
554
+            check_supported({4, 2}, "GL_ARB_texture_compression_bptc");
555
+            return;
556
+        case GL_COMPRESSED_RGB8_ETC2:
557
+        case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
558
+        case GL_COMPRESSED_SRGB8_ETC2:
559
+        case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
560
+        case GL_COMPRESSED_RGBA8_ETC2_EAC:
561
+        case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
562
+        case GL_COMPRESSED_R11_EAC:
563
+        case GL_COMPRESSED_RG11_EAC:
564
+        case GL_COMPRESSED_SIGNED_R11_EAC:
565
+        case GL_COMPRESSED_SIGNED_RG11_EAC:
566
+            check_supported({4, 3}, "GL_ARB_ES3_compatibility");
567
+            return;
568
+        case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
569
+        case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
570
+        case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
571
+        case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
572
+        case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
573
+        case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
574
+        case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
575
+        case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
576
+        case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
577
+        case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
578
+        case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
579
+        case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
580
+        case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
581
+        case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
582
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
583
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
584
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
585
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
586
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
587
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
588
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
589
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
590
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
591
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
592
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
593
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
594
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
595
+        case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
596
+            check_supported({}, "GL_KHR_texture_compression_astc_ldr");
597
+            return;
598
+        default:
599
+            STR_THROW(
600
+                "Expected " << "internal format"                     << ", " <<
601
+                "got "      << str_internal_format_(internal_format) << "."
602
+            );
603
+    }
604
+}
605
+
606
+
607
+/// Fail
608
+
609
+
610
+void GLBase::fail_action_(
611
+    std::string const & action,
612
+    std::string const & name
613
+)
614
+{
615
+    STR_RETHROW("Failed to " << action << " " << name << ":\n");
616
+}
617
+
618
+
619
+/// String
620
+
621
+
622
+std::string GLBase::str_path_(Path const & path)
623
+{
624
+    return STR("\"" << path << "\"");
625
+}
626
+
627
+
628
+std::string GLBase::str_paths_(Paths const & paths)
629
+{
630
+    return STR_JOIN(", ", path, str_path_(path), paths);
631
+}
632
+
633
+
634
+std::string GLBase::str_enum_(GLenum name)
635
+{
636
+    return STR(std::hex << std::showbase << std::uppercase << name);
637
+}
638
+
639
+
640
+std::string GLBase::str_error_(GLenum error)
641
+{
642
+    switch (error)
643
+    {
644
+        STR_CASE(GL_NO_ERROR)
645
+        STR_CASE(GL_INVALID_ENUM)
646
+        STR_CASE(GL_INVALID_VALUE)
647
+        STR_CASE(GL_INVALID_OPERATION)
648
+        STR_CASE(GL_INVALID_FRAMEBUFFER_OPERATION)
649
+        STR_CASE(GL_OUT_OF_MEMORY)
650
+        STR_CASE(GL_STACK_OVERFLOW)
651
+        STR_CASE(GL_STACK_UNDERFLOW)
652
+        STR_CASE(GL_CONTEXT_LOST) // GL_KHR_robustness
653
+        default:
654
+            return str_enum_(error);
655
+    }
656
+}
657
+
658
+
659
+std::string GLBase::str_object_type_(GLenum object_type)
660
+{
661
+    switch (object_type)
662
+    {
663
+        STR_CASE(GL_TEXTURE)
664
+        STR_CASE(GL_BUFFER)
665
+        STR_CASE(GL_SHADER)
666
+        STR_CASE(GL_PROGRAM)
667
+        STR_CASE(GL_PROGRAM_PIPELINE)
668
+        STR_CASE(GL_FRAMEBUFFER)
669
+        STR_CASE(GL_RENDERBUFFER)
670
+        STR_CASE(GL_VERTEX_ARRAY)
671
+        STR_CASE(GL_TRANSFORM_FEEDBACK)
672
+        STR_CASE(GL_SAMPLER)
673
+        STR_CASE(GL_QUERY)
674
+        default:
675
+            return str_enum_(object_type);
676
+    }
677
+}
678
+
679
+
680
+std::string GLBase::str_glsl_(GLenum glsl)
681
+{
682
+    switch (glsl)
683
+    {
684
+        STR_CASE(GL_FLOAT)
685
+        STR_CASE(GL_FLOAT_VEC2)
686
+        STR_CASE(GL_FLOAT_VEC3)
687
+        STR_CASE(GL_FLOAT_VEC4)
688
+        STR_CASE(GL_FLOAT_MAT2)
689
+        STR_CASE(GL_FLOAT_MAT2x3)
690
+        STR_CASE(GL_FLOAT_MAT2x4)
691
+        STR_CASE(GL_FLOAT_MAT3x2)
692
+        STR_CASE(GL_FLOAT_MAT3)
693
+        STR_CASE(GL_FLOAT_MAT3x4)
694
+        STR_CASE(GL_FLOAT_MAT4x2)
695
+        STR_CASE(GL_FLOAT_MAT4x3)
696
+        STR_CASE(GL_FLOAT_MAT4)
697
+        STR_CASE(GL_INT)
698
+        STR_CASE(GL_INT_VEC2)
699
+        STR_CASE(GL_INT_VEC3)
700
+        STR_CASE(GL_INT_VEC4)
701
+        STR_CASE(GL_UNSIGNED_INT)
702
+        STR_CASE(GL_UNSIGNED_INT_VEC2)
703
+        STR_CASE(GL_UNSIGNED_INT_VEC3)
704
+        STR_CASE(GL_UNSIGNED_INT_VEC4)
705
+        STR_CASE(GL_DOUBLE)
706
+        STR_CASE(GL_DOUBLE_VEC2)
707
+        STR_CASE(GL_DOUBLE_VEC3)
708
+        STR_CASE(GL_DOUBLE_VEC4)
709
+        STR_CASE(GL_DOUBLE_MAT2)
710
+        STR_CASE(GL_DOUBLE_MAT2x3)
711
+        STR_CASE(GL_DOUBLE_MAT2x4)
712
+        STR_CASE(GL_DOUBLE_MAT3x2)
713
+        STR_CASE(GL_DOUBLE_MAT3)
714
+        STR_CASE(GL_DOUBLE_MAT3x4)
715
+        STR_CASE(GL_DOUBLE_MAT4x2)
716
+        STR_CASE(GL_DOUBLE_MAT4x3)
717
+        STR_CASE(GL_DOUBLE_MAT4)
718
+        STR_CASE(GL_BOOL)
719
+        STR_CASE(GL_BOOL_VEC2)
720
+        STR_CASE(GL_BOOL_VEC3)
721
+        STR_CASE(GL_BOOL_VEC4)
722
+        STR_CASE(GL_SAMPLER_1D)
723
+        STR_CASE(GL_SAMPLER_1D_SHADOW)
724
+        STR_CASE(GL_SAMPLER_1D_ARRAY)
725
+        STR_CASE(GL_SAMPLER_1D_ARRAY_SHADOW)
726
+        STR_CASE(GL_SAMPLER_2D)
727
+        STR_CASE(GL_SAMPLER_2D_SHADOW)
728
+        STR_CASE(GL_SAMPLER_2D_ARRAY)
729
+        STR_CASE(GL_SAMPLER_2D_ARRAY_SHADOW)
730
+        STR_CASE(GL_SAMPLER_2D_RECT)
731
+        STR_CASE(GL_SAMPLER_2D_RECT_SHADOW)
732
+        STR_CASE(GL_SAMPLER_2D_MULTISAMPLE)
733
+        STR_CASE(GL_SAMPLER_2D_MULTISAMPLE_ARRAY)
734
+        STR_CASE(GL_SAMPLER_3D)
735
+        STR_CASE(GL_SAMPLER_CUBE)
736
+        STR_CASE(GL_SAMPLER_CUBE_SHADOW)
737
+        STR_CASE(GL_SAMPLER_CUBE_MAP_ARRAY)
738
+        STR_CASE(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW)
739
+        STR_CASE(GL_SAMPLER_BUFFER)
740
+        STR_CASE(GL_INT_SAMPLER_1D)
741
+        STR_CASE(GL_INT_SAMPLER_1D_ARRAY)
742
+        STR_CASE(GL_INT_SAMPLER_2D)
743
+        STR_CASE(GL_INT_SAMPLER_2D_ARRAY)
744
+        STR_CASE(GL_INT_SAMPLER_2D_RECT)
745
+        STR_CASE(GL_INT_SAMPLER_2D_MULTISAMPLE)
746
+        STR_CASE(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY)
747
+        STR_CASE(GL_INT_SAMPLER_3D)
748
+        STR_CASE(GL_INT_SAMPLER_CUBE)
749
+        STR_CASE(GL_INT_SAMPLER_CUBE_MAP_ARRAY)
750
+        STR_CASE(GL_INT_SAMPLER_BUFFER)
751
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_1D)
752
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY)
753
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D)
754
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY)
755
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_RECT)
756
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE)
757
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY)
758
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_3D)
759
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_CUBE)
760
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY)
761
+        STR_CASE(GL_UNSIGNED_INT_SAMPLER_BUFFER)
762
+        STR_CASE(GL_IMAGE_1D)
763
+        STR_CASE(GL_IMAGE_1D_ARRAY)
764
+        STR_CASE(GL_IMAGE_2D)
765
+        STR_CASE(GL_IMAGE_2D_ARRAY)
766
+        STR_CASE(GL_IMAGE_2D_RECT)
767
+        STR_CASE(GL_IMAGE_2D_MULTISAMPLE)
768
+        STR_CASE(GL_IMAGE_2D_MULTISAMPLE_ARRAY)
769
+        STR_CASE(GL_IMAGE_3D)
770
+        STR_CASE(GL_IMAGE_CUBE)
771
+        STR_CASE(GL_IMAGE_CUBE_MAP_ARRAY)
772
+        STR_CASE(GL_IMAGE_BUFFER)
773
+        STR_CASE(GL_INT_IMAGE_1D)
774
+        STR_CASE(GL_INT_IMAGE_1D_ARRAY)
775
+        STR_CASE(GL_INT_IMAGE_2D)
776
+        STR_CASE(GL_INT_IMAGE_2D_ARRAY)
777
+        STR_CASE(GL_INT_IMAGE_2D_RECT)
778
+        STR_CASE(GL_INT_IMAGE_2D_MULTISAMPLE)
779
+        STR_CASE(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY)
780
+        STR_CASE(GL_INT_IMAGE_3D)
781
+        STR_CASE(GL_INT_IMAGE_CUBE)
782
+        STR_CASE(GL_INT_IMAGE_CUBE_MAP_ARRAY)
783
+        STR_CASE(GL_INT_IMAGE_BUFFER)
784
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_1D)
785
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_1D_ARRAY)
786
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_2D)
787
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_ARRAY)
788
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_RECT)
789
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE)
790
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY)
791
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_3D)
792
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_CUBE)
793
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY)
794
+        STR_CASE(GL_UNSIGNED_INT_IMAGE_BUFFER)
795
+        // GL_ARB_gpu_shader_int64
796
+        STR_CASE(GL_INT64_ARB)
797
+        STR_CASE(GL_INT64_VEC2_ARB)
798
+        STR_CASE(GL_INT64_VEC3_ARB)
799
+        STR_CASE(GL_INT64_VEC4_ARB)
800
+        STR_CASE(GL_UNSIGNED_INT64_ARB) // GL_ARB_bindless_texture
801
+        STR_CASE(GL_UNSIGNED_INT64_VEC2_ARB)
802
+        STR_CASE(GL_UNSIGNED_INT64_VEC3_ARB)
803
+        STR_CASE(GL_UNSIGNED_INT64_VEC4_ARB)
804
+        default:
805
+            return str_enum_(glsl);
806
+    }
807
+}
808
+
809
+
810
+std::string GLBase::str_format_(GLenum format)
811
+{
812
+    switch (format)
813
+    {
814
+        STR_CASE(GL_RED)
815
+        STR_CASE(GL_RED_INTEGER)
816
+        STR_CASE(GL_GREEN)
817
+        STR_CASE(GL_GREEN_INTEGER)
818
+        STR_CASE(GL_BLUE)
819
+        STR_CASE(GL_BLUE_INTEGER)
820
+        STR_CASE(GL_ALPHA)
821
+        STR_CASE(GL_ALPHA_INTEGER)
822
+        STR_CASE(GL_RG)
823
+        STR_CASE(GL_RG_INTEGER)
824
+        STR_CASE(GL_RGB)
825
+        STR_CASE(GL_RGB_INTEGER)
826
+        STR_CASE(GL_RGBA)
827
+        STR_CASE(GL_RGBA_INTEGER)
828
+        STR_CASE(GL_BGR)
829
+        STR_CASE(GL_BGR_INTEGER)
830
+        STR_CASE(GL_BGRA)
831
+        STR_CASE(GL_BGRA_INTEGER)
832
+        STR_CASE(GL_ABGR_EXT) // GL_EXT_abgr
833
+        STR_CASE(GL_DEPTH_STENCIL)
834
+        STR_CASE(GL_DEPTH_COMPONENT)
835
+        STR_CASE(GL_STENCIL_INDEX)
836
+        default:
837
+            return str_enum_(format);
838
+    }
839
+}
840
+
841
+
842
+std::string GLBase::str_type_(GLenum type)
843
+{
844
+    switch (type)
845
+    {
846
+        STR_CASE(GL_FLOAT)
847
+        STR_CASE(GL_BYTE)
848
+        STR_CASE(GL_SHORT)
849
+        STR_CASE(GL_INT)
850
+        STR_CASE(GL_UNSIGNED_BYTE)
851
+        STR_CASE(GL_UNSIGNED_SHORT)
852
+        STR_CASE(GL_UNSIGNED_INT)
853
+        STR_CASE(GL_UNSIGNED_BYTE_3_3_2)
854
+        STR_CASE(GL_UNSIGNED_BYTE_2_3_3_REV)
855
+        STR_CASE(GL_UNSIGNED_SHORT_5_6_5)
856
+        STR_CASE(GL_UNSIGNED_SHORT_5_6_5_REV)
857
+        STR_CASE(GL_UNSIGNED_SHORT_4_4_4_4)
858
+        STR_CASE(GL_UNSIGNED_SHORT_4_4_4_4_REV)
859
+        STR_CASE(GL_UNSIGNED_SHORT_5_5_5_1)
860
+        STR_CASE(GL_UNSIGNED_SHORT_1_5_5_5_REV)
861
+        STR_CASE(GL_UNSIGNED_INT_8_8_8_8)
862
+        STR_CASE(GL_UNSIGNED_INT_8_8_8_8_REV)
863
+        STR_CASE(GL_UNSIGNED_INT_10_10_10_2)
864
+        STR_CASE(GL_UNSIGNED_INT_2_10_10_10_REV)
865
+        STR_CASE(GL_UNSIGNED_INT_10F_11F_11F_REV)
866
+        STR_CASE(GL_UNSIGNED_INT_5_9_9_9_REV)
867
+        STR_CASE(GL_UNSIGNED_INT_24_8)
868
+        STR_CASE(GL_FLOAT_32_UNSIGNED_INT_24_8_REV)
869
+        STR_CASE(GL_DOUBLE)
870
+        STR_CASE(GL_HALF_FLOAT)
871
+        STR_CASE(GL_FIXED)
872
+        // GL_ARB_gpu_shader_int64
873
+        STR_CASE(GL_INT64_ARB)
874
+        STR_CASE(GL_UNSIGNED_INT64_ARB) // GL_ARB_bindless_texture
875
+        default:
876
+            return str_enum_(type);
877
+    }
878
+}
879
+
880
+
881
+std::string GLBase::str_internal_format_(GLenum internal_format)
882
+{
883
+    switch (internal_format)
884
+    {
885
+        STR_CASE(GL_RED)
886
+        STR_CASE(GL_R8)
887
+        STR_CASE(GL_R8I)
888
+        STR_CASE(GL_R8UI)
889
+        STR_CASE(GL_R16)
890
+        STR_CASE(GL_R16I)
891
+        STR_CASE(GL_R16UI)
892
+        STR_CASE(GL_R32I)
893
+        STR_CASE(GL_R32UI)
894
+        STR_CASE(GL_R16F)
895
+        STR_CASE(GL_R32F)
896
+        STR_CASE(GL_RG)
897
+        STR_CASE(GL_RG8)
898
+        STR_CASE(GL_RG8I)
899
+        STR_CASE(GL_RG8UI)
900
+        STR_CASE(GL_RG16)
901
+        STR_CASE(GL_RG16I)
902
+        STR_CASE(GL_RG16UI)
903
+        STR_CASE(GL_RG32I)
904
+        STR_CASE(GL_RG32UI)
905
+        STR_CASE(GL_RG16F)
906
+        STR_CASE(GL_RG32F)
907
+        STR_CASE(GL_RGB)
908
+        STR_CASE(GL_RGB2_EXT) // GL_EXT_texture
909
+        STR_CASE(GL_R3_G3_B2)
910
+        STR_CASE(GL_RGB4)
911
+        STR_CASE(GL_RGB5)
912
+        STR_CASE(GL_RGB565)
913
+        STR_CASE(GL_RGB8)
914
+        STR_CASE(GL_RGB8I)
915
+        STR_CASE(GL_RGB8UI)
916
+        STR_CASE(GL_RGB10)
917
+        STR_CASE(GL_RGB12)
918
+        STR_CASE(GL_RGB16)
919
+        STR_CASE(GL_RGB16I)
920
+        STR_CASE(GL_RGB16UI)
921
+        STR_CASE(GL_RGB32I)
922
+        STR_CASE(GL_RGB32UI)
923
+        STR_CASE(GL_RGB16F)
924
+        STR_CASE(GL_RGB32F)
925
+        STR_CASE(GL_R11F_G11F_B10F)
926
+        STR_CASE(GL_RGB9_E5)
927
+        STR_CASE(GL_RGBA)
928
+        STR_CASE(GL_RGBA2)
929
+        STR_CASE(GL_RGBA4)
930
+        STR_CASE(GL_RGBA8)
931
+        STR_CASE(GL_RGBA8I)
932
+        STR_CASE(GL_RGBA8UI)
933
+        STR_CASE(GL_RGBA12)
934
+        STR_CASE(GL_RGBA16)
935
+        STR_CASE(GL_RGBA16I)
936
+        STR_CASE(GL_RGBA16UI)
937
+        STR_CASE(GL_RGBA32I)
938
+        STR_CASE(GL_RGBA32UI)
939
+        STR_CASE(GL_RGB5_A1)
940
+        STR_CASE(GL_RGB10_A2)
941
+        STR_CASE(GL_RGB10_A2UI)
942
+        STR_CASE(GL_RGBA16F)
943
+        STR_CASE(GL_RGBA32F)
944
+        STR_CASE(GL_R8_SNORM)
945
+        STR_CASE(GL_R16_SNORM)
946
+        STR_CASE(GL_RG8_SNORM)
947
+        STR_CASE(GL_RG16_SNORM)
948
+        STR_CASE(GL_RGB8_SNORM)
949
+        STR_CASE(GL_RGB16_SNORM)
950
+        STR_CASE(GL_RGBA8_SNORM)
951
+        STR_CASE(GL_RGBA16_SNORM)
952
+        STR_CASE(GL_SR8_EXT)  // GL_EXT_texture_sRGB_R8
953
+        STR_CASE(GL_SRG8_EXT) // GL_EXT_texture_sRGB_RG8
954
+        STR_CASE(GL_SRGB)
955
+        STR_CASE(GL_SRGB8)
956
+        STR_CASE(GL_SRGB_ALPHA)
957
+        STR_CASE(GL_SRGB8_ALPHA8)
958
+        STR_CASE(GL_DEPTH_STENCIL)
959
+        STR_CASE(GL_DEPTH24_STENCIL8)
960
+        STR_CASE(GL_DEPTH32F_STENCIL8)
961
+        STR_CASE(GL_DEPTH_COMPONENT)
962
+        STR_CASE(GL_DEPTH_COMPONENT16)
963
+        STR_CASE(GL_DEPTH_COMPONENT24)
964
+        STR_CASE(GL_DEPTH_COMPONENT32)
965
+        STR_CASE(GL_DEPTH_COMPONENT32F)
966
+        STR_CASE(GL_STENCIL_INDEX)
967
+        STR_CASE(GL_STENCIL_INDEX1)
968
+        STR_CASE(GL_STENCIL_INDEX4)
969
+        STR_CASE(GL_STENCIL_INDEX8)
970
+        STR_CASE(GL_STENCIL_INDEX16)
971
+        STR_CASE(GL_COMPRESSED_RED)
972
+        STR_CASE(GL_COMPRESSED_RG)
973
+        STR_CASE(GL_COMPRESSED_RGB)
974
+        STR_CASE(GL_COMPRESSED_RGBA)
975
+        STR_CASE(GL_COMPRESSED_SRGB)
976
+        STR_CASE(GL_COMPRESSED_SRGB_ALPHA)
977
+        STR_CASE(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
978
+        STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
979
+        STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
980
+        STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
981
+        STR_CASE(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT)
982
+        STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT)
983
+        STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT)
984
+        STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT)
985
+        STR_CASE(GL_COMPRESSED_RED_RGTC1)
986
+        STR_CASE(GL_COMPRESSED_RG_RGTC2)
987
+        STR_CASE(GL_COMPRESSED_SIGNED_RED_RGTC1)
988
+        STR_CASE(GL_COMPRESSED_SIGNED_RG_RGTC2)
989
+        STR_CASE(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT)
990
+        STR_CASE(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT)
991
+        STR_CASE(GL_COMPRESSED_RGBA_BPTC_UNORM)
992
+        STR_CASE(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM)
993
+        STR_CASE(GL_COMPRESSED_RGB8_ETC2)
994
+        STR_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2)
995
+        STR_CASE(GL_COMPRESSED_SRGB8_ETC2)
996
+        STR_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2)
997
+        STR_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC)
998
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC)
999
+        STR_CASE(GL_COMPRESSED_R11_EAC)
1000
+        STR_CASE(GL_COMPRESSED_RG11_EAC)
1001
+        STR_CASE(GL_COMPRESSED_SIGNED_R11_EAC)
1002
+        STR_CASE(GL_COMPRESSED_SIGNED_RG11_EAC)
1003
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_4x4_KHR)
1004
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_5x4_KHR)
1005
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_5x5_KHR)
1006
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_6x5_KHR)
1007
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_6x6_KHR)
1008
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x5_KHR)
1009
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x6_KHR)
1010
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x8_KHR)
1011
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x5_KHR)
1012
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x6_KHR)
1013
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x8_KHR)
1014
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x10_KHR)
1015
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_12x10_KHR)
1016
+        STR_CASE(GL_COMPRESSED_RGBA_ASTC_12x12_KHR)
1017
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR)
1018
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR)
1019
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR)
1020
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR)
1021
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR)
1022
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR)
1023
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR)
1024
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR)
1025
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR)
1026
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR)
1027
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR)
1028
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR)
1029
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR)
1030
+        STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR)
1031
+        default:
1032
+            return str_enum_(internal_format);
1033
+    }
1034
+}