diff --git a/libs/gfx/include/psemek/gfx/attribs.hpp b/libs/gfx/include/psemek/gfx/attribs.hpp index 4451b63e..2b4e2210 100644 --- a/libs/gfx/include/psemek/gfx/attribs.hpp +++ b/libs/gfx/include/psemek/gfx/attribs.hpp @@ -19,7 +19,6 @@ namespace psemek::gfx GLint size; GLenum type; GLboolean normalized; - GLsizei stride; void const * pointer; GLuint divisor; }; @@ -27,7 +26,11 @@ namespace psemek::gfx struct attribs_description { std::vector attribs; - GLuint index_count; + GLuint index_count = 0; + GLuint vertex_size = 0; + GLuint instance_size = 0; + + attribs_description & operator += (attribs_description const & d); }; inline attribs_description operator + (attribs_description d1, attribs_description const & d2) @@ -35,12 +38,21 @@ namespace psemek::gfx for (auto a : d2.attribs) { a.index += d1.index_count; + a.pointer = reinterpret_cast(a.pointer) + (a.divisor == 0 ? d1.vertex_size : d1.instance_size); d1.attribs.push_back(a); } d1.index_count += d2.index_count; + d1.vertex_size += d2.vertex_size; + d1.instance_size += d2.instance_size; return d1; } + inline attribs_description & attribs_description::operator += (attribs_description const & d) + { + (*this) = (*this) + d; + return *this; + } + template struct normalized { @@ -263,32 +275,6 @@ namespace psemek::gfx } } - template - struct stride_helper; - - template - struct stride_helper - { - static std::size_t stride() - { - return 0; - } - }; - - template - struct stride_helper - { - static std::size_t stride() - { - std::size_t s = 0; - if constexpr (is_instanced::value == Instance) - { - s = attr_size(); - } - return s + stride_helper::stride(); - } - }; - template struct make_attribs_description_impl; @@ -298,9 +284,17 @@ namespace psemek::gfx static void make(attribs_description &) {} - static void make_impl(attribs_description & result, std::size_t index, std::size_t, std::size_t) + static void make_impl(attribs_description & result, std::size_t index, std::size_t offset) { result.index_count = index; + if constexpr (Instance) + { + result.instance_size = offset; + } + else + { + result.vertex_size = offset; + } } }; @@ -309,19 +303,18 @@ namespace psemek::gfx { static void make(attribs_description & result) { - std::size_t const stride = stride_helper::stride(); - make_impl(result, 0, 0, stride); + make_impl(result, 0, 0); } - static void make_impl(attribs_description & result, std::size_t index, std::size_t offset, std::size_t stride) + static void make_impl(attribs_description & result, std::size_t index, std::size_t offset) { if constexpr (std::is_same_v) { - make_attribs_description_impl::make_impl(result, index + 1, offset, stride); + make_attribs_description_impl::make_impl(result, index + 1, offset); } else if constexpr (is_padding::value) { - make_attribs_description_impl::make_impl(result, index, Instance ? offset : offset + Attr1::size, stride); + make_attribs_description_impl::make_impl(result, index, Instance ? offset : offset + Attr1::size); } else if constexpr (is_instanced::value == Instance) { @@ -339,14 +332,13 @@ namespace psemek::gfx attr.size = traits::size; attr.type = traits::type; attr.normalized = traits::normalized; - attr.stride = stride; attr.pointer = reinterpret_cast(offset + row * attr::static_columns * sizeof(T)); attr.divisor = Instance ? 1 : 0; result.attribs.push_back(attr); } - make_attribs_description_impl::make_impl(result, index + attr::static_rows, offset + attr_size(), stride); + make_attribs_description_impl::make_impl(result, index + attr::static_rows, offset + attr_size()); } else { @@ -358,13 +350,12 @@ namespace psemek::gfx attr.size = traits::size; attr.type = traits::type; attr.normalized = traits::normalized; - attr.stride = stride; attr.pointer = reinterpret_cast(offset); attr.divisor = Instance ? 1 : 0; result.attribs.push_back(attr); - make_attribs_description_impl::make_impl(result, index + 1, offset + attr_size(), stride); + make_attribs_description_impl::make_impl(result, index + 1, offset + attr_size()); } } else @@ -373,11 +364,11 @@ namespace psemek::gfx if constexpr (is_matrix::value) { - make_attribs_description_impl::make_impl(result, index + attr::static_rows, offset, stride); + make_attribs_description_impl::make_impl(result, index + attr::static_rows, offset); } else { - make_attribs_description_impl::make_impl(result, index + 1, offset, stride); + make_attribs_description_impl::make_impl(result, index + 1, offset); } } } diff --git a/libs/gfx/source/mesh.cpp b/libs/gfx/source/mesh.cpp index 4fe3dd34..4abaaac0 100644 --- a/libs/gfx/source/mesh.cpp +++ b/libs/gfx/source/mesh.cpp @@ -45,28 +45,21 @@ namespace psemek::gfx std::size_t max_index = 0; bool instanced = false; - std::size_t stride = 0; - std::size_t instance_stride = 0; for (auto const & a : attribs.attribs) { max_index = std::max(max_index, a.index); - if (a.divisor == 0) - { - stride = a.stride; - } - else + if (a.divisor != 0) { assert(a.divisor == 1); - instance_stride = a.stride; instanced = true; } } info_.max_attribute_index_ = max_index; - info_.stride_ = stride; - info_.instance_stride_ = instance_stride; + info_.stride_ = attribs.vertex_size; + info_.instance_stride_ = attribs.instance_size; info_.instanced_ = instanced; if (!vertex_buffer_) vertex_buffer_ = buffer{}; @@ -77,7 +70,7 @@ namespace psemek::gfx if (a.divisor != 0) continue; gl::EnableVertexAttribArray(a.index); - gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, a.stride, a.pointer); + gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.vertex_size, a.pointer); } if (instanced) @@ -90,7 +83,7 @@ namespace psemek::gfx if (a.divisor == 0) continue; gl::EnableVertexAttribArray(a.index); - gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, a.stride, a.pointer); + gl::VertexAttribPointer(a.index, a.size, a.type, a.normalized, attribs.instance_size, a.pointer); gl::VertexAttribDivisor(a.index, a.divisor); } }