Photon Engine 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
IndexedVertexBuffer.h
Go to the documentation of this file.
1#pragma once
2
3#include "Math/TVector2.h"
4#include "Math/TVector3.h"
5#include "Utility/utility.h"
6
7#include <Common/assertion.h>
8#include <Common/primitive_type.h>
9
10#include <memory>
11#include <cstddef>
12#include <limits>
13#include <array>
14#include <climits>
15#include <type_traits>
16
17namespace ph
18{
19
20enum class EVertexAttribute : uint8
21{
22 Position_0 = 0,
27 Color_0,
28
29 // Special values
30 SIZE
31};
32
33enum class EVertexElement : uint8
34{
35 Float32 = 0,
36 Float16,
37 Int32,
38 Int16,
41
42 // Special values
43 SIZE
44};
45
49{
50 static_assert(sizeof(std::byte) * CHAR_BIT == 8,
51 "The buffer explicitly depends on the fact that std::byte contains 8 bits.");
52
53public:
55
59 EVertexAttribute attribute,
60 EVertexElement element,
61 std::size_t numElements,
62 bool shouldNormalize = false);
63
73 EVertexAttribute attribute,
74 EVertexElement element,
75 std::size_t numElements,
76 std::size_t strideOffset,
77 std::size_t strideSize,
78 bool shouldNormalize = false);
79
80 void allocate(std::size_t numVertices);
81
82 void setAttribute(EVertexAttribute attribute, std::size_t index, const math::Vector3R& value);
83 void setAttribute(EVertexAttribute attribute, std::size_t index, const math::Vector2R& value);
84 void setAttribute(EVertexAttribute attribute, std::size_t index, real value);
85 void setVertices(const std::byte* srcBytes, std::size_t numBytes, std::size_t dstOffset = 0);
86 bool hasAttribute(EVertexAttribute attribute) const;
87 math::Vector3R getAttribute(EVertexAttribute attribute, std::size_t index) const;
88 std::size_t memoryUsage() const;
89 bool isAllocated() const;
90 std::size_t numVertices() const;
91
95 std::byte* getData();
96 const std::byte* getData() const;
98
102 {
103 std::size_t strideOffset;
104 std::size_t strideSize;
106 uint8 numElements : 2;
108
110
111 bool isEmpty() const;
112 };
113
118
119private:
120 // Sizes are in bytes
121
122 // Internal info for a vertex attribute. Members are ordered to minimize padding.
123 struct Entry final
124 {
125 inline constexpr static auto INVALID_STRIDE_VALUE = static_cast<std::size_t>(-1);
126
127 union
128 {
132 std::byte* u_attributeBuffer;
133
137 std::size_t u_strideOffset;
138 };
139
141 std::size_t strideSize;
142
143 EVertexElement element;
144
146 uint8 numElements : 2;
147
153 uint8 shouldNormalize : 1;
154
155 Entry();
156
158 bool isEmpty() const;
159
160 bool hasStrideInfo() const;
161 };
162
163 bool hasEntry(EVertexAttribute attribute) const;
164 const Entry& getEntry(EVertexAttribute attribute) const;
165 void ensureConsistentVertexLayout() const;
166
167 inline constexpr static auto MAX_ENTRIES = enum_size<EVertexAttribute>();
168
169 std::array<std::underlying_type_t<EVertexAttribute>, MAX_ENTRIES> m_attributeTypeToEntryIndex;
170 std::array<Entry, MAX_ENTRIES> m_entries;
171 std::underlying_type_t<EVertexAttribute> m_numEntries;
172
173 std::unique_ptr<std::byte[]> m_byteBuffer;
174 std::size_t m_byteBufferSize;
175 uint16 m_vertexSize;
176};
177
178// In-header Implementations:
179
180inline std::size_t IndexedVertexBuffer::memoryUsage() const
181{
182 return sizeof(*this) + m_byteBufferSize;
183}
184
185inline bool IndexedVertexBuffer::Entry::isEmpty() const
186{
187 return numElements == 0;
188}
189
190inline bool IndexedVertexBuffer::Entry::hasStrideInfo() const
191{
192 // Cannot have partially filled stride info
193 PH_ASSERT(
194 (u_strideOffset != INVALID_STRIDE_VALUE && strideSize != INVALID_STRIDE_VALUE) ||
195 (u_strideOffset == INVALID_STRIDE_VALUE && strideSize == INVALID_STRIDE_VALUE));
196
197 return u_strideOffset != INVALID_STRIDE_VALUE && strideSize != INVALID_STRIDE_VALUE;
198}
199
201{
202 return m_byteBuffer != nullptr;
203}
204
205inline std::size_t IndexedVertexBuffer::numVertices() const
206{
207 return m_vertexSize > 0 ? m_byteBufferSize / m_vertexSize : 0;
208}
209
210inline void IndexedVertexBuffer::setAttribute(const EVertexAttribute attribute, const std::size_t index, const math::Vector2R& value)
211{
212 setAttribute(attribute, index, math::Vector3R(value[0], value[1], 0.0_r));
213}
214
215inline void IndexedVertexBuffer::setAttribute(const EVertexAttribute attribute, const std::size_t index, real value)
216{
217 setAttribute(attribute, index, math::Vector3R(value, 0.0_r, 0.0_r));
218}
219
220inline bool IndexedVertexBuffer::hasAttribute(const EVertexAttribute attribute) const
221{
222 return hasEntry(attribute);
223}
224
225inline bool IndexedVertexBuffer::hasEntry(const EVertexAttribute attribute) const
226{
227 return m_attributeTypeToEntryIndex[enum_to_value(attribute)] != MAX_ENTRIES;
228}
229
230inline auto IndexedVertexBuffer::getEntry(const EVertexAttribute attribute) const
231-> const Entry&
232{
233 const auto entryIndex = m_attributeTypeToEntryIndex[enum_to_value(attribute)];
234 PH_ASSERT_LT(entryIndex, m_numEntries);
235 return m_entries[entryIndex];
236}
237
239{
240 PH_ASSERT(isAllocated());
241 return m_byteBuffer.get();
242}
243
244inline const std::byte* IndexedVertexBuffer::getData() const
245{
246 PH_ASSERT(isAllocated());
247 return m_byteBuffer.get();
248}
249
251{
252 return numElements == 0;
253}
254
255}// end namespace ph
A general vertex buffer for storing various indexed attributes.
Definition IndexedVertexBuffer.h:49
std::size_t memoryUsage() const
Definition IndexedVertexBuffer.h:180
void declareAttribute(EVertexAttribute attribute, EVertexElement element, std::size_t numElements, bool shouldNormalize=false)
Declares a vertex attribute with default layout (AoS).
Definition IndexedVertexBuffer.cpp:51
std::byte * getData()
Access to the underlying raw byte buffer.
Definition IndexedVertexBuffer.h:238
AttributeDeclaration getAttributeDeclaration(EVertexAttribute attribute) const
Get information for a previously declared attribute. Can only be called after allocation.
Definition IndexedVertexBuffer.cpp:432
IndexedVertexBuffer()
Definition IndexedVertexBuffer.cpp:38
void allocate(std::size_t numVertices)
Definition IndexedVertexBuffer.cpp:135
math::Vector3R getAttribute(EVertexAttribute attribute, std::size_t index) const
Definition IndexedVertexBuffer.cpp:210
void setAttribute(EVertexAttribute attribute, std::size_t index, const math::Vector3R &value)
Definition IndexedVertexBuffer.cpp:313
bool hasAttribute(EVertexAttribute attribute) const
Definition IndexedVertexBuffer.h:220
void setVertices(const std::byte *srcBytes, std::size_t numBytes, std::size_t dstOffset=0)
Definition IndexedVertexBuffer.cpp:417
std::size_t numVertices() const
Definition IndexedVertexBuffer.h:205
bool isAllocated() const
Definition IndexedVertexBuffer.h:200
The root for all renderer implementations.
Definition EEngineProject.h:6
constexpr auto enum_size()
Definition utility.h:179
EVertexAttribute
Definition IndexedVertexBuffer.h:21
EVertexElement
Definition IndexedVertexBuffer.h:34
constexpr auto enum_to_value(const EnumType enumValue)
Definition utility.h:166
Info for a declared vertex attribute.
Definition IndexedVertexBuffer.h:102
std::size_t strideOffset
Definition IndexedVertexBuffer.h:103
uint8 numElements
Definition IndexedVertexBuffer.h:106
uint8 shouldNormalize
Definition IndexedVertexBuffer.h:107
AttributeDeclaration()
Definition IndexedVertexBuffer.cpp:28
std::size_t strideSize
Definition IndexedVertexBuffer.h:104
EVertexElement element
Definition IndexedVertexBuffer.h:105
bool isEmpty() const
Definition IndexedVertexBuffer.h:250