Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#5584: Start implementing container classes storing the winding vertices
- Loading branch information
1 parent
d9ac2ae
commit dd9d9b8
Showing
10 changed files
with
236 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#pragma once | ||
|
||
#include <vector> | ||
#include <limits> | ||
#include "render/ArbitraryMeshVertex.h" | ||
|
||
namespace render | ||
{ | ||
|
||
/** | ||
* A winding renderer accepts a variable number of windings and arranges them into | ||
* one or more continuous blocks of vertices for efficient rendering. | ||
* | ||
* The internal arrangement has the goal of reducing the amount of draw calls for | ||
* winding sharing a single material. Allocating a winding slot yields a handle which | ||
* allows for later update or deallocation of the slot. | ||
* | ||
* Only the vertex data (XYZ, UV, Normals, Colour) needs to be submitted, | ||
* the render indices of each winding slot are handled internally. | ||
*/ | ||
class IWindingRenderer | ||
{ | ||
public: | ||
virtual ~IWindingRenderer() {} | ||
|
||
using Slot = std::size_t; | ||
static constexpr Slot InvalidSlot = std::numeric_limits<std::size_t>::max(); | ||
|
||
// Allocate a slot to hold the vertex data of a winding of the given size | ||
// Returns the handle which can be used to update or deallocate the data later | ||
virtual Slot allocateWinding(int size) = 0; | ||
|
||
// Releases a previously allocated winding slot. This invalidates the handle. | ||
virtual void deallocateWinding(Slot slot) = 0; | ||
|
||
// Sets the winding data | ||
virtual void updateWinding(Slot slot, const std::vector<ArbitraryMeshVertex>& vertices) = 0; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#pragma once | ||
|
||
#include <vector> | ||
|
||
namespace render | ||
{ | ||
|
||
template<typename VertexT> | ||
class CompactWindingVertexBuffer | ||
{ | ||
private: | ||
std::size_t _size; | ||
std::size_t _numIndicesPerWinding; | ||
|
||
std::vector<VertexT> _vertices; | ||
|
||
// The indices suitable for rendering triangles | ||
std::vector<unsigned int> _indices; | ||
|
||
public: | ||
CompactWindingVertexBuffer(std::size_t size) : | ||
_size(size), | ||
_numIndicesPerWinding(3 * (_size - 2)) | ||
{} | ||
|
||
CompactWindingVertexBuffer(const CompactWindingVertexBuffer& other) = delete; | ||
CompactWindingVertexBuffer& operator=(const CompactWindingVertexBuffer& other) = delete; | ||
|
||
std::size_t getWindingSize() const | ||
{ | ||
return _size; | ||
} | ||
|
||
std::size_t getNumIndicesPerWinding() const | ||
{ | ||
return _numIndicesPerWinding; | ||
} | ||
|
||
const std::vector<VertexT>& getVertices() const | ||
{ | ||
return _vertices; | ||
} | ||
|
||
const std::vector<unsigned int>& getIndices() const | ||
{ | ||
return _indices; | ||
} | ||
|
||
// Appends the given winding data to the end of the buffer, returns the position in the array | ||
std::size_t pushWinding(const std::vector<VertexT>& winding) | ||
{ | ||
assert(winding.size() == _size); | ||
|
||
auto currentSize = _vertices.size(); | ||
auto position = currentSize / _size; | ||
_vertices.reserve(currentSize + _size); // reserve() never shrinks | ||
|
||
std::copy(winding.begin(), winding.end(), std::back_inserter(_vertices)); | ||
|
||
// Allocate and calculate indices | ||
_indices.reserve(_indices.size() + _numIndicesPerWinding); | ||
|
||
for (unsigned int n = static_cast<unsigned int>(_size) - 1; n - 1 > 0; --n) | ||
{ | ||
_indices.push_back(0); | ||
_indices.push_back(n - 1); | ||
_indices.push_back(n); | ||
} | ||
|
||
return position; | ||
} | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#pragma once | ||
|
||
#include "iwindingrenderer.h" | ||
|
||
namespace render | ||
{ | ||
|
||
class WindingRenderer : | ||
public IWindingRenderer | ||
{ | ||
private: | ||
|
||
|
||
public: | ||
Slot allocateWinding(int size) override | ||
{ | ||
// Get the Bucket this Slot is referring to | ||
|
||
return InvalidSlot; | ||
} | ||
|
||
void deallocateWinding(Slot slot) override | ||
{ | ||
|
||
} | ||
|
||
void updateWinding(Slot slot, const std::vector<ArbitraryMeshVertex>& vertices) override | ||
{ | ||
|
||
} | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
#include "gtest/gtest.h" | ||
#include "render/ArbitraryMeshVertex.h" | ||
#include "render/WindingRenderer.h" | ||
#include "render/CompactWindingVertexBuffer.h" | ||
|
||
namespace test | ||
{ | ||
|
||
using VertexBuffer = render::CompactWindingVertexBuffer<ArbitraryMeshVertex>; | ||
|
||
inline std::vector<ArbitraryMeshVertex> createWinding(int id, int size) | ||
{ | ||
std::vector<ArbitraryMeshVertex> winding; | ||
|
||
for (int i = 0; i < size; ++i) | ||
{ | ||
winding.emplace_back(ArbitraryMeshVertex({ id + 0.0, id + 0.5, id + 0.3 }, { 0, 0, id + 0.0 }, { id + 0.0, -id + 0.0 })); | ||
} | ||
|
||
return winding; | ||
} | ||
|
||
inline void checkWindingIndices(const VertexBuffer& buffer, std::size_t slot) | ||
{ | ||
// Slot must be within range | ||
auto windingSize = buffer.getWindingSize(); | ||
|
||
EXPECT_LT(slot, buffer.getVertices().size() / windingSize); | ||
|
||
// Assume the indices are within bounds | ||
auto indexStart = buffer.getNumIndicesPerWinding() * slot; | ||
EXPECT_LE(indexStart + buffer.getNumIndicesPerWinding(), buffer.getIndices().size()); | ||
|
||
// Check the indices, they must be referencing vertices in that slot | ||
for (auto i = indexStart; i < indexStart + buffer.getNumIndicesPerWinding(); ++i) | ||
{ | ||
auto index = buffer.getIndices().at(i); | ||
EXPECT_GE(index, slot * windingSize) << "Winding index out of lower bounds"; | ||
EXPECT_LT(index, (slot + 1) * windingSize) << "Winding index out of upper bounds"; | ||
} | ||
} | ||
|
||
TEST(CompactWindingVertexBuffer, NumIndicesPerWinding) | ||
{ | ||
for (auto i = 0; i < 10; ++i) | ||
{ | ||
VertexBuffer buffer(i); | ||
EXPECT_EQ(buffer.getWindingSize(), i); | ||
EXPECT_EQ(buffer.getNumIndicesPerWinding(), 3 * (buffer.getWindingSize() - 2)); | ||
} | ||
} | ||
|
||
TEST(CompactWindingVertexBuffer, AddSingleWinding) | ||
{ | ||
auto winding1 = createWinding(1, 4); | ||
|
||
VertexBuffer buffer(4); | ||
|
||
auto slot = buffer.pushWinding(winding1); | ||
|
||
EXPECT_EQ(slot, 0) << "Wrong slot assignment"; | ||
EXPECT_EQ(buffer.getVertices().size(), 4); | ||
EXPECT_EQ(buffer.getIndices().size(), buffer.getNumIndicesPerWinding()); | ||
|
||
// Assume that the indices have been correctly calculated | ||
checkWindingIndices(buffer, slot); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters