/// Includes #include <glbase.hpp> #include <algorithm> #include <array> #include <cstdio> #include <fstream> #include <iostream> #include <iterator> #include <sstream> #include <string> #include <unordered_set> #define STR_EXCEPTION GLBase::Exception #include <str.hpp> /// Base GLBASE_GLOBAL(GLBase::version_max_, {}) bool GLBase::supported( Version version_min, std::string const & extension ) { if (!extension.empty() && extension.rfind("GL_", 0) == std::string::npos) STR_THROW("Failed to parse extension \"" << extension << "\"."); auto static thread_local version = Version{}; auto static thread_local extensions = std::unordered_set<std::string>{}; if (version == Version{}) { auto const * version_str = string(GL_VERSION); if (!version_str) return false; // NOLINTNEXTLINE if (std::sscanf(version_str, "%d.%d", &version[0], &version[1]) != 2) STR_THROW("Failed to parse version \"" << version_str << "\"."); if (version[0] >= 3) { auto count = (GLuint)integer(GL_NUM_EXTENSIONS); for (auto index = GLuint{0}; index < count; ++index) { auto const * extension_str = string(GL_EXTENSIONS, index); if (extension_str) extensions.insert(extension_str); } } else { auto const * extensions_str = string(GL_EXTENSIONS); if (!extensions_str) return false; auto istream = std::istringstream(extensions_str); using iterator = std::istream_iterator<std::string>; std::copy( iterator(istream), iterator(), std::inserter(extensions, extensions.end()) ); } } if (version_max() != Version{}) if ( version_min[0] > version_max()[0] || ( version_min[0] == version_max()[0] && version_min[1] > version_max()[1] ) ) return false; if (version_min != Version{}) if ( version[0] > version_min[0] || ( version[0] == version_min[0] && version[1] >= version_min[1] ) ) return true; if (!extension.empty()) if (extensions.find(extension) != extensions.end()) return true; return false; } char const * GLBase::string(GLenum name) try { auto const * string = (char const *)glGetString(name); check_error_(glGetError()); return string; } catch (...) { fail_action_("get string", str_enum_(name)); } char const * GLBase::string(GLenum name, GLuint index) try { // if (debug() >= 1) // check_supported({3, 0}); auto const * string = (char const *)glGetStringi(name, index); check_error_(glGetError()); return string; } catch (...) { fail_action_("get string", STR(str_enum_(name) << "[" << index << "]")); } GLint GLBase::integer(GLenum name) try { auto integer = GLint{}; glGetIntegerv(name, &integer); check_error_(glGetError()); return integer; } catch (...) { fail_action_("get integer", str_enum_(name)); } /// Path GLBase::Path GLBase::path_prefix_( Path const & path, Path const & prefix ) { check_path_(path); if (prefix.empty() || path[0] == '/') return path; return STR(prefix << "/" << path); } /// TGA GLBase::TGA_::TGA_(Size size, Data data, Path const & path) try : size_{size}, data_{std::move(data)} { check_data_size_(); } catch (...) { fail_action_("create", name_(path)); } GLBase::TGA_ GLBase::TGA_::read(Path const & path) try { auto istream = std::ifstream(path, std::ios::binary); auto header = Header_({}); istream.read((char *)header.data(), (std::streamsize)header.size()); check_header_(header); auto size = header.tga_size(); auto data = Data(4 * (std::size_t)size[0] * (std::size_t)size[1]); istream.read((char *)data.data(), (std::streamsize)data.size()); if (!istream) STR_THROW_ERRNO(); if (!istream.eof()) STR_THROW("Garbage at end of file."); return TGA_(size, std::move(data), path);; } catch (...) { fail_action_("read", name_(path)); } void GLBase::TGA_::write(Path const & path) const try { auto header = Header_(size()); auto ostream = std::ofstream(path, std::ios::binary); ostream.write((char *)header.data(), (std::streamsize)header.size()); ostream.write((char *)data_ .data(), (std::streamsize)data_ .size()); if (!ostream) STR_THROW_ERRNO(); } catch (...) { fail_action_("write", name_(path)); } GLBase::TGA_::Header_::Header_(Size size) : std::array<GLubyte, 18>{ // NOLINT 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, // NOLINT (GLubyte)(size[0] >> 0), // NOLINT (GLubyte)(size[0] >> 8), // NOLINT (GLubyte)(size[1] >> 0), // NOLINT (GLubyte)(size[1] >> 8), // NOLINT 32, 0, // NOLINT } { } GLBase::TGA_::Size GLBase::TGA_::Header_::tga_size() const { return { (GLsizei)((*this)[12]) << 0 | // NOLINT (GLsizei)((*this)[13]) << 8, // NOLINT (GLsizei)((*this)[14]) << 0 | // NOLINT (GLsizei)((*this)[15]) << 8, // NOLINT }; } std::string GLBase::TGA_::name_(Path const & path) { return STR("TGA" << " " << str_path_(path)); } void GLBase::TGA_::check_header_(Header_ const & header) { auto header_ = Header_(header.tga_size()); if (header != header_) STR_THROW( "Expected TGA header" << " " << "[" << STR_JOIN(", ", byte, byte, header_) << "]" << ", " << "got" << " " << "[" << STR_JOIN(", ", byte, byte, header) << "]" << "." ); } void GLBase::TGA_::check_data_size_() const { auto size = this->size(); auto data_size = (std::size_t)(4 * size[0] * size[1]); if (data_size != data_.size()) STR_THROW( "Expected TGA data size " << data_size << ", " << "got " << data_.size() << "." ); } //// Debug GLBASE_GLOBAL(GLBase::debug_, {0}) GLBASE_GLOBAL(GLBase::debug_callback_, {[](std::string const & message) { std::cerr << message << std::endl; }}) int GLBase::debug(int debug) { auto debug_old = debug_; debug_ = debug; if (supported({4, 3}, "GL_KHR_debug")) { if (debug_old && !debug) glDisable(GL_DEBUG_OUTPUT); if (!debug_old && debug) { glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE ); } if (debug_old >= 2 && debug < 2) glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_FALSE ); if (debug_old < 2 && debug >= 2) glDebugMessageControl( GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, nullptr, GL_TRUE ); } return debug_old; } void GLBase::debug_action_( std::string const & action, std::string const & name ) { debug_message(STR("Trying to " << action << " " << name << ".")); } /// Check void GLBase::check_path_(Path const & path) { if (path.empty()) STR_THROW( "Expected " << "non-empty path" << ", " << "got " << str_path_(path) << "." ); } void GLBase::check_error_(GLenum error) { if (error != GL_NO_ERROR) STR_THROW( "Expected " << "no error" << ", " << "got " << str_error_(error) << "." ); } void GLBase::check_supported( Version version_min, std::string const & extension ) { if (!supported(version_min, extension)) { auto const * version_str = string(GL_VERSION); STR_THROW( "Expected OpenGL version >=" << STR_JOIN(".", it, it, version_min) << ( !extension.empty() ? STR(" or extension " << extension) : "" ) << ", " << "got " << ( version_str ? version_str : "none (no current context?)" ) << "." ); } } void GLBase::check_type_( GLenum type, GLenum type_expected ) { if (type != type_expected) STR_THROW( "Expected type " << str_type_(type_expected) << ", " << "got " << str_type_(type) << "." ); } void GLBase::check_format_( GLenum format, GLenum format_expected ) { if (format != format_expected) STR_THROW( "Expected format " << str_format_(format_expected) << ", " << "got " << str_format_(format) << "." ); } void GLBase::check_internal_format_(GLenum internal_format) { switch (internal_format) { case GL_RED: case GL_RGB: case GL_RGBA: case GL_DEPTH_COMPONENT: case GL_STENCIL_INDEX: check_supported({1, 0}); return; case GL_R3_G3_B2: check_supported({1, 1}); return; case GL_RGB4: case GL_RGB5: case GL_RGB8: case GL_RGB10: case GL_RGB12: case GL_RGB16: case GL_RGB5_A1: case GL_RGB10_A2: case GL_RGBA2: case GL_RGBA4: case GL_RGBA8: case GL_RGBA12: case GL_RGBA16: check_supported({1, 1}, "GL_EXT_texture"); return; case GL_RGB2_EXT: check_supported({}, "GL_EXT_texture"); return; case GL_COMPRESSED_RGB: case GL_COMPRESSED_RGBA: check_supported({1, 3}, "GL_ARB_texture_compression"); return; case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: check_supported({1, 4}, "GL_ARB_depth_texture"); return; case GL_SRGB: case GL_SRGB8: case GL_SRGB_ALPHA: case GL_SRGB8_ALPHA8: case GL_COMPRESSED_SRGB: case GL_COMPRESSED_SRGB_ALPHA: check_supported({2, 1}, "GL_EXT_texture_sRGB"); return; case GL_SR8_EXT: check_supported({}, "GL_EXT_texture_sRGB_R8"); return; case GL_SRG8_EXT: check_supported({}, "GL_EXT_texture_sRGB_RG8"); return; case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: check_supported({}, "GL_EXT_texture_compression_s3tc"); return; case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: check_supported({}, "GL_EXT_texture_sRGB"); check_supported({}, "GL_EXT_texture_compression_s3tc"); return; case GL_COMPRESSED_RED: case GL_COMPRESSED_RG: check_supported({3, 0}); return; case GL_COMPRESSED_RED_RGTC1: case GL_COMPRESSED_RG_RGTC2: case GL_COMPRESSED_SIGNED_RED_RGTC1: case GL_COMPRESSED_SIGNED_RG_RGTC2: check_supported({3, 0}, "GL_ARB_texture_compression_rgtc"); return; case GL_RGB16F: case GL_RGB32F: case GL_RGBA16F: case GL_RGBA32F: check_supported({3, 0}, "GL_ARB_texture_float"); return; case GL_RGB8I: case GL_RGB8UI: case GL_RGB16I: case GL_RGB16UI: case GL_RGB32I: case GL_RGB32UI: case GL_RGBA8I: case GL_RGBA8UI: case GL_RGBA16I: case GL_RGBA16UI: case GL_RGBA32I: case GL_RGBA32UI: check_supported({3, 0}, "GL_EXT_texture_integer"); return; case GL_R8: case GL_R8I: case GL_R8UI: case GL_R16: case GL_R16I: case GL_R16UI: case GL_R32I: case GL_R32UI: case GL_R16F: case GL_R32F: case GL_RG: case GL_RG8: case GL_RG8I: case GL_RG8UI: case GL_RG16: case GL_RG16I: case GL_RG16UI: case GL_RG32I: case GL_RG32UI: case GL_RG16F: case GL_RG32F: check_supported({3, 0}, "GL_ARB_texture_rg"); return; case GL_R11F_G11F_B10F: check_supported({3, 0}, "GL_EXT_packed_float"); return; case GL_RGB9_E5: check_supported({3, 0}, "GL_EXT_texture_shared_exponent"); return; case GL_DEPTH_STENCIL: case GL_DEPTH24_STENCIL8: check_supported({3, 0}, "GL_EXT_packed_depth_stencil"); return; case GL_DEPTH32F_STENCIL8: case GL_DEPTH_COMPONENT32F: check_supported({3, 0}, "GL_ARB_depth_buffer_float"); return; case GL_STENCIL_INDEX1: case GL_STENCIL_INDEX4: case GL_STENCIL_INDEX8: case GL_STENCIL_INDEX16: check_supported({3, 0}, "GL_ARB_framebuffer_object"); return; case GL_R8_SNORM: case GL_R16_SNORM: case GL_RG8_SNORM: case GL_RG16_SNORM: case GL_RGB8_SNORM: case GL_RGB16_SNORM: case GL_RGBA8_SNORM: case GL_RGBA16_SNORM: check_supported({3, 1}, "GL_EXT_texture_snorm"); return; case GL_RGB10_A2UI: check_supported({3, 3}, "GL_ARB_texture_rgb10_a2ui"); return; case GL_RGB565: check_supported({4, 1}, "GL_ARB_ES2_compatibility"); return; case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: case GL_COMPRESSED_RGBA_BPTC_UNORM: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: check_supported({4, 2}, "GL_ARB_texture_compression_bptc"); return; case GL_COMPRESSED_RGB8_ETC2: case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2: case GL_COMPRESSED_SRGB8_ETC2: case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2: case GL_COMPRESSED_RGBA8_ETC2_EAC: case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC: case GL_COMPRESSED_R11_EAC: case GL_COMPRESSED_RG11_EAC: case GL_COMPRESSED_SIGNED_R11_EAC: case GL_COMPRESSED_SIGNED_RG11_EAC: check_supported({4, 3}, "GL_ARB_ES3_compatibility"); return; case GL_COMPRESSED_RGBA_ASTC_4x4_KHR: case GL_COMPRESSED_RGBA_ASTC_5x4_KHR: case GL_COMPRESSED_RGBA_ASTC_5x5_KHR: case GL_COMPRESSED_RGBA_ASTC_6x5_KHR: case GL_COMPRESSED_RGBA_ASTC_6x6_KHR: case GL_COMPRESSED_RGBA_ASTC_8x5_KHR: case GL_COMPRESSED_RGBA_ASTC_8x6_KHR: case GL_COMPRESSED_RGBA_ASTC_8x8_KHR: case GL_COMPRESSED_RGBA_ASTC_10x5_KHR: case GL_COMPRESSED_RGBA_ASTC_10x6_KHR: case GL_COMPRESSED_RGBA_ASTC_10x8_KHR: case GL_COMPRESSED_RGBA_ASTC_10x10_KHR: case GL_COMPRESSED_RGBA_ASTC_12x10_KHR: case GL_COMPRESSED_RGBA_ASTC_12x12_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: check_supported({}, "GL_KHR_texture_compression_astc_ldr"); return; default: STR_THROW( "Expected " << "internal format" << ", " << "got " << str_internal_format_(internal_format) << "." ); } } /// Fail void GLBase::fail_action_( std::string const & action, std::string const & name ) { STR_RETHROW("Failed to " << action << " " << name << ":\n"); } /// String std::string GLBase::str_path_(Path const & path) { return STR("\"" << path << "\""); } std::string GLBase::str_paths_(Paths const & paths) { return STR_JOIN(", ", path, str_path_(path), paths); } std::string GLBase::str_enum_(GLenum name) { return STR(std::hex << std::showbase << std::uppercase << name); } std::string GLBase::str_error_(GLenum error) { switch (error) { STR_CASE(GL_NO_ERROR) STR_CASE(GL_INVALID_ENUM) STR_CASE(GL_INVALID_VALUE) STR_CASE(GL_INVALID_OPERATION) STR_CASE(GL_INVALID_FRAMEBUFFER_OPERATION) STR_CASE(GL_OUT_OF_MEMORY) STR_CASE(GL_STACK_OVERFLOW) STR_CASE(GL_STACK_UNDERFLOW) STR_CASE(GL_CONTEXT_LOST) // GL_KHR_robustness default: return str_enum_(error); } } std::string GLBase::str_object_type_(GLenum object_type) { switch (object_type) { STR_CASE(GL_TEXTURE) STR_CASE(GL_BUFFER) STR_CASE(GL_SHADER) STR_CASE(GL_PROGRAM) STR_CASE(GL_PROGRAM_PIPELINE) STR_CASE(GL_FRAMEBUFFER) STR_CASE(GL_RENDERBUFFER) STR_CASE(GL_VERTEX_ARRAY) STR_CASE(GL_TRANSFORM_FEEDBACK) STR_CASE(GL_SAMPLER) STR_CASE(GL_QUERY) default: return str_enum_(object_type); } } std::string GLBase::str_glsl_(GLenum glsl) { switch (glsl) { STR_CASE(GL_FLOAT) STR_CASE(GL_FLOAT_VEC2) STR_CASE(GL_FLOAT_VEC3) STR_CASE(GL_FLOAT_VEC4) STR_CASE(GL_FLOAT_MAT2) STR_CASE(GL_FLOAT_MAT2x3) STR_CASE(GL_FLOAT_MAT2x4) STR_CASE(GL_FLOAT_MAT3x2) STR_CASE(GL_FLOAT_MAT3) STR_CASE(GL_FLOAT_MAT3x4) STR_CASE(GL_FLOAT_MAT4x2) STR_CASE(GL_FLOAT_MAT4x3) STR_CASE(GL_FLOAT_MAT4) STR_CASE(GL_INT) STR_CASE(GL_INT_VEC2) STR_CASE(GL_INT_VEC3) STR_CASE(GL_INT_VEC4) STR_CASE(GL_UNSIGNED_INT) STR_CASE(GL_UNSIGNED_INT_VEC2) STR_CASE(GL_UNSIGNED_INT_VEC3) STR_CASE(GL_UNSIGNED_INT_VEC4) STR_CASE(GL_DOUBLE) STR_CASE(GL_DOUBLE_VEC2) STR_CASE(GL_DOUBLE_VEC3) STR_CASE(GL_DOUBLE_VEC4) STR_CASE(GL_DOUBLE_MAT2) STR_CASE(GL_DOUBLE_MAT2x3) STR_CASE(GL_DOUBLE_MAT2x4) STR_CASE(GL_DOUBLE_MAT3x2) STR_CASE(GL_DOUBLE_MAT3) STR_CASE(GL_DOUBLE_MAT3x4) STR_CASE(GL_DOUBLE_MAT4x2) STR_CASE(GL_DOUBLE_MAT4x3) STR_CASE(GL_DOUBLE_MAT4) STR_CASE(GL_BOOL) STR_CASE(GL_BOOL_VEC2) STR_CASE(GL_BOOL_VEC3) STR_CASE(GL_BOOL_VEC4) STR_CASE(GL_SAMPLER_1D) STR_CASE(GL_SAMPLER_1D_SHADOW) STR_CASE(GL_SAMPLER_1D_ARRAY) STR_CASE(GL_SAMPLER_1D_ARRAY_SHADOW) STR_CASE(GL_SAMPLER_2D) STR_CASE(GL_SAMPLER_2D_SHADOW) STR_CASE(GL_SAMPLER_2D_ARRAY) STR_CASE(GL_SAMPLER_2D_ARRAY_SHADOW) STR_CASE(GL_SAMPLER_2D_RECT) STR_CASE(GL_SAMPLER_2D_RECT_SHADOW) STR_CASE(GL_SAMPLER_2D_MULTISAMPLE) STR_CASE(GL_SAMPLER_2D_MULTISAMPLE_ARRAY) STR_CASE(GL_SAMPLER_3D) STR_CASE(GL_SAMPLER_CUBE) STR_CASE(GL_SAMPLER_CUBE_SHADOW) STR_CASE(GL_SAMPLER_CUBE_MAP_ARRAY) STR_CASE(GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW) STR_CASE(GL_SAMPLER_BUFFER) STR_CASE(GL_INT_SAMPLER_1D) STR_CASE(GL_INT_SAMPLER_1D_ARRAY) STR_CASE(GL_INT_SAMPLER_2D) STR_CASE(GL_INT_SAMPLER_2D_ARRAY) STR_CASE(GL_INT_SAMPLER_2D_RECT) STR_CASE(GL_INT_SAMPLER_2D_MULTISAMPLE) STR_CASE(GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) STR_CASE(GL_INT_SAMPLER_3D) STR_CASE(GL_INT_SAMPLER_CUBE) STR_CASE(GL_INT_SAMPLER_CUBE_MAP_ARRAY) STR_CASE(GL_INT_SAMPLER_BUFFER) STR_CASE(GL_UNSIGNED_INT_SAMPLER_1D) STR_CASE(GL_UNSIGNED_INT_SAMPLER_1D_ARRAY) STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D) STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_ARRAY) STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_RECT) STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE) STR_CASE(GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY) STR_CASE(GL_UNSIGNED_INT_SAMPLER_3D) STR_CASE(GL_UNSIGNED_INT_SAMPLER_CUBE) STR_CASE(GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY) STR_CASE(GL_UNSIGNED_INT_SAMPLER_BUFFER) STR_CASE(GL_IMAGE_1D) STR_CASE(GL_IMAGE_1D_ARRAY) STR_CASE(GL_IMAGE_2D) STR_CASE(GL_IMAGE_2D_ARRAY) STR_CASE(GL_IMAGE_2D_RECT) STR_CASE(GL_IMAGE_2D_MULTISAMPLE) STR_CASE(GL_IMAGE_2D_MULTISAMPLE_ARRAY) STR_CASE(GL_IMAGE_3D) STR_CASE(GL_IMAGE_CUBE) STR_CASE(GL_IMAGE_CUBE_MAP_ARRAY) STR_CASE(GL_IMAGE_BUFFER) STR_CASE(GL_INT_IMAGE_1D) STR_CASE(GL_INT_IMAGE_1D_ARRAY) STR_CASE(GL_INT_IMAGE_2D) STR_CASE(GL_INT_IMAGE_2D_ARRAY) STR_CASE(GL_INT_IMAGE_2D_RECT) STR_CASE(GL_INT_IMAGE_2D_MULTISAMPLE) STR_CASE(GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY) STR_CASE(GL_INT_IMAGE_3D) STR_CASE(GL_INT_IMAGE_CUBE) STR_CASE(GL_INT_IMAGE_CUBE_MAP_ARRAY) STR_CASE(GL_INT_IMAGE_BUFFER) STR_CASE(GL_UNSIGNED_INT_IMAGE_1D) STR_CASE(GL_UNSIGNED_INT_IMAGE_1D_ARRAY) STR_CASE(GL_UNSIGNED_INT_IMAGE_2D) STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_ARRAY) STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_RECT) STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE) STR_CASE(GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY) STR_CASE(GL_UNSIGNED_INT_IMAGE_3D) STR_CASE(GL_UNSIGNED_INT_IMAGE_CUBE) STR_CASE(GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY) STR_CASE(GL_UNSIGNED_INT_IMAGE_BUFFER) // GL_ARB_gpu_shader_int64 STR_CASE(GL_INT64_ARB) STR_CASE(GL_INT64_VEC2_ARB) STR_CASE(GL_INT64_VEC3_ARB) STR_CASE(GL_INT64_VEC4_ARB) STR_CASE(GL_UNSIGNED_INT64_ARB) // GL_ARB_bindless_texture STR_CASE(GL_UNSIGNED_INT64_VEC2_ARB) STR_CASE(GL_UNSIGNED_INT64_VEC3_ARB) STR_CASE(GL_UNSIGNED_INT64_VEC4_ARB) default: return str_enum_(glsl); } } std::string GLBase::str_format_(GLenum format) { switch (format) { STR_CASE(GL_RED) STR_CASE(GL_RED_INTEGER) STR_CASE(GL_GREEN) STR_CASE(GL_GREEN_INTEGER) STR_CASE(GL_BLUE) STR_CASE(GL_BLUE_INTEGER) STR_CASE(GL_ALPHA) STR_CASE(GL_ALPHA_INTEGER) STR_CASE(GL_RG) STR_CASE(GL_RG_INTEGER) STR_CASE(GL_RGB) STR_CASE(GL_RGB_INTEGER) STR_CASE(GL_RGBA) STR_CASE(GL_RGBA_INTEGER) STR_CASE(GL_BGR) STR_CASE(GL_BGR_INTEGER) STR_CASE(GL_BGRA) STR_CASE(GL_BGRA_INTEGER) STR_CASE(GL_ABGR_EXT) // GL_EXT_abgr STR_CASE(GL_DEPTH_STENCIL) STR_CASE(GL_DEPTH_COMPONENT) STR_CASE(GL_STENCIL_INDEX) default: return str_enum_(format); } } std::string GLBase::str_type_(GLenum type) { switch (type) { STR_CASE(GL_FLOAT) STR_CASE(GL_BYTE) STR_CASE(GL_SHORT) STR_CASE(GL_INT) STR_CASE(GL_UNSIGNED_BYTE) STR_CASE(GL_UNSIGNED_SHORT) STR_CASE(GL_UNSIGNED_INT) STR_CASE(GL_UNSIGNED_BYTE_3_3_2) STR_CASE(GL_UNSIGNED_BYTE_2_3_3_REV) STR_CASE(GL_UNSIGNED_SHORT_5_6_5) STR_CASE(GL_UNSIGNED_SHORT_5_6_5_REV) STR_CASE(GL_UNSIGNED_SHORT_4_4_4_4) STR_CASE(GL_UNSIGNED_SHORT_4_4_4_4_REV) STR_CASE(GL_UNSIGNED_SHORT_5_5_5_1) STR_CASE(GL_UNSIGNED_SHORT_1_5_5_5_REV) STR_CASE(GL_UNSIGNED_INT_8_8_8_8) STR_CASE(GL_UNSIGNED_INT_8_8_8_8_REV) STR_CASE(GL_UNSIGNED_INT_10_10_10_2) STR_CASE(GL_UNSIGNED_INT_2_10_10_10_REV) STR_CASE(GL_UNSIGNED_INT_10F_11F_11F_REV) STR_CASE(GL_UNSIGNED_INT_5_9_9_9_REV) STR_CASE(GL_UNSIGNED_INT_24_8) STR_CASE(GL_FLOAT_32_UNSIGNED_INT_24_8_REV) STR_CASE(GL_DOUBLE) STR_CASE(GL_HALF_FLOAT) STR_CASE(GL_FIXED) // GL_ARB_gpu_shader_int64 STR_CASE(GL_INT64_ARB) STR_CASE(GL_UNSIGNED_INT64_ARB) // GL_ARB_bindless_texture default: return str_enum_(type); } } std::string GLBase::str_internal_format_(GLenum internal_format) { switch (internal_format) { STR_CASE(GL_RED) STR_CASE(GL_R8) STR_CASE(GL_R8I) STR_CASE(GL_R8UI) STR_CASE(GL_R16) STR_CASE(GL_R16I) STR_CASE(GL_R16UI) STR_CASE(GL_R32I) STR_CASE(GL_R32UI) STR_CASE(GL_R16F) STR_CASE(GL_R32F) STR_CASE(GL_RG) STR_CASE(GL_RG8) STR_CASE(GL_RG8I) STR_CASE(GL_RG8UI) STR_CASE(GL_RG16) STR_CASE(GL_RG16I) STR_CASE(GL_RG16UI) STR_CASE(GL_RG32I) STR_CASE(GL_RG32UI) STR_CASE(GL_RG16F) STR_CASE(GL_RG32F) STR_CASE(GL_RGB) STR_CASE(GL_RGB2_EXT) // GL_EXT_texture STR_CASE(GL_R3_G3_B2) STR_CASE(GL_RGB4) STR_CASE(GL_RGB5) STR_CASE(GL_RGB565) STR_CASE(GL_RGB8) STR_CASE(GL_RGB8I) STR_CASE(GL_RGB8UI) STR_CASE(GL_RGB10) STR_CASE(GL_RGB12) STR_CASE(GL_RGB16) STR_CASE(GL_RGB16I) STR_CASE(GL_RGB16UI) STR_CASE(GL_RGB32I) STR_CASE(GL_RGB32UI) STR_CASE(GL_RGB16F) STR_CASE(GL_RGB32F) STR_CASE(GL_R11F_G11F_B10F) STR_CASE(GL_RGB9_E5) STR_CASE(GL_RGBA) STR_CASE(GL_RGBA2) STR_CASE(GL_RGBA4) STR_CASE(GL_RGBA8) STR_CASE(GL_RGBA8I) STR_CASE(GL_RGBA8UI) STR_CASE(GL_RGBA12) STR_CASE(GL_RGBA16) STR_CASE(GL_RGBA16I) STR_CASE(GL_RGBA16UI) STR_CASE(GL_RGBA32I) STR_CASE(GL_RGBA32UI) STR_CASE(GL_RGB5_A1) STR_CASE(GL_RGB10_A2) STR_CASE(GL_RGB10_A2UI) STR_CASE(GL_RGBA16F) STR_CASE(GL_RGBA32F) STR_CASE(GL_R8_SNORM) STR_CASE(GL_R16_SNORM) STR_CASE(GL_RG8_SNORM) STR_CASE(GL_RG16_SNORM) STR_CASE(GL_RGB8_SNORM) STR_CASE(GL_RGB16_SNORM) STR_CASE(GL_RGBA8_SNORM) STR_CASE(GL_RGBA16_SNORM) STR_CASE(GL_SR8_EXT) // GL_EXT_texture_sRGB_R8 STR_CASE(GL_SRG8_EXT) // GL_EXT_texture_sRGB_RG8 STR_CASE(GL_SRGB) STR_CASE(GL_SRGB8) STR_CASE(GL_SRGB_ALPHA) STR_CASE(GL_SRGB8_ALPHA8) STR_CASE(GL_DEPTH_STENCIL) STR_CASE(GL_DEPTH24_STENCIL8) STR_CASE(GL_DEPTH32F_STENCIL8) STR_CASE(GL_DEPTH_COMPONENT) STR_CASE(GL_DEPTH_COMPONENT16) STR_CASE(GL_DEPTH_COMPONENT24) STR_CASE(GL_DEPTH_COMPONENT32) STR_CASE(GL_DEPTH_COMPONENT32F) STR_CASE(GL_STENCIL_INDEX) STR_CASE(GL_STENCIL_INDEX1) STR_CASE(GL_STENCIL_INDEX4) STR_CASE(GL_STENCIL_INDEX8) STR_CASE(GL_STENCIL_INDEX16) STR_CASE(GL_COMPRESSED_RED) STR_CASE(GL_COMPRESSED_RG) STR_CASE(GL_COMPRESSED_RGB) STR_CASE(GL_COMPRESSED_RGBA) STR_CASE(GL_COMPRESSED_SRGB) STR_CASE(GL_COMPRESSED_SRGB_ALPHA) STR_CASE(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) STR_CASE(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) STR_CASE(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT) STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT) STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT) STR_CASE(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT) STR_CASE(GL_COMPRESSED_RED_RGTC1) STR_CASE(GL_COMPRESSED_RG_RGTC2) STR_CASE(GL_COMPRESSED_SIGNED_RED_RGTC1) STR_CASE(GL_COMPRESSED_SIGNED_RG_RGTC2) STR_CASE(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT) STR_CASE(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT) STR_CASE(GL_COMPRESSED_RGBA_BPTC_UNORM) STR_CASE(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM) STR_CASE(GL_COMPRESSED_RGB8_ETC2) STR_CASE(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) STR_CASE(GL_COMPRESSED_SRGB8_ETC2) STR_CASE(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) STR_CASE(GL_COMPRESSED_RGBA8_ETC2_EAC) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) STR_CASE(GL_COMPRESSED_R11_EAC) STR_CASE(GL_COMPRESSED_RG11_EAC) STR_CASE(GL_COMPRESSED_SIGNED_R11_EAC) STR_CASE(GL_COMPRESSED_SIGNED_RG11_EAC) STR_CASE(GL_COMPRESSED_RGBA_ASTC_4x4_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_5x4_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_5x5_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_6x5_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_6x6_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x5_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x6_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_8x8_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x5_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x6_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x8_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_10x10_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_12x10_KHR) STR_CASE(GL_COMPRESSED_RGBA_ASTC_12x12_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) STR_CASE(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) default: return str_enum_(internal_format); } }