summaryrefslogtreecommitdiff
path: root/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'gfx')
-rw-r--r--gfx/gl/glBuffer.h27
-rw-r--r--gfx/gl/glVertexArray.h125
-rw-r--r--gfx/gl/instanceVertices.h39
-rw-r--r--gfx/gl/sceneRenderer.cpp3
-rw-r--r--gfx/gl/sceneShader.cpp2
-rw-r--r--gfx/gl/vertexArrayObject.h125
-rw-r--r--gfx/models/mesh.h16
-rw-r--r--gfx/models/vertex.cpp8
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);
}