summaryrefslogtreecommitdiff
path: root/gfx
diff options
context:
space:
mode:
Diffstat (limited to 'gfx')
-rw-r--r--gfx/gl/instanceVertices.h56
-rw-r--r--gfx/models/mesh.cpp7
-rw-r--r--gfx/models/mesh.h3
-rw-r--r--gfx/models/stb_image.impl.c2
4 files changed, 48 insertions, 20 deletions
diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h
index a89aa78..28e11ee 100644
--- a/gfx/gl/instanceVertices.h
+++ b/gfx/gl/instanceVertices.h
@@ -1,7 +1,6 @@
#pragma once
#include "glContainer.h"
-#include "pack.h"
#include <cassert>
#include <special_members.h>
#include <utility>
@@ -14,7 +13,8 @@ public:
public:
InstanceProxy(InstanceVertices * iv, std::size_t idx) : instances {iv}, index {idx} { }
- InstanceProxy(InstanceProxy && other) : instances {std::exchange(other.instances, nullptr)}, index {other.index}
+ InstanceProxy(InstanceProxy && other) noexcept :
+ instances {std::exchange(other.instances, nullptr)}, index {other.index}
{
}
@@ -28,7 +28,7 @@ public:
}
InstanceProxy &
- operator=(InstanceProxy && other)
+ operator=(InstanceProxy && other) noexcept
{
if (instances) {
instances->release(index);
@@ -39,17 +39,20 @@ public:
}
template<typename U>
- T &
+ InstanceProxy &
operator=(U && v)
{
- return instances->lookup(index) = std::forward<U>(v);
+ instances->lookup(index) = std::forward<U>(v);
+ return *this;
}
+ // NOLINTNEXTLINE)hicpp-explicit-conversions
[[nodiscard]] operator T &()
{
return instances->lookup(index);
}
+ // NOLINTNEXTLINE)hicpp-explicit-conversions
[[nodiscard]] operator const T &() const
{
return instances->lookup(index);
@@ -104,10 +107,12 @@ public:
auto idx = unused.back();
unused.pop_back();
index[idx] = base::size();
+ reverseIndex.emplace_back(idx);
base::emplace_back(std::forward<Params>(params)...);
return InstanceProxy {this, idx};
}
index.emplace_back(base::size());
+ reverseIndex.push_back(base::size());
base::emplace_back(std::forward<Params>(params)...);
return InstanceProxy {this, index.size() - 1};
}
@@ -121,25 +126,35 @@ public:
return base::size();
}
+ template<typename Pred>
+ glContainer<T>::iterator
+ partition(Pred pred)
+ {
+ return partition(base::begin(), base::end(), pred);
+ }
+
protected:
+ static constexpr auto npos = static_cast<size_t>(-1);
friend InstanceProxy;
void
release(const size_t pidx)
{
- if (base::size() - 1 != index[pidx]) {
+ if (const size_t last = base::size() - 1; last != index[pidx]) {
lookup(pidx) = std::move(base::back());
- *std::find_if(index.begin(), index.end(), [this, old = base::size() - 1](const auto & i) {
- return i == old && !std::binary_search(unused.begin(), unused.end(), &i - index.data());
- }) = index[pidx];
+ const auto movedKey = reverseIndex[last];
+ index[movedKey] = std::exchange(index[pidx], npos);
+ reverseIndex[index[movedKey]] = movedKey;
}
base::pop_back();
+ reverseIndex.pop_back();
if (pidx == index.size() - 1) {
index.pop_back();
}
else {
- // Remember p.index is free index now, keeping it sorted
- unused.insert(std::upper_bound(unused.begin(), unused.end(), pidx), pidx);
+ index[pidx] = npos;
+ // Remember p.index is free index now
+ unused.emplace_back(pidx);
}
}
@@ -149,8 +164,27 @@ protected:
return base::data()[index[pindex]];
}
+ template<typename Pred>
+ glContainer<T>::iterator
+ partition(glContainer<T>::iterator first, glContainer<T>::iterator last, Pred pred)
+ {
+ while (first < last) {
+ first = std::find_if_not(first, last, pred);
+ last = --std::find_if(std::make_reverse_iterator(last), std::make_reverse_iterator(first), pred).base();
+ if (first < last) {
+ std::iter_swap(first, last);
+ const auto fidx = static_cast<size_t>(first - base::begin()),
+ lidx = static_cast<size_t>(last - base::begin());
+ std::swap(index[reverseIndex[fidx]], index[reverseIndex[lidx]]);
+ std::swap(reverseIndex[fidx], reverseIndex[lidx]);
+ }
+ }
+ return first;
+ }
+
// Index into buffer given to nth proxy
std::vector<size_t> index;
+ std::vector<size_t> reverseIndex;
// List of free spaces in index
std::vector<size_t> unused;
};
diff --git a/gfx/models/mesh.cpp b/gfx/models/mesh.cpp
index 1f4dc09..e7474ca 100644
--- a/gfx/models/mesh.cpp
+++ b/gfx/models/mesh.cpp
@@ -1,7 +1,4 @@
#include "mesh.h"
-#include "glArrays.h"
-#include "vertex.h"
-#include <cstddef>
MeshBase::MeshBase(GLsizei m_numIndices, GLenum mode) : m_numIndices {m_numIndices}, mode {mode} { }
@@ -16,11 +13,11 @@ MeshBase::Draw() const
}
void
-MeshBase::DrawInstanced(GLuint vao, GLsizei count) const
+MeshBase::DrawInstanced(GLuint vao, GLsizei count, GLuint base) const
{
glBindVertexArray(vao);
- glDrawElementsInstanced(mode, m_numIndices, GL_UNSIGNED_INT, nullptr, count);
+ glDrawElementsInstancedBaseInstance(mode, m_numIndices, GL_UNSIGNED_INT, nullptr, count, base);
glBindVertexArray(0);
}
diff --git a/gfx/models/mesh.h b/gfx/models/mesh.h
index 71f6dce..248cb8f 100644
--- a/gfx/models/mesh.h
+++ b/gfx/models/mesh.h
@@ -3,7 +3,6 @@
#include "gfx/gl/vertexArrayObject.h"
#include <glArrays.h>
#include <glad/gl.h>
-#include <memory>
#include <span>
#include <stdTypeDefs.h>
@@ -12,7 +11,7 @@ class Vertex;
class MeshBase {
public:
void Draw() const;
- void DrawInstanced(GLuint vao, GLsizei count) const;
+ void DrawInstanced(GLuint vao, GLsizei count, GLuint base = 0) const;
protected:
MeshBase(GLsizei m_numIndices, GLenum mode);
diff --git a/gfx/models/stb_image.impl.c b/gfx/models/stb_image.impl.c
deleted file mode 100644
index 38c72e9..0000000
--- a/gfx/models/stb_image.impl.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define STB_IMAGE_IMPLEMENTATION
-#include "stb/stb_image.h"