class GLTraits { public: template <typename> struct Value; template <GLenum id> struct ValueID; template <GLenum object_type> struct Object; template <std::size_t N> struct Texture; private: template <std::size_t... Is> struct Indices { }; template <std::size_t N, std::size_t... Is> struct MakeIndices_ : MakeIndices_<N - 1, N - 1, Is...> { }; template <std::size_t... Is> struct MakeIndices_<0, Is...> { using Indices_ = Indices<Is...>; }; template <std::size_t N> using MakeIndices = typename MakeIndices_<N>::Indices_; template < std::size_t N, typename Indices, typename CopySizeIndices, typename CopyOffsetIndices> struct Texture_; }; template <> struct GLTraits::Value<GLfloat> { auto static constexpr name = "GLfloat"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_FLOAT}; auto static constexpr format = GLenum{GL_RED}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_R32F}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLfloat) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLfloat const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform1f(location, (value)); } void static vertex_attrib(GLint location, GLfloat const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib1f((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLfloat)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLfloat) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLfloat>::id> { using Value = GLfloat; }; template <> struct GLTraits::Value<bool> { auto static constexpr name = "bool"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_BOOL}; auto static constexpr format = GLenum{GL_RED_INTEGER}; auto static constexpr type = GLenum{GL_BYTE}; auto static constexpr internal_format = GLenum{GL_R8I}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(bool) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, bool const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform1i(location, (value)); } void static vertex_attrib(GLint location, bool const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI1i((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(bool)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(bool) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<bool>::id> { using Value = bool; }; template <> struct GLTraits::Value<GLbyte> { auto static constexpr name = "GLbyte"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_INT}; auto static constexpr format = GLenum{GL_RED_INTEGER}; auto static constexpr type = GLenum{GL_BYTE}; auto static constexpr internal_format = GLenum{GL_R8I}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLbyte) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLbyte const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform1i(location, (value)); } void static vertex_attrib(GLint location, GLbyte const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI1i((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLbyte)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLbyte) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLbyte>::id> { using Value = GLbyte; }; template <> struct GLTraits::Value<GLshort> { auto static constexpr name = "GLshort"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_INT}; auto static constexpr format = GLenum{GL_RED_INTEGER}; auto static constexpr type = GLenum{GL_SHORT}; auto static constexpr internal_format = GLenum{GL_R16I}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLshort) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLshort const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform1i(location, (value)); } void static vertex_attrib(GLint location, GLshort const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI1i((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLshort)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLshort) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLshort>::id> { using Value = GLshort; }; template <> struct GLTraits::Value<GLint> { auto static constexpr name = "GLint"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_INT}; auto static constexpr format = GLenum{GL_RED_INTEGER}; auto static constexpr type = GLenum{GL_INT}; auto static constexpr internal_format = GLenum{GL_R32I}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLint) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLint const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform1i(location, (value)); } void static vertex_attrib(GLint location, GLint const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI1i((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLint)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLint) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLint>::id> { using Value = GLint; }; template <> struct GLTraits::Value<GLubyte> { auto static constexpr name = "GLubyte"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_UNSIGNED_INT}; auto static constexpr format = GLenum{GL_RED_INTEGER}; auto static constexpr type = GLenum{GL_UNSIGNED_BYTE}; auto static constexpr internal_format = GLenum{GL_R8UI}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLubyte) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLubyte const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); glUniform1ui(location, (value)); } void static vertex_attrib(GLint location, GLubyte const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI1ui((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLubyte)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLubyte) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLubyte>::id> { using Value = GLubyte; }; template <> struct GLTraits::Value<GLushort> { auto static constexpr name = "GLushort"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_UNSIGNED_INT}; auto static constexpr format = GLenum{GL_RED_INTEGER}; auto static constexpr type = GLenum{GL_UNSIGNED_SHORT}; auto static constexpr internal_format = GLenum{GL_R16UI}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLushort) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLushort const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); glUniform1ui(location, (value)); } void static vertex_attrib(GLint location, GLushort const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI1ui((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLushort)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLushort) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLushort>::id> { using Value = GLushort; }; template <> struct GLTraits::Value<GLuint> { auto static constexpr name = "GLuint"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_UNSIGNED_INT}; auto static constexpr format = GLenum{GL_RED_INTEGER}; auto static constexpr type = GLenum{GL_UNSIGNED_INT}; auto static constexpr internal_format = GLenum{GL_R32UI}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLuint) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLuint const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); glUniform1ui(location, (value)); } void static vertex_attrib(GLint location, GLuint const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI1ui((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLuint)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLuint) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLuint>::id> { using Value = GLuint; }; template <> struct GLTraits::Value<GLdouble> { auto static constexpr name = "GLdouble"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{1}; auto static constexpr glsl = GLenum{GL_DOUBLE}; auto static constexpr format = GLenum{GL_RED}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RED}; auto static constexpr internal_format_srgb = GLenum{GL_SR8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RED}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(GLdouble) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, GLdouble const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniform1d(location, (value)); } void static vertex_attrib(GLint location, GLdouble const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL1d((GLuint)location + column, (value)); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(GLdouble)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(GLdouble) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<GLdouble>::id> { using Value = GLdouble; }; template <> struct GLTraits::Value<glm::vec2> { auto static constexpr name = "glm::vec2"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_FLOAT_VEC2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RG32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::vec2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::vec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform2fv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::vec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib2fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::vec2)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::vec2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec2>::id> { using Value = glm::vec2; }; template <> struct GLTraits::Value<glm::vec3> { auto static constexpr name = "glm::vec3"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_FLOAT_VEC3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGB32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::vec3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::vec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform3fv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::vec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib3fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::vec3)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::vec3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec3>::id> { using Value = glm::vec3; }; template <> struct GLTraits::Value<glm::vec4> { auto static constexpr name = "glm::vec4"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_FLOAT_VEC4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGBA32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::vec4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::vec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform4fv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::vec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib4fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::vec4)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::vec4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::vec4>::id> { using Value = glm::vec4; }; template <> struct GLTraits::Value<glm::mat2> { auto static constexpr name = "glm::mat2"; auto static constexpr columns = GLint{2}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RG32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniformMatrix2fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib2fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat2)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2>::id> { using Value = glm::mat2; }; template <> struct GLTraits::Value<glm::mat2x3> { auto static constexpr name = "glm::mat2x3"; auto static constexpr columns = GLint{2}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT2x3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGB32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat2x3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat2x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 1}, {}); glUniformMatrix2x3fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat2x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib3fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat2x3)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat2x3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2x3>::id> { using Value = glm::mat2x3; }; template <> struct GLTraits::Value<glm::mat2x4> { auto static constexpr name = "glm::mat2x4"; auto static constexpr columns = GLint{2}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT2x4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGBA32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat2x4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat2x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 1}, {}); glUniformMatrix2x4fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat2x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib4fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat2x4)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat2x4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat2x4>::id> { using Value = glm::mat2x4; }; template <> struct GLTraits::Value<glm::mat3x2> { auto static constexpr name = "glm::mat3x2"; auto static constexpr columns = GLint{3}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT3x2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RG32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat3x2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat3x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 1}, {}); glUniformMatrix3x2fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat3x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib2fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat3x2)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat3x2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3x2>::id> { using Value = glm::mat3x2; }; template <> struct GLTraits::Value<glm::mat3> { auto static constexpr name = "glm::mat3"; auto static constexpr columns = GLint{3}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGB32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniformMatrix3fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib3fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat3)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3>::id> { using Value = glm::mat3; }; template <> struct GLTraits::Value<glm::mat3x4> { auto static constexpr name = "glm::mat3x4"; auto static constexpr columns = GLint{3}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT3x4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGBA32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat3x4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat3x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 1}, {}); glUniformMatrix3x4fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat3x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib4fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat3x4)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat3x4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat3x4>::id> { using Value = glm::mat3x4; }; template <> struct GLTraits::Value<glm::mat4x2> { auto static constexpr name = "glm::mat4x2"; auto static constexpr columns = GLint{4}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT4x2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RG32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat4x2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat4x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 1}, {}); glUniformMatrix4x2fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat4x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib2fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat4x2)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat4x2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4x2>::id> { using Value = glm::mat4x2; }; template <> struct GLTraits::Value<glm::mat4x3> { auto static constexpr name = "glm::mat4x3"; auto static constexpr columns = GLint{4}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT4x3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGB32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat4x3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat4x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 1}, {}); glUniformMatrix4x3fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat4x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib3fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat4x3)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat4x3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4x3>::id> { using Value = glm::mat4x3; }; template <> struct GLTraits::Value<glm::mat4> { auto static constexpr name = "glm::mat4"; auto static constexpr columns = GLint{4}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_FLOAT_MAT4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_FLOAT}; auto static constexpr internal_format = GLenum{GL_RGBA32F}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::mat4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::mat4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniformMatrix4fv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::mat4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttrib4fv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::mat4)) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::mat4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribPointer( (GLuint)location + column, rows, type, GL_FALSE, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::mat4>::id> { using Value = glm::mat4; }; template <> struct GLTraits::Value<glm::ivec2> { auto static constexpr name = "glm::ivec2"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_INT_VEC2}; auto static constexpr format = GLenum{GL_RG_INTEGER}; auto static constexpr type = GLenum{GL_INT}; auto static constexpr internal_format = GLenum{GL_RG32I}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::ivec2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::ivec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform2iv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::ivec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI2iv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::ivec2)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::ivec2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec2>::id> { using Value = glm::ivec2; }; template <> struct GLTraits::Value<glm::ivec3> { auto static constexpr name = "glm::ivec3"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_INT_VEC3}; auto static constexpr format = GLenum{GL_RGB_INTEGER}; auto static constexpr type = GLenum{GL_INT}; auto static constexpr internal_format = GLenum{GL_RGB32I}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::ivec3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::ivec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform3iv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::ivec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI3iv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::ivec3)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::ivec3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec3>::id> { using Value = glm::ivec3; }; template <> struct GLTraits::Value<glm::ivec4> { auto static constexpr name = "glm::ivec4"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_INT_VEC4}; auto static constexpr format = GLenum{GL_RGBA_INTEGER}; auto static constexpr type = GLenum{GL_INT}; auto static constexpr internal_format = GLenum{GL_RGBA32I}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::ivec4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::ivec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); glUniform4iv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::ivec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI4iv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::ivec4)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::ivec4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::ivec4>::id> { using Value = glm::ivec4; }; template <> struct GLTraits::Value<glm::uvec2> { auto static constexpr name = "glm::uvec2"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_UNSIGNED_INT_VEC2}; auto static constexpr format = GLenum{GL_RG_INTEGER}; auto static constexpr type = GLenum{GL_UNSIGNED_INT}; auto static constexpr internal_format = GLenum{GL_RG32UI}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::uvec2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::uvec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); glUniform2uiv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::uvec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI2uiv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::uvec2)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::uvec2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec2>::id> { using Value = glm::uvec2; }; template <> struct GLTraits::Value<glm::uvec3> { auto static constexpr name = "glm::uvec3"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_UNSIGNED_INT_VEC3}; auto static constexpr format = GLenum{GL_RGB_INTEGER}; auto static constexpr type = GLenum{GL_UNSIGNED_INT}; auto static constexpr internal_format = GLenum{GL_RGB32UI}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::uvec3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::uvec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); glUniform3uiv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::uvec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI3uiv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::uvec3)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::uvec3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec3>::id> { using Value = glm::uvec3; }; template <> struct GLTraits::Value<glm::uvec4> { auto static constexpr name = "glm::uvec4"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_UNSIGNED_INT_VEC4}; auto static constexpr format = GLenum{GL_RGBA_INTEGER}; auto static constexpr type = GLenum{GL_UNSIGNED_INT}; auto static constexpr internal_format = GLenum{GL_RGBA32UI}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*"_INTEGER"); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::uvec4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::uvec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); glUniform4uiv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::uvec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribI4uiv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::uvec4)) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, {}); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::uvec4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribIPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::uvec4>::id> { using Value = glm::uvec4; }; template <> struct GLTraits::Value<glm::dvec2> { auto static constexpr name = "glm::dvec2"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_DOUBLE_VEC2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RG}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dvec2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dvec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniform2dv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dvec2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL2dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dvec2)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dvec2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec2>::id> { using Value = glm::dvec2; }; template <> struct GLTraits::Value<glm::dvec3> { auto static constexpr name = "glm::dvec3"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_DOUBLE_VEC3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGB}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dvec3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dvec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniform3dv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dvec3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL3dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dvec3)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dvec3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec3>::id> { using Value = glm::dvec3; }; template <> struct GLTraits::Value<glm::dvec4> { auto static constexpr name = "glm::dvec4"; auto static constexpr columns = GLint{1}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_DOUBLE_VEC4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGBA}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dvec4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dvec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniform4dv(location, 1, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dvec4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL4dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dvec4)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dvec4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dvec4>::id> { using Value = glm::dvec4; }; template <> struct GLTraits::Value<glm::dmat2> { auto static constexpr name = "glm::dmat2"; auto static constexpr columns = GLint{2}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RG}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix2dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL2dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat2)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2>::id> { using Value = glm::dmat2; }; template <> struct GLTraits::Value<glm::dmat2x3> { auto static constexpr name = "glm::dmat2x3"; auto static constexpr columns = GLint{2}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT2x3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGB}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat2x3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat2x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix2x3dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat2x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL3dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat2x3)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat2x3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2x3>::id> { using Value = glm::dmat2x3; }; template <> struct GLTraits::Value<glm::dmat2x4> { auto static constexpr name = "glm::dmat2x4"; auto static constexpr columns = GLint{2}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT2x4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGBA}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat2x4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat2x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix2x4dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat2x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL4dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat2x4)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat2x4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat2x4>::id> { using Value = glm::dmat2x4; }; template <> struct GLTraits::Value<glm::dmat3x2> { auto static constexpr name = "glm::dmat3x2"; auto static constexpr columns = GLint{3}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT3x2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RG}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat3x2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat3x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix3x2dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat3x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL2dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat3x2)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat3x2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3x2>::id> { using Value = glm::dmat3x2; }; template <> struct GLTraits::Value<glm::dmat3> { auto static constexpr name = "glm::dmat3"; auto static constexpr columns = GLint{3}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGB}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix3dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL3dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat3)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3>::id> { using Value = glm::dmat3; }; template <> struct GLTraits::Value<glm::dmat3x4> { auto static constexpr name = "glm::dmat3x4"; auto static constexpr columns = GLint{3}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT3x4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGBA}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat3x4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat3x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix3x4dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat3x4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL4dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat3x4)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat3x4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat3x4>::id> { using Value = glm::dmat3x4; }; template <> struct GLTraits::Value<glm::dmat4x2> { auto static constexpr name = "glm::dmat4x2"; auto static constexpr columns = GLint{4}; auto static constexpr rows = GLint{2}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT4x2}; auto static constexpr format = GLenum{GL_RG}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RG}; auto static constexpr internal_format_srgb = GLenum{GL_SRG8_EXT}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RG}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat4x2) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat4x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix4x2dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat4x2 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL2dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat4x2)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat4x2) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4x2>::id> { using Value = glm::dmat4x2; }; template <> struct GLTraits::Value<glm::dmat4x3> { auto static constexpr name = "glm::dmat4x3"; auto static constexpr columns = GLint{4}; auto static constexpr rows = GLint{3}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT4x3}; auto static constexpr format = GLenum{GL_RGB}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGB}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGB}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat4x3) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat4x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix4x3dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat4x3 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL3dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat4x3)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat4x3) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4x3>::id> { using Value = glm::dmat4x3; }; template <> struct GLTraits::Value<glm::dmat4> { auto static constexpr name = "glm::dmat4"; auto static constexpr columns = GLint{4}; auto static constexpr rows = GLint{4}; auto static constexpr glsl = GLenum{GL_DOUBLE_MAT4}; auto static constexpr format = GLenum{GL_RGBA}; auto static constexpr type = GLenum{GL_DOUBLE}; auto static constexpr internal_format = GLenum{GL_RGBA}; auto static constexpr internal_format_srgb = GLenum{GL_SRGB8_ALPHA8}; auto static constexpr internal_format_compressed = GLenum{GL_COMPRESSED_RGBA}; auto static constexpr internal_format_compressed_srgb = GLenum{GL_COMPRESSED_SRGB_ALPHA}; auto static constexpr integer = bool(*""); auto static constexpr id = (glsl == GL_INT || glsl == GL_UNSIGNED_INT) && sizeof(glm::dmat4) < sizeof(GLint) ? type : glsl; void static uniform(GLint location, glm::dmat4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_gpu_shader_fp64"); glUniformMatrix4dv(location, 1, GL_FALSE, glm::value_ptr(value)); } void static vertex_attrib(GLint location, glm::dmat4 const & value) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribL4dv( (GLuint)location + column, glm::value_ptr(value) + rows * column); } void static vertex_attrib_pointer( GLint location, std::size_t offset = 0, std::size_t stride = sizeof(glm::dmat4)) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_vertex_attrib_64bit"); if (location == -1) return; auto constexpr sizeof_column = sizeof(glm::dmat4) / columns; for (auto column = GLuint{0}; column < columns; ++column) glVertexAttribLPointer( (GLuint)location + column, rows, type, (GLsizei)stride, (void const *)(offset + sizeof_column * column)); } }; template <> struct GLTraits::ValueID<GLTraits::Value<glm::dmat4>::id> { using Value = glm::dmat4; }; template <> struct GLTraits::Object<GL_TEXTURE> { auto static constexpr name = "GL_" "TEXTURE"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 1}, {}); glGenTextures(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 1}, {}); glDeleteTextures(n, objects); } }; template <> struct GLTraits::Object<GL_BUFFER> { auto static constexpr name = "GL_" "BUFFER"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 5}, {}); glGenBuffers(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 5}, {}); glDeleteBuffers(n, objects); } }; template <> struct GLTraits::Object<GL_QUERY> { auto static constexpr name = "GL_" "QUERY"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 5}, {}); glGenQueries(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 5}, {}); glDeleteQueries(n, objects); } }; template <> struct GLTraits::Object<GL_PROGRAM> { auto static constexpr name = "GL_" "PROGRAM"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); while (n--) objects[n] = glCreateProgram(args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); while (n--) glDeleteProgram(objects[n]); } std::string static info_log(GLuint object) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); auto length = GLint{}; glGetProgramiv(object, GL_INFO_LOG_LENGTH, &length); if (length != 0) --length; auto info_log = std::string((std::size_t)length, char{}); glGetProgramInfoLog(object, length + 1, nullptr, &info_log[0]); return info_log; } }; template <> struct GLTraits::Object<GL_SHADER> { auto static constexpr name = "GL_" "SHADER"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); while (n--) objects[n] = glCreateShader(args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); while (n--) glDeleteShader(objects[n]); } std::string static info_log(GLuint object) { if (GLBase::debug() >= 1) GLBase::check_supported({2, 0}, {}); auto length = GLint{}; glGetShaderiv(object, GL_INFO_LOG_LENGTH, &length); if (length != 0) --length; auto info_log = std::string((std::size_t)length, char{}); glGetShaderInfoLog(object, length + 1, nullptr, &info_log[0]); return info_log; } }; template <> struct GLTraits::Object<GL_VERTEX_ARRAY> { auto static constexpr name = "GL_" "VERTEX_ARRAY"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, "GL_ARB_vertex_array_object"); glGenVertexArrays(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, "GL_ARB_vertex_array_object"); glDeleteVertexArrays(n, objects); } }; template <> struct GLTraits::Object<GL_FRAMEBUFFER> { auto static constexpr name = "GL_" "FRAMEBUFFER"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); glGenFramebuffers(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); glDeleteFramebuffers(n, objects); } }; template <> struct GLTraits::Object<GL_RENDERBUFFER> { auto static constexpr name = "GL_" "RENDERBUFFER"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); glGenRenderbuffers(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 0}, "GL_ARB_framebuffer_object"); glDeleteRenderbuffers(n, objects); } }; template <> struct GLTraits::Object<GL_SAMPLER> { auto static constexpr name = "GL_" "SAMPLER"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 3}, "GL_ARB_sampler_objects"); glGenSamplers(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({3, 3}, "GL_ARB_sampler_objects"); glDeleteSamplers(n, objects); } }; template <> struct GLTraits::Object<GL_TRANSFORM_FEEDBACK> { auto static constexpr name = "GL_" "TRANSFORM_FEEDBACK"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_transform_feedback2"); glGenTransformFeedbacks(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 0}, "GL_ARB_transform_feedback2"); glDeleteTransformFeedbacks(n, objects); } }; template <> struct GLTraits::Object<GL_PROGRAM_PIPELINE> { auto static constexpr name = "GL_" "PROGRAM_PIPELINE"; template <typename... Args> void static gen_objects(GLsizei n, GLuint * objects, Args... args) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects"); glGenProgramPipelines(n, objects, args...); } void static delete_objects(GLsizei n, GLuint const * objects) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects"); glDeleteProgramPipelines(n, objects); } std::string static info_log(GLuint object) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 1}, "GL_ARB_separate_shader_objects"); auto length = GLint{}; glGetProgramPipelineiv(object, GL_INFO_LOG_LENGTH, &length); if (length != 0) --length; auto info_log = std::string((std::size_t)length, char{}); glGetProgramPipelineInfoLog(object, length + 1, nullptr, &info_log[0]); return info_log; } }; template <> struct GLTraits::Texture<0> { protected: void static defaults_( GLenum & internal_format, GLenum & format, GLenum & type, GLenum default_internal_format, GLenum default_format, GLenum default_type) { if (!internal_format) internal_format = default_internal_format; switch (internal_format) { case GL_DEPTH_STENCIL: case GL_DEPTH24_STENCIL8: case GL_DEPTH32F_STENCIL8: if (!format) format = GL_DEPTH_STENCIL; if (!type) type = GL_UNSIGNED_INT_24_8; break; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: case GL_DEPTH_COMPONENT24: case GL_DEPTH_COMPONENT32: case GL_DEPTH_COMPONENT32F: if (!format) format = GL_DEPTH_COMPONENT; if (!type) type = GL_UNSIGNED_INT; break; case GL_STENCIL_INDEX: case GL_STENCIL_INDEX1: case GL_STENCIL_INDEX4: case GL_STENCIL_INDEX8: case GL_STENCIL_INDEX16: if (!format) format = GL_STENCIL_INDEX; if (!type) type = GL_UNSIGNED_BYTE; break; default: if (!format) format = default_format; if (!type) type = default_type; } } }; template < std::size_t... Is, std::size_t... CopySizeIs, std::size_t... CopyOffsetIs> struct GLTraits::Texture_< 1, GLTraits::Indices<Is...>, GLTraits::Indices<CopySizeIs...>, GLTraits::Indices<CopyOffsetIs...>> : GLTraits::Texture<0> { using Size = std::array<GLsizei, sizeof...(Is)>; using Offset = std::array<GLsizei, sizeof...(Is)>; using CopySize = std::array<GLsizei, sizeof...(CopySizeIs)>; using CopyOffset = std::array<GLsizei, sizeof...(CopyOffsetIs)>; auto static constexpr default_target = GL_TEXTURE_1D; auto static constexpr default_binding = GL_TEXTURE_BINDING_1D; template <typename Value = GLubyte> void static tex_image( GLenum target, Size size, GLenum internal_format = 0, Value const * data = nullptr, GLenum format = 0, GLenum type = 0, GLint level = 0, GLint border = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 0}, {}); defaults_( internal_format, format, type, GLTraits::Value<Value>::internal_format, GLTraits::Value<Value>::format, GLTraits::Value<Value>::type); glTexImage1D( target, level, (GLint)internal_format, std::get<Is>(size)..., border, format, type, data); } template <typename Value = GLubyte> void static tex_sub_image( GLenum target, Size size, Value const * data, GLenum format = 0, GLenum type = 0, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 1}, {}); if (!format) format = GLTraits::Value<Value>::format; if (!type) type = GLTraits::Value<Value>::type; glTexSubImage1D( target, level, std::get<Is>(offset)..., std::get<Is>(size)..., format, type, data); } void static copy_tex_sub_image( GLenum target, CopySize copy_size, CopyOffset copy_offset = {}, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 1}, {}); glCopyTexSubImage1D( target, level, std::get<Is>(offset)..., std::get<CopyOffsetIs>(copy_offset)..., std::get<CopySizeIs>(copy_size)...); } void static compressed_tex_image( GLenum target, Size size, GLenum internal_format, GLsizei data_size = 0, void const * data = nullptr, GLint level = 0, GLint border = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 3}, {}); glCompressedTexImage1D( target, level, internal_format, std::get<Is>(size)..., border, data_size, data); } void static compressed_tex_sub_image( GLenum target, Size size, GLsizei data_size, void const * data, GLenum internal_format, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 3}, {}); glCompressedTexSubImage1D( target, level, std::get<Is>(offset)..., std::get<Is>(size)..., internal_format, data_size, data); } template <typename Value = GLubyte> void static tex_storage( GLenum target, Size size, GLenum internal_format = 0, GLsizei levels = 1) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 2}, "GL_ARB_texture_storage"); if (!internal_format) internal_format = GLTraits::Value<Value>::internal_format; glTexStorage1D(target, levels, internal_format, std::get<Is>(size)...); } template <typename Value = GLubyte> void static texture_storage( GLuint texture, Size size, GLenum internal_format = 0, GLsizei levels = 1) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); if (!internal_format) internal_format = GLTraits::Value<Value>::internal_format; glTextureStorage1D( texture, levels, internal_format, std::get<Is>(size)...); } template <typename Value = GLubyte> void static texture_sub_image( GLuint texture, Size size, Value const * data, GLenum format = 0, GLenum type = 0, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); if (!format) format = GLTraits::Value<Value>::format; if (!type) type = GLTraits::Value<Value>::type; glTextureSubImage1D( texture, level, std::get<Is>(offset)..., std::get<Is>(size)..., format, type, data); } void static copy_texture_sub_image( GLuint texture, CopySize copy_size, CopyOffset copy_offset = {}, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); glCopyTextureSubImage1D( texture, level, std::get<Is>(offset)..., std::get<CopyOffsetIs>(copy_offset)..., std::get<CopySizeIs>(copy_size)...); } void static compressed_texture_sub_image( GLuint texture, Size size, GLsizei data_size, void const * data, GLenum internal_format, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); glCompressedTextureSubImage1D( texture, level, std::get<Is>(offset)..., std::get<Is>(size)..., internal_format, data_size, data); } }; template <> struct GLTraits::Texture<1> : Texture_<1, MakeIndices<1>, MakeIndices<1 < 2 ? 1 : 2>, MakeIndices<2>> { }; template < std::size_t... Is, std::size_t... CopySizeIs, std::size_t... CopyOffsetIs> struct GLTraits::Texture_< 2, GLTraits::Indices<Is...>, GLTraits::Indices<CopySizeIs...>, GLTraits::Indices<CopyOffsetIs...>> : GLTraits::Texture<0> { using Size = std::array<GLsizei, sizeof...(Is)>; using Offset = std::array<GLsizei, sizeof...(Is)>; using CopySize = std::array<GLsizei, sizeof...(CopySizeIs)>; using CopyOffset = std::array<GLsizei, sizeof...(CopyOffsetIs)>; auto static constexpr default_target = GL_TEXTURE_2D; auto static constexpr default_binding = GL_TEXTURE_BINDING_2D; template <typename Value = GLubyte> void static tex_image( GLenum target, Size size, GLenum internal_format = 0, Value const * data = nullptr, GLenum format = 0, GLenum type = 0, GLint level = 0, GLint border = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 0}, {}); defaults_( internal_format, format, type, GLTraits::Value<Value>::internal_format, GLTraits::Value<Value>::format, GLTraits::Value<Value>::type); glTexImage2D( target, level, (GLint)internal_format, std::get<Is>(size)..., border, format, type, data); } template <typename Value = GLubyte> void static tex_sub_image( GLenum target, Size size, Value const * data, GLenum format = 0, GLenum type = 0, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 1}, {}); if (!format) format = GLTraits::Value<Value>::format; if (!type) type = GLTraits::Value<Value>::type; glTexSubImage2D( target, level, std::get<Is>(offset)..., std::get<Is>(size)..., format, type, data); } void static copy_tex_sub_image( GLenum target, CopySize copy_size, CopyOffset copy_offset = {}, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 1}, {}); glCopyTexSubImage2D( target, level, std::get<Is>(offset)..., std::get<CopyOffsetIs>(copy_offset)..., std::get<CopySizeIs>(copy_size)...); } void static compressed_tex_image( GLenum target, Size size, GLenum internal_format, GLsizei data_size = 0, void const * data = nullptr, GLint level = 0, GLint border = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 3}, {}); glCompressedTexImage2D( target, level, internal_format, std::get<Is>(size)..., border, data_size, data); } void static compressed_tex_sub_image( GLenum target, Size size, GLsizei data_size, void const * data, GLenum internal_format, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 3}, {}); glCompressedTexSubImage2D( target, level, std::get<Is>(offset)..., std::get<Is>(size)..., internal_format, data_size, data); } template <typename Value = GLubyte> void static tex_storage( GLenum target, Size size, GLenum internal_format = 0, GLsizei levels = 1) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 2}, "GL_ARB_texture_storage"); if (!internal_format) internal_format = GLTraits::Value<Value>::internal_format; glTexStorage2D(target, levels, internal_format, std::get<Is>(size)...); } template <typename Value = GLubyte> void static texture_storage( GLuint texture, Size size, GLenum internal_format = 0, GLsizei levels = 1) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); if (!internal_format) internal_format = GLTraits::Value<Value>::internal_format; glTextureStorage2D( texture, levels, internal_format, std::get<Is>(size)...); } template <typename Value = GLubyte> void static texture_sub_image( GLuint texture, Size size, Value const * data, GLenum format = 0, GLenum type = 0, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); if (!format) format = GLTraits::Value<Value>::format; if (!type) type = GLTraits::Value<Value>::type; glTextureSubImage2D( texture, level, std::get<Is>(offset)..., std::get<Is>(size)..., format, type, data); } void static copy_texture_sub_image( GLuint texture, CopySize copy_size, CopyOffset copy_offset = {}, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); glCopyTextureSubImage2D( texture, level, std::get<Is>(offset)..., std::get<CopyOffsetIs>(copy_offset)..., std::get<CopySizeIs>(copy_size)...); } void static compressed_texture_sub_image( GLuint texture, Size size, GLsizei data_size, void const * data, GLenum internal_format, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); glCompressedTextureSubImage2D( texture, level, std::get<Is>(offset)..., std::get<Is>(size)..., internal_format, data_size, data); } }; template <> struct GLTraits::Texture<2> : Texture_<2, MakeIndices<2>, MakeIndices<2 < 2 ? 2 : 2>, MakeIndices<2>> { }; template < std::size_t... Is, std::size_t... CopySizeIs, std::size_t... CopyOffsetIs> struct GLTraits::Texture_< 3, GLTraits::Indices<Is...>, GLTraits::Indices<CopySizeIs...>, GLTraits::Indices<CopyOffsetIs...>> : GLTraits::Texture<0> { using Size = std::array<GLsizei, sizeof...(Is)>; using Offset = std::array<GLsizei, sizeof...(Is)>; using CopySize = std::array<GLsizei, sizeof...(CopySizeIs)>; using CopyOffset = std::array<GLsizei, sizeof...(CopyOffsetIs)>; auto static constexpr default_target = GL_TEXTURE_3D; auto static constexpr default_binding = GL_TEXTURE_BINDING_3D; template <typename Value = GLubyte> void static tex_image( GLenum target, Size size, GLenum internal_format = 0, Value const * data = nullptr, GLenum format = 0, GLenum type = 0, GLint level = 0, GLint border = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 2}, {}); defaults_( internal_format, format, type, GLTraits::Value<Value>::internal_format, GLTraits::Value<Value>::format, GLTraits::Value<Value>::type); glTexImage3D( target, level, (GLint)internal_format, std::get<Is>(size)..., border, format, type, data); } template <typename Value = GLubyte> void static tex_sub_image( GLenum target, Size size, Value const * data, GLenum format = 0, GLenum type = 0, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 2}, {}); if (!format) format = GLTraits::Value<Value>::format; if (!type) type = GLTraits::Value<Value>::type; glTexSubImage3D( target, level, std::get<Is>(offset)..., std::get<Is>(size)..., format, type, data); } void static copy_tex_sub_image( GLenum target, CopySize copy_size, CopyOffset copy_offset = {}, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 2}, {}); glCopyTexSubImage3D( target, level, std::get<Is>(offset)..., std::get<CopyOffsetIs>(copy_offset)..., std::get<CopySizeIs>(copy_size)...); } void static compressed_tex_image( GLenum target, Size size, GLenum internal_format, GLsizei data_size = 0, void const * data = nullptr, GLint level = 0, GLint border = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 3}, {}); glCompressedTexImage3D( target, level, internal_format, std::get<Is>(size)..., border, data_size, data); } void static compressed_tex_sub_image( GLenum target, Size size, GLsizei data_size, void const * data, GLenum internal_format, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({1, 3}, {}); glCompressedTexSubImage3D( target, level, std::get<Is>(offset)..., std::get<Is>(size)..., internal_format, data_size, data); } template <typename Value = GLubyte> void static tex_storage( GLenum target, Size size, GLenum internal_format = 0, GLsizei levels = 1) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 2}, "GL_ARB_texture_storage"); if (!internal_format) internal_format = GLTraits::Value<Value>::internal_format; glTexStorage3D(target, levels, internal_format, std::get<Is>(size)...); } template <typename Value = GLubyte> void static texture_storage( GLuint texture, Size size, GLenum internal_format = 0, GLsizei levels = 1) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); if (!internal_format) internal_format = GLTraits::Value<Value>::internal_format; glTextureStorage3D( texture, levels, internal_format, std::get<Is>(size)...); } template <typename Value = GLubyte> void static texture_sub_image( GLuint texture, Size size, Value const * data, GLenum format = 0, GLenum type = 0, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); if (!format) format = GLTraits::Value<Value>::format; if (!type) type = GLTraits::Value<Value>::type; glTextureSubImage3D( texture, level, std::get<Is>(offset)..., std::get<Is>(size)..., format, type, data); } void static copy_texture_sub_image( GLuint texture, CopySize copy_size, CopyOffset copy_offset = {}, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); glCopyTextureSubImage3D( texture, level, std::get<Is>(offset)..., std::get<CopyOffsetIs>(copy_offset)..., std::get<CopySizeIs>(copy_size)...); } void static compressed_texture_sub_image( GLuint texture, Size size, GLsizei data_size, void const * data, GLenum internal_format, Offset offset = {}, GLint level = 0) { if (GLBase::debug() >= 1) GLBase::check_supported({4, 5}, "GL_ARB_direct_state_access"); glCompressedTextureSubImage3D( texture, level, std::get<Is>(offset)..., std::get<Is>(size)..., internal_format, data_size, data); } }; template <> struct GLTraits::Texture<3> : Texture_<3, MakeIndices<3>, MakeIndices<3 < 2 ? 3 : 2>, MakeIndices<2>> { };