summaryrefslogtreecommitdiff
path: root/gfx/gl/instanceVertices.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/gl/instanceVertices.h')
-rw-r--r--gfx/gl/instanceVertices.h111
1 files changed, 83 insertions, 28 deletions
diff --git a/gfx/gl/instanceVertices.h b/gfx/gl/instanceVertices.h
index 28e11ee..9963a96 100644
--- a/gfx/gl/instanceVertices.h
+++ b/gfx/gl/instanceVertices.h
@@ -1,17 +1,20 @@
#pragma once
-#include "glContainer.h"
+#include "glAllocator.h"
+#include <algorithm>
#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>;
+ using IndexT = uint32_t;
public:
class [[nodiscard]] InstanceProxy {
public:
- InstanceProxy(InstanceVertices * iv, std::size_t idx) : instances {iv}, index {idx} { }
+ InstanceProxy(InstanceVertices * iv, IndexT idx) : instances {iv}, index {idx} { }
InstanceProxy(InstanceProxy && other) noexcept :
instances {std::exchange(other.instances, nullptr)}, index {other.index}
@@ -47,13 +50,15 @@ public:
}
// NOLINTNEXTLINE)hicpp-explicit-conversions
- [[nodiscard]] operator T &()
+ [[nodiscard]]
+ operator T &()
{
return instances->lookup(index);
}
// NOLINTNEXTLINE)hicpp-explicit-conversions
- [[nodiscard]] operator const T &() const
+ [[nodiscard]]
+ operator const T &() const
{
return instances->lookup(index);
}
@@ -94,9 +99,9 @@ public:
return instances->lookup(index);
}
- private:
+ // private:
InstanceVertices<T> * instances;
- std::size_t index;
+ IndexT index;
};
template<typename... Params>
@@ -106,41 +111,91 @@ public:
if (!unused.empty()) {
auto idx = unused.back();
unused.pop_back();
- index[idx] = base::size();
+ index[idx] = static_cast<IndexT>(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());
+ index.emplace_back(static_cast<IndexT>(base::size()));
+ reverseIndex.push_back(static_cast<IndexT>(base::size()));
base::emplace_back(std::forward<Params>(params)...);
- return InstanceProxy {this, index.size() - 1};
+ return InstanceProxy {this, static_cast<IndexT>(index.size() - 1)};
}
- using base::bufferName;
+ [[nodiscard]] GLuint
+ bufferName() const
+ {
+ return base::begin().base().bufferName();
+ }
- [[nodiscard]] auto
- size() const
+ [[nodiscard]] GLuint
+ indexBufferName() const
{
- base::unmap();
- return base::size();
+ return index.begin().base().bufferName();
}
+ using typename base::value_type;
+
+ 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>
- glContainer<T>::iterator
+ base::size_type
partition(Pred pred)
{
- return partition(base::begin(), base::end(), pred);
+ return indexOf(partition(base::begin(), base::end(), pred));
+ }
+
+ using PartitionResult
+ = std::pair<typename base::size_type, std::pair<typename base::size_type, typename base::size_type>>;
+
+ template<typename Pred1, typename Pred2>
+ PartitionResult
+ partition(Pred1 pred1, Pred2 pred2)
+ {
+ return partition(pred1, std::not_fn(pred2), pred2);
+ }
+
+ template<typename Pred1, typename Pred2, typename Pred3>
+ PartitionResult
+ partition(Pred1 pred1, Pred2 pred2, Pred3 pred3)
+ {
+ auto boundary1 = partition(base::begin(), base::end(), pred1);
+ auto begin2 = partition(base::begin(), boundary1, pred2);
+ auto end2 = partition(boundary1, base::end(), pred3);
+ return {indexOf(boundary1), {indexOf(begin2), indexOf(end2)}};
}
protected:
- static constexpr auto npos = static_cast<size_t>(-1);
+ static constexpr auto npos = static_cast<IndexT>(-1);
friend InstanceProxy;
+ base::size_type
+ indexOf(base::iterator iter)
+ {
+ return static_cast<base::size_type>(iter - base::begin());
+ }
+
void
- release(const size_t pidx)
+ release(const IndexT pidx)
{
- if (const size_t last = base::size() - 1; last != index[pidx]) {
+ if (const auto last = static_cast<IndexT>(base::size() - 1); last != index[pidx]) {
lookup(pidx) = std::move(base::back());
const auto movedKey = reverseIndex[last];
index[movedKey] = std::exchange(index[pidx], npos);
@@ -159,14 +214,14 @@ protected:
}
[[nodiscard]] T &
- lookup(size_t pindex)
+ lookup(IndexT pindex)
{
return base::data()[index[pindex]];
}
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);
@@ -183,8 +238,8 @@ protected:
}
// Index into buffer given to nth proxy
- std::vector<size_t> index;
- std::vector<size_t> reverseIndex;
+ glVector<IndexT> index;
+ std::vector<IndexT> reverseIndex;
// List of free spaces in index
- std::vector<size_t> unused;
+ std::vector<IndexT> unused;
};