From da1c1336596d361678b3f641a1d23ab89e078789 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 17 Apr 2023 17:09:40 +0100 Subject: Revamp how VertexArrayObject configures attributes and data --- gfx/gl/vertexArrayObject.hpp | 78 ++++++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 35 deletions(-) (limited to 'gfx/gl/vertexArrayObject.hpp') diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp index 5b9fc60..3e2a18b 100644 --- a/gfx/gl/vertexArrayObject.hpp +++ b/gfx/gl/vertexArrayObject.hpp @@ -2,47 +2,56 @@ #include "collections.hpp" #include "gl_traits.hpp" +#include "special_members.hpp" #include -#include -template class VertexArrayObject { +class VertexArrayObject { public: - template - static void - configure(const GLuint arrayObject, const GLuint arrayBuffer, const GLuint indexBuffer, - const SequentialCollection auto & vertices, const SequentialCollection auto & indices) + [[nodiscard]] VertexArrayObject(const GLuint arrayObject) { glBindVertexArray(arrayObject); - - configure_attribs(arrayBuffer); - data(vertices, arrayBuffer, GL_ARRAY_BUFFER); - data(indices, indexBuffer, GL_ELEMENT_ARRAY_BUFFER); - + } + ~VertexArrayObject() + { glBindVertexArray(0); } + NO_MOVE(VertexArrayObject); + NO_COPY(VertexArrayObject); - template - static void - configure(const GLuint arrayObject, const GLuint arrayBuffer, const SequentialCollection auto & vertices) - { - glBindVertexArray(arrayObject); + template struct MP { + constexpr MP(m T::*p) : P {p} { } + operator void *() const + { + return &(static_cast(nullptr)->*P); + } + m T::*P; + using value_type = m; + }; + template MP(m T::*) -> MP; - configure_attribs(arrayBuffer); + template + VertexArrayObject & + addAttribs(const GLuint arrayBuffer, const SequentialCollection auto & vertices) + { + addAttribs(arrayBuffer); data(vertices, arrayBuffer, GL_ARRAY_BUFFER); - - glBindVertexArray(0); + return *this; } - template - static void - configure(const GLuint arrayObject, const GLuint arrayBuffer) + template + VertexArrayObject & + addAttribs(const GLuint arrayBuffer) { - glBindVertexArray(arrayObject); - - configure_attribs(arrayBuffer); - glBufferData(GL_ARRAY_BUFFER, static_cast(sizeof(Vertex)), nullptr, GL_DYNAMIC_DRAW); + configure_attribs(arrayBuffer); + return *this; + } - glBindVertexArray(0); + template + VertexArrayObject & + addIndices(const GLuint arrayBuffer, const Indices & indices) + { + data(indices, arrayBuffer, GL_ELEMENT_ARRAY_BUFFER); + return *this; } private: @@ -55,34 +64,33 @@ private: glBufferData(target, static_cast(sizeof(Value) * data.size()), data.data(), GL_STATIC_DRAW); } - template + template static void set_pointer(const GLuint vertexArrayId, const void * ptr) { glEnableVertexAttribArray(vertexArrayId); using traits = gl_traits; - traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(Vertex), ptr); + traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(VertexT), ptr); } - template + template static void set_pointer(const GLuint vertexArrayId) { - set_pointer().*attrib)>>( - vertexArrayId, &(static_cast(nullptr)->*attrib)); + set_pointer(vertexArrayId, attrib); } - template + template static void configure_attribs(const GLuint arrayBuffer) { glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); if constexpr (sizeof...(attribs) == 0) { - set_pointer(0, nullptr); + set_pointer(0, nullptr); } else { GLuint vertexArrayId {}; - (set_pointer(vertexArrayId++), ...); + (set_pointer(vertexArrayId++), ...); } } }; -- cgit v1.2.3 From 9b0828ea5bb6cb4e92d6019785b3ceb88e2a58be Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 17 Apr 2023 22:43:51 +0100 Subject: Separate storing of mesh vertex/index data from configuring VAO --- gfx/gl/vertexArrayObject.hpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'gfx/gl/vertexArrayObject.hpp') diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp index 3e2a18b..8c828c8 100644 --- a/gfx/gl/vertexArrayObject.hpp +++ b/gfx/gl/vertexArrayObject.hpp @@ -7,7 +7,7 @@ class VertexArrayObject { public: - [[nodiscard]] VertexArrayObject(const GLuint arrayObject) + template [[nodiscard]] VertexArrayObject(const T & arrayObject) { glBindVertexArray(arrayObject); } @@ -54,7 +54,13 @@ public: return *this; } -private: + VertexArrayObject & + addIndices(const GLuint arrayBuffer) + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, arrayBuffer); + return *this; + } + template static void data(const Data & data, const GLuint arrayBuffer, GLenum target) @@ -64,6 +70,7 @@ private: glBufferData(target, static_cast(sizeof(Value) * data.size()), data.data(), GL_STATIC_DRAW); } +private: template static void set_pointer(const GLuint vertexArrayId, const void * ptr) -- cgit v1.2.3 From 21459ac4c92b82f2a3eeb1d9a6b462726001084c Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 18 Apr 2023 00:08:18 +0100 Subject: Specialize vertexAttribFunc for matrices because there's an upper limit of size 4 on attrib pointers --- gfx/gl/vertexArrayObject.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'gfx/gl/vertexArrayObject.hpp') diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp index 8c828c8..fdc43e9 100644 --- a/gfx/gl/vertexArrayObject.hpp +++ b/gfx/gl/vertexArrayObject.hpp @@ -72,19 +72,19 @@ public: private: template - static void + static auto set_pointer(const GLuint vertexArrayId, const void * ptr) { glEnableVertexAttribArray(vertexArrayId); using traits = gl_traits; - traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(VertexT), ptr); + return traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(VertexT), ptr); } template - static void + static auto set_pointer(const GLuint vertexArrayId) { - set_pointer(vertexArrayId, attrib); + return set_pointer(vertexArrayId, attrib); } template @@ -97,7 +97,7 @@ private: } else { GLuint vertexArrayId {}; - (set_pointer(vertexArrayId++), ...); + ((vertexArrayId += set_pointer(vertexArrayId)), ...); } } }; -- cgit v1.2.3 From 6b0b13d4b61eb95fb515bd49a8a70a06ea0748ab Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 19 Apr 2023 14:36:57 +0100 Subject: Persist vertexArrayId across multiple calls Allows chaining together to build VAO from multiple buffers --- gfx/gl/vertexArrayObject.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'gfx/gl/vertexArrayObject.hpp') diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp index fdc43e9..2285ed0 100644 --- a/gfx/gl/vertexArrayObject.hpp +++ b/gfx/gl/vertexArrayObject.hpp @@ -88,16 +88,17 @@ private: } template - static void + void configure_attribs(const GLuint arrayBuffer) { glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); if constexpr (sizeof...(attribs) == 0) { - set_pointer(0, nullptr); + vertexArrayId += set_pointer(vertexArrayId, nullptr); } else { - GLuint vertexArrayId {}; ((vertexArrayId += set_pointer(vertexArrayId)), ...); } } + + GLuint vertexArrayId {}; }; -- cgit v1.2.3 From c7396955e9d0437dc24d5ede09724fa47e0693af Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 19 Apr 2023 14:42:11 +0100 Subject: Enable all vertex array attribs configured by vertexAttribFunc --- gfx/gl/vertexArrayObject.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'gfx/gl/vertexArrayObject.hpp') diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp index 2285ed0..92e0325 100644 --- a/gfx/gl/vertexArrayObject.hpp +++ b/gfx/gl/vertexArrayObject.hpp @@ -75,9 +75,13 @@ private: static auto set_pointer(const GLuint vertexArrayId, const void * ptr) { - glEnableVertexAttribArray(vertexArrayId); using traits = gl_traits; - return traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(VertexT), ptr); + const auto usedAttribs + = traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(VertexT), ptr); + for (GLuint i {}; i < usedAttribs; i++) { + glEnableVertexAttribArray(vertexArrayId + i); + } + return usedAttribs; } template -- cgit v1.2.3 From 5e0233646ef0170e54dfd9c9b991ffdc7674ba84 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 19 Apr 2023 14:48:04 +0100 Subject: Support setting vertex attrib divisor --- gfx/gl/vertexArrayObject.hpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'gfx/gl/vertexArrayObject.hpp') diff --git a/gfx/gl/vertexArrayObject.hpp b/gfx/gl/vertexArrayObject.hpp index 92e0325..7ded03e 100644 --- a/gfx/gl/vertexArrayObject.hpp +++ b/gfx/gl/vertexArrayObject.hpp @@ -31,18 +31,18 @@ public: template VertexArrayObject & - addAttribs(const GLuint arrayBuffer, const SequentialCollection auto & vertices) + addAttribs(const GLuint arrayBuffer, const SequentialCollection auto & vertices, const GLuint divisor = 0) { - addAttribs(arrayBuffer); + addAttribs(arrayBuffer, divisor); data(vertices, arrayBuffer, GL_ARRAY_BUFFER); return *this; } template VertexArrayObject & - addAttribs(const GLuint arrayBuffer) + addAttribs(const GLuint arrayBuffer, const GLuint divisor = 0) { - configure_attribs(arrayBuffer); + configure_attribs(arrayBuffer, divisor); return *this; } @@ -73,34 +73,35 @@ public: private: template static auto - set_pointer(const GLuint vertexArrayId, const void * ptr) + set_pointer(const GLuint vertexArrayId, const void * ptr, const GLuint divisor) { using traits = gl_traits; const auto usedAttribs = traits::vertexAttribFunc(vertexArrayId, traits::size, traits::type, sizeof(VertexT), ptr); for (GLuint i {}; i < usedAttribs; i++) { glEnableVertexAttribArray(vertexArrayId + i); + glVertexAttribDivisor(vertexArrayId + i, divisor); } return usedAttribs; } template static auto - set_pointer(const GLuint vertexArrayId) + set_pointer(const GLuint vertexArrayId, const GLuint divisor) { - return set_pointer(vertexArrayId, attrib); + return set_pointer(vertexArrayId, attrib, divisor); } template void - configure_attribs(const GLuint arrayBuffer) + configure_attribs(const GLuint arrayBuffer, const GLuint divisor) { glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); if constexpr (sizeof...(attribs) == 0) { - vertexArrayId += set_pointer(vertexArrayId, nullptr); + vertexArrayId += set_pointer(vertexArrayId, nullptr, divisor); } else { - ((vertexArrayId += set_pointer(vertexArrayId)), ...); + ((vertexArrayId += set_pointer(vertexArrayId, divisor)), ...); } } -- cgit v1.2.3