diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2026-03-07 11:50:47 +0000 |
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2026-03-07 11:50:47 +0000 |
| commit | adb0096046d357a6463ae2ce66c182546c8de9c2 (patch) | |
| tree | 0e06a281efc2da637ebc19dca38f160e86516d9f /gfx | |
| parent | Update stencils and billboards less often (diff) | |
| parent | Replace glContainer with glAllocator (diff) | |
| download | ilt-adb0096046d357a6463ae2ce66c182546c8de9c2.tar.bz2 ilt-adb0096046d357a6463ae2ce66c182546c8de9c2.tar.xz ilt-adb0096046d357a6463ae2ce66c182546c8de9c2.zip | |
Merge branch 'glalloc'
Diffstat (limited to 'gfx')
| -rw-r--r-- | gfx/gl/glBuffer.h | 27 | ||||
| -rw-r--r-- | gfx/gl/glVertexArray.h | 125 | ||||
| -rw-r--r-- | gfx/gl/instanceVertices.h | 39 | ||||
| -rw-r--r-- | gfx/gl/sceneRenderer.cpp | 3 | ||||
| -rw-r--r-- | gfx/gl/sceneShader.cpp | 2 | ||||
| -rw-r--r-- | gfx/gl/vertexArrayObject.h | 125 | ||||
| -rw-r--r-- | gfx/models/mesh.h | 16 | ||||
| -rw-r--r-- | gfx/models/vertex.cpp | 8 |
8 files changed, 193 insertions, 152 deletions
diff --git a/gfx/gl/glBuffer.h b/gfx/gl/glBuffer.h new file mode 100644 index 0000000..f43c223 --- /dev/null +++ b/gfx/gl/glBuffer.h @@ -0,0 +1,27 @@ +#pragma once + +#include "glArrays.h" + +namespace Impl { + // NOLINTNEXTLINE(readability-identifier-naming) + struct glBuffer : Detail::glNamed { + void + storage(const std::ranges::contiguous_range auto & data, GLenum flags) + { + glNamedBufferStorage( + name, static_cast<GLsizeiptr>(data.size() * sizeof(decltype(*data.data()))), data.data(), flags); + } + + void + data(const std::ranges::contiguous_range auto & data, GLenum flags) + { + glNamedBufferData( + name, static_cast<GLsizeiptr>(data.size() * sizeof(decltype(*data.data()))), data.data(), flags); + } + }; +} + +// NOLINTBEGIN(readability-identifier-naming) +template<size_t N> using glBuffers = glManagedArray<Impl::glBuffer, N, &glCreateBuffers, &glDeleteBuffers>; +using glBuffer = glManagedSingle<Impl::glBuffer, &glCreateBuffers, &glDeleteBuffers>; +// NOLINTEND(readability-identifier-naming) diff --git a/gfx/gl/glVertexArray.h b/gfx/gl/glVertexArray.h new file mode 100644 index 0000000..3594cbf --- /dev/null +++ b/gfx/gl/glVertexArray.h @@ -0,0 +1,125 @@ +#pragma once + +#include "collections.h" +#include "glArrays.h" +#include "glBuffer.h" +#include "gl_traits.h" + +namespace Impl { + class VertexArrayConfigurator { + public: + template<typename M, typename T> struct MP { + constexpr MP(M T::* ptr) : ptr {ptr} { } + + operator GLuint() const + { + return static_cast<GLuint>(reinterpret_cast<const char *>(&(static_cast<T *>(nullptr)->*ptr)) + - static_cast<const char *>(nullptr)); + } + + M T::* ptr; + using ValueType = M; + }; + + template<typename M, typename T> MP(M T::*) -> MP<M, T>; + + explicit VertexArrayConfigurator(GLuint name) : name {name} { } + + VertexArrayConfigurator & + addIndices(const glBuffer & buffer) + { + glVertexArrayElementBuffer(name, buffer); + return *this; + } + + VertexArrayConfigurator & + addIndices(glBuffer & buffer, const SequentialCollection<GLuint> auto & indices) + { + buffer.storage(indices, 0); + return addIndices(buffer); + } + + // Customisation point + template<typename VertexT> VertexArrayConfigurator & addAttribsFor(GLuint divisor, const glBuffer & buffer); + + template<typename VertexT, MP... Attribs> + VertexArrayConfigurator & + addAttribs(const GLuint divisor) + { + configureAttribs<VertexT, Attribs...>(divisor); + return *this; + } + + template<typename VertexT, MP... Attribs> + VertexArrayConfigurator & + addAttribs(const GLuint divisor, const glBuffer & buffer) + { + glVertexArrayVertexBuffer(name, binding, buffer, 0, sizeof(VertexT)); + return addAttribs<VertexT, Attribs...>(divisor); + } + + template<typename VertexT, MP... Attribs> + VertexArrayConfigurator & + addAttribs(const GLuint divisor, glBuffer & buffer, const SequentialCollection<VertexT> auto & data) + { + buffer.storage(data, 0); + return addAttribs<VertexT, Attribs...>(divisor, buffer); + } + + private: + void + setPointerMeta(const GLuint usedAttribs) + { + while (attrib < usedAttribs) { + glEnableVertexArrayAttrib(name, attrib); + glVertexArrayAttribBinding(name, attrib++, binding); + } + } + + template<typename T> + void + setPointer(const GLuint offset) + { + setPointerMeta(attrib + gl_traits<T>::vertexArrayAttribFormat(name, attrib, offset)); + } + + template<MP Attrib> + void + setPointer() + { + setPointer<typename decltype(Attrib)::ValueType>(Attrib); + } + + template<typename VertexT, MP... Attribs> + void + configureAttribs(const GLuint divisor) + { + if constexpr (sizeof...(Attribs) == 0) { + setPointer<VertexT>(0); + } + else { + ((setPointer<Attribs>()), ...); + } + glVertexArrayBindingDivisor(name, binding++, divisor); + } + + GLuint name; + GLuint binding = 0; + GLuint attrib = 0; + }; + + // NOLINTNEXTLINE(readability-identifier-naming) + struct glVertexArray : Detail::glNamed { + VertexArrayConfigurator + configure() + { + return VertexArrayConfigurator {name}; + } + }; +} + +// NOLINTBEGIN(readability-identifier-naming) +template<size_t N> +using glVertexArrays = glManagedArray<Impl::glVertexArray, N, &glCreateVertexArrays, &glDeleteVertexArrays>; +using glVertexArray = glManagedSingle<Impl::glVertexArray, &glCreateVertexArrays, &glDeleteVertexArrays>; +// NOLINTEND(readability-identifier-naming) diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h index ecadf8f..f24eaa3 100644 --- a/gfx/gl/instanceVertices.h +++ b/gfx/gl/instanceVertices.h @@ -1,13 +1,13 @@ #pragma once -#include "glContainer.h" +#include "glAllocator.h" #include <cassert> #include <functional> #include <special_members.h> #include <utility> -template<typename T> class InstanceVertices : protected glContainer<T> { - using base = glContainer<T>; +template<typename T> class InstanceVertices : protected glVector<T> { + using base = glVector<T>; public: class [[nodiscard]] InstanceProxy { @@ -120,16 +120,31 @@ public: return InstanceProxy {this, index.size() - 1}; } - using base::bufferName; - using base::reserve; - - [[nodiscard]] auto - size() const + [[nodiscard]] GLuint + bufferName() const { - base::unmap(); - return base::size(); + return base::get_allocator().getNameFor(static_cast<const base &>(*this)); } + using base::at; + using base::begin; + using base::cbegin; + using base::cend; + using base::crbegin; + using base::crend; + using base::end; + using base::rbegin; + using base::rend; + using base::size; + using base::operator[]; + using base::back; + using base::capacity; + using base::data; + using base::empty; + using base::front; + using base::reserve; + using base::shrink_to_fit; + template<typename Pred> base::size_type partition(Pred pred) @@ -195,8 +210,8 @@ protected: } template<typename Pred> - glContainer<T>::iterator - partition(glContainer<T>::iterator first, glContainer<T>::iterator last, Pred pred) + base::iterator + partition(base::iterator first, base::iterator last, Pred pred) { while (first < last) { first = std::find_if_not(first, last, pred); diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index 15dde1b..e67711b 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -1,6 +1,5 @@ #include "sceneRenderer.h" #include "maths.h" -#include "vertexArrayObject.h" #include <gfx/gl/shaders/directionalLight-frag.h> #include <gfx/gl/shaders/lighting-frag.h> #include <gfx/gl/shaders/lighting-vert.h> @@ -22,7 +21,7 @@ SceneRenderer::SceneRenderer(ScreenAbsCoord s, GLuint o, glDebugScope) : lighting {lighting_vert, lighting_frag}, shadowMapper {{2048, 2048}} { shader.setViewPort({0, 0, size.x, size.y}); - VertexArrayObject {displayVAO}.addAttribs<glm::i8vec4>(displayVBO, displayVAOdata); + displayVAO.configure().addAttribs<glm::i8vec4>(0, displayVBO, displayVAOdata); const auto configuregdata = [this](const auto & data, const std::initializer_list<GLint> iformats, const GLenum format, const GLenum attachment) { diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp index 43e54a5..302edda 100644 --- a/gfx/gl/sceneShader.cpp +++ b/gfx/gl/sceneShader.cpp @@ -22,7 +22,7 @@ #include <gfx/gl/shaders/spotLight-vert.h> #include <gfx/gl/shaders/water-frag.h> #include <gfx/gl/shaders/water-vert.h> -#include <gfx/gl/vertexArrayObject.h> +#include <gl_traits.h> #include <glm/gtc/type_ptr.hpp> #include <glm/gtx/transform.hpp> #include <location.h> diff --git a/gfx/gl/vertexArrayObject.h b/gfx/gl/vertexArrayObject.h deleted file mode 100644 index d008897..0000000 --- a/gfx/gl/vertexArrayObject.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include "collections.h" -#include "gl_traits.h" -#include "special_members.h" -#include <glad/gl.h> - -class VertexArrayObject { -public: - template<typename T> [[nodiscard]] VertexArrayObject(const T & arrayObject) - { - glBindVertexArray(arrayObject); - } - - ~VertexArrayObject() - { - glBindVertexArray(0); - } - - NO_MOVE(VertexArrayObject); - NO_COPY(VertexArrayObject); - - template<typename m, typename T> struct MP { - constexpr MP(m T::* p) : P {p} { } - - constexpr - operator void *() const - { - return &(static_cast<T *>(nullptr)->*P); - } - - m T::* P; - using value_type = m; - }; - - template<typename m, typename T> MP(m T::*) -> MP<m, T>; - - template<typename VertexT, MP... attribs> - VertexArrayObject & - addAttribs(const GLuint arrayBuffer, const SequentialCollection<VertexT> auto & vertices, const GLuint divisor = 0) - { - addAttribs<VertexT, attribs...>(arrayBuffer, divisor); - data(vertices, arrayBuffer, GL_ARRAY_BUFFER); - return *this; - } - - template<typename VertexT, MP... attribs> - VertexArrayObject & - addAttribs(const GLuint arrayBuffer, const GLuint divisor = 0) - { - configure_attribs<VertexT, attribs...>(arrayBuffer, divisor); - return *this; - } - - // Customisation point - template<typename VertexT> VertexArrayObject & addAttribsFor(const GLuint arrayBuffer, const GLuint divisor = 0); - - template<typename Indices> - VertexArrayObject & - addIndices(const GLuint arrayBuffer, const Indices & indices) - { - data(indices, arrayBuffer, GL_ELEMENT_ARRAY_BUFFER); - return *this; - } - - VertexArrayObject & - addIndices(const GLuint arrayBuffer) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, arrayBuffer); - return *this; - } - - VertexArrayObject & - data(const GLuint arrayBuffer, GLenum target) - { - glBindBuffer(target, arrayBuffer); - return *this; - } - - template<typename Data> - static void - data(const Data & data, const GLuint arrayBuffer, GLenum target) - { - using Value = typename Data::value_type; - glBindBuffer(target, arrayBuffer); - glBufferData(target, static_cast<GLsizeiptr>(sizeof(Value) * data.size()), data.data(), GL_STATIC_DRAW); - } - -private: - template<typename VertexT, typename T> - static auto - set_pointer(const GLuint vertexArrayId, const void * ptr, const GLuint divisor) - { - using traits = gl_traits<T>; - 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<typename VertexT, MP attrib> - static auto - set_pointer(const GLuint vertexArrayId, const GLuint divisor) - { - return set_pointer<VertexT, typename decltype(attrib)::value_type>(vertexArrayId, attrib, divisor); - } - - template<typename VertexT, MP... attribs> - void - configure_attribs(const GLuint arrayBuffer, const GLuint divisor) - { - glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer); - if constexpr (sizeof...(attribs) == 0) { - vertexArrayId += set_pointer<VertexT, VertexT>(vertexArrayId, nullptr, divisor); - } - else { - ((vertexArrayId += set_pointer<VertexT, attribs>(vertexArrayId, divisor)), ...); - } - } - - GLuint vertexArrayId {}; -}; diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h index 8791aed..e78d27e 100644 --- a/gfx/models/mesh.h +++ b/gfx/models/mesh.h @@ -1,8 +1,8 @@ #pragma once #include "config/types.h" -#include "gfx/gl/vertexArrayObject.h" -#include <glArrays.h> +#include "gfx/gl/glBuffer.h" +#include <gfx/gl/glVertexArray.h> #include <glad/gl.h> #include <ranges> #include <span> @@ -53,15 +53,15 @@ public: return static_cast<RelativePosition3D>(v.pos); }))} { - VertexArrayObject::data(vertices, m_vertexArrayBuffers[0], GL_ARRAY_BUFFER); - VertexArrayObject::data(indices, m_vertexArrayBuffers[1], GL_ARRAY_BUFFER); - configureVAO(m_vertexArrayObject); + m_vertexArrayBuffers[0].storage(vertices, 0); + m_vertexArrayBuffers[1].storage(indices, 0); + configureVAO(m_vertexArrayObject, 0); } - VertexArrayObject & - configureVAO(VertexArrayObject && vao) const + auto + configureVAO(glVertexArray & vao, GLuint divisor) const { - return vao.addAttribsFor<V>(m_vertexArrayBuffers[0]).addIndices(m_vertexArrayBuffers[1]); + return vao.configure().addAttribsFor<V>(divisor, m_vertexArrayBuffers[0]).addIndices(m_vertexArrayBuffers[1]); } }; diff --git a/gfx/models/vertex.cpp b/gfx/models/vertex.cpp index c144db3..dc32f72 100644 --- a/gfx/models/vertex.cpp +++ b/gfx/models/vertex.cpp @@ -1,10 +1,10 @@ #include "vertex.h" -#include "gfx/gl/vertexArrayObject.h" +#include "gfx/gl/glVertexArray.h" template<> -VertexArrayObject & -VertexArrayObject::addAttribsFor<Vertex>(const GLuint arrayBuffer, const GLuint divisor) +Impl::VertexArrayConfigurator & +Impl::VertexArrayConfigurator::addAttribsFor<Vertex>(const GLuint divisor, const glBuffer & buffer) { return addAttribs<Vertex, &Vertex::pos, &Vertex::texCoord, &Vertex::normal, &Vertex::colour, &Vertex::material>( - arrayBuffer, divisor); + divisor, buffer); } |
