From 1cc5d2876180a753a1139137c9be64faf597020d Mon Sep 17 00:00:00 2001 From: lisyarus Date: Tue, 13 Jul 2021 11:46:46 +0300 Subject: [PATCH] Support integer vertex attributes --- libs/gfx/include/psemek/gfx/attribs.hpp | 39 ++++++++++++++++++++++++- libs/gfx/source/mesh.cpp | 10 +++++-- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/libs/gfx/include/psemek/gfx/attribs.hpp b/libs/gfx/include/psemek/gfx/attribs.hpp index 576ca125..1ffce06e 100644 --- a/libs/gfx/include/psemek/gfx/attribs.hpp +++ b/libs/gfx/include/psemek/gfx/attribs.hpp @@ -19,6 +19,7 @@ namespace psemek::gfx GLuint index; GLint size; GLenum type; + bool integer = false; GLboolean normalized; void const * pointer; GLuint divisor; @@ -60,6 +61,12 @@ namespace psemek::gfx using type = T; }; + template + struct integer + { + using type = T; + }; + // skips a single attribute index struct skip {}; @@ -94,6 +101,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::UNSIGNED_BYTE; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -104,6 +112,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::BYTE; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -114,6 +123,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::UNSIGNED_SHORT; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -124,6 +134,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::SHORT; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -134,6 +145,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::UNSIGNED_INT; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -144,6 +156,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::INT; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -154,6 +167,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::FLOAT; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -164,6 +178,7 @@ namespace psemek::gfx static constexpr GLint size = 1; static constexpr GLenum type = gl::DOUBLE; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::FALSE; }; @@ -174,6 +189,7 @@ namespace psemek::gfx static constexpr GLint size = N; static constexpr GLenum type = attrib_traits::type; + static constexpr bool integer = attrib_traits::integer; static constexpr GLboolean normalized = gl::FALSE; }; @@ -184,6 +200,7 @@ namespace psemek::gfx static constexpr GLint size = N; static constexpr GLenum type = attrib_traits::type; + static constexpr bool integer = attrib_traits::integer; static constexpr GLboolean normalized = gl::FALSE; }; @@ -194,6 +211,7 @@ namespace psemek::gfx static constexpr GLint size = N; static constexpr GLenum type = attrib_traits::type; + static constexpr bool integer = attrib_traits::integer; static constexpr GLboolean normalized = gl::FALSE; }; @@ -210,6 +228,7 @@ namespace psemek::gfx static constexpr GLint size = 4; static constexpr GLenum type = attrib_traits::type; + static constexpr bool integer = attrib_traits::integer; static constexpr GLboolean normalized = gl::FALSE; }; @@ -220,9 +239,21 @@ namespace psemek::gfx static constexpr GLint size = attrib_traits::size; static constexpr GLenum type = attrib_traits::type; + static constexpr bool integer = false; static constexpr GLboolean normalized = gl::TRUE; }; + template + struct attrib_traits> + { + using attrib_type = T; + + static constexpr GLint size = attrib_traits::size; + static constexpr GLenum type = attrib_traits::type; + static constexpr bool integer = true; + static constexpr GLboolean normalized = gl::FALSE; + }; + template struct attrib_traits> { @@ -230,6 +261,7 @@ namespace psemek::gfx static constexpr GLint size = attrib_traits::size; static constexpr GLenum type = attrib_traits::type; + static constexpr bool integer = attrib_traits::integer; static constexpr GLboolean normalized = attrib_traits::normalized; }; @@ -342,6 +374,7 @@ namespace psemek::gfx attr.index = index + row; attr.size = traits::size; attr.type = traits::type; + attr.integer = traits::integer; attr.normalized = traits::normalized; attr.pointer = reinterpret_cast(offset + row * attr::static_columns * sizeof(T)); attr.divisor = Instance ? 1 : 0; @@ -360,6 +393,7 @@ namespace psemek::gfx attr.index = index; attr.size = traits::size; attr.type = traits::type; + attr.integer = traits::integer; attr.normalized = traits::normalized; attr.pointer = reinterpret_cast(offset); attr.divisor = Instance ? 1 : 0; @@ -401,8 +435,11 @@ namespace psemek::gfx for (auto const & a : attribs.attribs) { gl::EnableVertexAttribArray(a.index); - gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.vertex_size, a.pointer); gl::VertexAttribDivisor(a.index, a.divisor); + if (a.integer) + gl::VertexAttribIPointer(a.index, a.size, a.type, attribs.vertex_size, a.pointer); + else + gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.vertex_size, a.pointer); } } diff --git a/libs/gfx/source/mesh.cpp b/libs/gfx/source/mesh.cpp index 06598550..4b5a8336 100644 --- a/libs/gfx/source/mesh.cpp +++ b/libs/gfx/source/mesh.cpp @@ -71,7 +71,10 @@ namespace psemek::gfx if (a.divisor != 0) continue; gl::EnableVertexAttribArray(a.index); - gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.vertex_size, a.pointer); + if (a.integer) + gl::VertexAttribIPointer(a.index, a.size, a.type, attribs.vertex_size, a.pointer); + else + gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.vertex_size, a.pointer); } if (instanced) @@ -84,8 +87,11 @@ namespace psemek::gfx if (a.divisor == 0) continue; gl::EnableVertexAttribArray(a.index); - gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.instance_size, a.pointer); gl::VertexAttribDivisor(a.index, a.divisor); + if (a.integer) + gl::VertexAttribIPointer(a.index, a.size, a.type, attribs.instance_size, a.pointer); + else + gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.instance_size, a.pointer); } } }