CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
VertexDeclaration.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
11
18
20
21namespace CeresEngine {
22
50
52 struct VertexElementType final : public StructEnum<VertexElementType> {
58
61
64
67
70
73
76
79 } raw;
81
82
83 template<typename T> static constexpr VertexElementType fromType() noexcept;
84
85 public:
88
90 [[nodiscard]] bool isNone() const noexcept { return raw == None; }
91
93 [[nodiscard]] bool isScalar() const noexcept { return raw == Scalar; }
94
96 [[nodiscard]] bool isVector() const noexcept { return raw == Vector2 || raw == Vector3 || raw == Vector4; }
97
99 [[nodiscard]] bool isMatrix() const noexcept { return raw == Matrix2 || raw == Matrix3 || raw == Matrix4; }
100 };
101
103 struct VertexElementComponentType final : public StructEnum<VertexElementComponentType> {
108
111
114
117
120
123
126
129
132
135
138
143
144
145 template<typename T> static constexpr VertexElementComponentType fromType() noexcept;
146
147 public:
150 };
151
154 public:
158
161
164
166 UInt32 streamIndex = 0;
167
171 bool normalized = false;
172
173 public:
175 [[nodiscard]] std::size_t getSize() const noexcept;
176
181 template<typename T> [[nodiscard]] bool is() const noexcept;
182
183 public:
186
190
193 object.toString(stream);
194 return stream;
195 }
196
197 public:
198 friend bool operator==(const VertexElement& lhs, const VertexElement& rhs) noexcept {
199 return lhs.semantic == rhs.semantic && lhs.type == rhs.type && lhs.componentType == rhs.componentType && lhs.normalized == rhs.normalized;
200 }
201 friend bool operator!=(const VertexElement& lhs, const VertexElement& rhs) noexcept { return !(rhs == lhs); }
202 };
203
207
208 public: // Vertex Elements
218 [[nodiscard]] const VertexElement* getElement(const VertexElementSemantic& semantic, UInt32 index = 0) const noexcept;
219
221 [[nodiscard]] VertexElement* getElement(const VertexElementSemantic& semantic, UInt32 index = 0) noexcept;
222
230 VertexElement& addElement(const VertexElementSemantic& semantic, const VertexElementType& type,
231 const VertexElementComponentType& componentType = VertexElementComponentType::Float32, bool normalized = false);
232
242 template<typename T> VertexElement& addElement(const VertexElementSemantic& semantic, bool normalized = false);
243
250 [[nodiscard]] bool removeElement(const VertexElementSemantic& semantic, UInt32 index = 0) noexcept;
251
252 public: // Vertex Buffer
254 [[nodiscard]] std::size_t getSize() const noexcept;
255
258 [[nodiscard]] std::size_t getElementOffset(const VertexElementSemantic& semantic, UInt32 index = 0) const noexcept;
259
260 public:
262 [[nodiscard]] String toString() const noexcept;
263
266 void toString(std::ostream& stream) const noexcept;
267
269 friend std::ostream& operator<<(std::ostream& stream, const VertexDeclaration& object) {
270 object.toString(stream);
271 return stream;
272 }
273
274 public: // Comparison & Hashing
275 friend bool operator==(const VertexDeclaration& lhs, const VertexDeclaration& rhs) noexcept;
276 friend bool operator!=(const VertexDeclaration& lhs, const VertexDeclaration& rhs) noexcept;
277 };
278
279 // ---------------------------------------------------------------------------------------------
280
287
289 UInt64 offset = 0;
290
293 UInt64 stride = ~0u;
294
295 public:
297 [[nodiscard]] String toString() const noexcept;
298
301 void toString(std::ostream& stream) const noexcept;
302
304 friend std::ostream& operator<<(std::ostream& stream, const VertexBufferLayoutElement& object) {
305 object.toString(stream);
306 return stream;
307 }
308
309 public: // Comparison & Hashing
310 friend bool operator==(const VertexBufferLayoutElement& lhs, const VertexBufferLayoutElement& rhs) noexcept;
311 friend bool operator!=(const VertexBufferLayoutElement& lhs, const VertexBufferLayoutElement& rhs) noexcept;
312 };
313
321
324
325 public:
336 [[nodiscard]] const VertexBufferLayoutElement* getElement(const VertexElementSemantic& semantic, UInt32 index = 0) const noexcept;
337
339 [[nodiscard]] VertexBufferLayoutElement* getElement(const VertexElementSemantic& semantic, UInt32 index = 0) noexcept;
340
341 template<typename T>
342 [[nodiscard]] StridedMemoryView<T> getElementView(const MemoryView<Byte>& data, const VertexElementSemantic& semantic, const UInt32 index = 0) {
343 CE_ASSERT(data.size() >= getSize() * length);
344
345 const VertexBufferLayoutElement* element = getElement(semantic, index);
346 if(element == nullptr) {
347 return nullptr;
348 }
349
350 CE_ASSERT(element->element.is<T>());
351 return make_strided_memory_view<T>(data, element->offset, element->stride);
352 }
353
355 template<typename T>
356 [[nodiscard]] StridedMemoryView<const T> getElementView(const MemoryView<const Byte>& data, const VertexElementSemantic& semantic, const UInt32 index = 0) {
357 // NOTE: It's safe to perform the const_cast here as it's later
358 // converted back to a `const T` view.
359 return getElementView<T>(data.as<Byte>(), semantic, index).template as<const T>();
360 }
361
362 void validate();
363
364 public: // Buffer sizes
370 void resize(UInt64 newVertexCount);
371
373 void offsetBy(const Int64 offset) const;
374
376 [[nodiscard]] std::size_t getSize() const noexcept;
377
379 [[nodiscard]] std::size_t getVertexSize() const noexcept;
380
381 public: // Standard layouts
382 static VertexBufferLayout separated(const Span<const VertexElement>& elements, UInt64 vertexCount);
383
385 static VertexBufferLayout separated(const VertexDeclaration& declaration, const UInt64 vertexCount) {
386 return separated(declaration.elements, vertexCount);
387 }
388
390
392 static VertexBufferLayout interleaved(const VertexDeclaration& declaration, const UInt64 vertexCount) {
393 return interleaved(declaration.elements, vertexCount);
394 }
395
396 public:
398 [[nodiscard]] String toString() const noexcept;
399
402 void toString(std::ostream& stream) const noexcept;
403
405 friend std::ostream& operator<<(std::ostream& stream, const VertexBufferLayout& object) {
406 object.toString(stream);
407 return stream;
408 }
409
410 public: // Comparison & Hashing
411 friend bool operator==(const VertexBufferLayout& lhs, const VertexBufferLayout& rhs) noexcept;
412 friend bool operator!=(const VertexBufferLayout& lhs, const VertexBufferLayout& rhs) noexcept;
413 };
414
415 // ---------------------------------------------------------------------------------------------
416 // ---------------------------------------------------------------------------------------------
417
418 template<typename T> struct VertexElementTypeTrait { static inline constexpr VertexElementType value = VertexElementType::Scalar; };
419 template<typename T> struct VertexElementTypeTrait<TVector2<T>> { static inline constexpr VertexElementType value = VertexElementType::Vector2; };
420 template<typename T> struct VertexElementTypeTrait<TVector3<T>> { static inline constexpr VertexElementType value = VertexElementType::Vector3; };
421 template<typename T> struct VertexElementTypeTrait<TVector4<T>> { static inline constexpr VertexElementType value = VertexElementType::Vector4; };
422 template<typename T> struct VertexElementTypeTrait<TMatrix2<T>> { static inline constexpr VertexElementType value = VertexElementType::Matrix2; };
423 template<typename T> struct VertexElementTypeTrait<TMatrix3<T>> { static inline constexpr VertexElementType value = VertexElementType::Matrix3; };
424 template<typename T> struct VertexElementTypeTrait<TMatrix4<T>> { static inline constexpr VertexElementType value = VertexElementType::Matrix4; };
425 template<typename T> struct VertexElementTypeTrait<TColor<T>> { static inline constexpr VertexElementType value = VertexElementType::Vector4; };
426
428
429 // ---------------------------------------------------------------------------------------------
430
431 template<typename T> struct VertexElementComponentTypeTrait;
433 static inline constexpr VertexElementComponentType value = VertexElementComponentType::Float32;
434 };
436 static inline constexpr VertexElementComponentType value = VertexElementComponentType::Float64;
437 };
438 template<> struct VertexElementComponentTypeTrait<Int8> { static inline constexpr VertexElementComponentType value = VertexElementComponentType::Int8; };
439 template<> struct VertexElementComponentTypeTrait<UInt8> { static inline constexpr VertexElementComponentType value = VertexElementComponentType::UInt8; };
440 template<> struct VertexElementComponentTypeTrait<Int16> { static inline constexpr VertexElementComponentType value = VertexElementComponentType::Int16; };
442 static inline constexpr VertexElementComponentType value = VertexElementComponentType::UInt16;
443 };
444 template<> struct VertexElementComponentTypeTrait<Int32> { static inline constexpr VertexElementComponentType value = VertexElementComponentType::Int32; };
446 static inline constexpr VertexElementComponentType value = VertexElementComponentType::UInt32;
447 };
448 template<> struct VertexElementComponentTypeTrait<Int64> { static inline constexpr VertexElementComponentType value = VertexElementComponentType::Int64; };
450 static inline constexpr VertexElementComponentType value = VertexElementComponentType::UInt64;
451 };
452 template<> struct VertexElementComponentTypeTrait<bool> { static inline constexpr VertexElementComponentType value = VertexElementComponentType::Boolean; };
453
457
458 // ---------------------------------------------------------------------------------------------
459
460 template<typename T> struct VertexElementTrait {
461 static inline constexpr VertexElementType type = VertexElementType::fromType<T>();
462 static inline constexpr VertexElementComponentType componentType = VertexElementComponentType::fromType<T>();
463 };
464
465 template<size_t D, typename T> struct VertexElementTrait<TVector<D, T>> {
466 static inline constexpr VertexElementType type = VertexElementType::fromType<TVector<D, T>>();
467 static inline constexpr VertexElementComponentType componentType = VertexElementComponentType::fromType<T>();
468 };
469
470 template<size_t C, size_t R, typename T> struct VertexElementTrait<TMatrix<C, R, T>> {
471 static inline constexpr VertexElementType type = VertexElementType::fromType<TMatrix<C, R, T>>();
472 static inline constexpr VertexElementComponentType componentType = VertexElementComponentType::fromType<T>();
473 };
474
475 template<typename T> struct VertexElementTrait<TColor<T>> {
476 static inline constexpr VertexElementType type = VertexElementType::fromType<TColor<T>>();
477 static inline constexpr VertexElementComponentType componentType = VertexElementComponentType::fromType<T>();
478 };
479
480 template<typename T> bool VertexElement::is() const noexcept {
481 return type == VertexElementTrait<T>::type && componentType == VertexElementTrait<T>::componentType;
482 }
483
484 template<typename T> VertexElement& VertexDeclaration::addElement(const VertexElementSemantic& semantic, const bool normalized) {
485 return addElement(semantic, VertexElementTrait<T>::type, VertexElementTrait<T>::componentType, normalized);
486 }
487
488} // namespace CeresEngine
489
491template<> struct std::hash<CeresEngine::VertexElementSemantic> {
492 inline size_t operator()(const CeresEngine::VertexElementSemantic object) const noexcept { return CeresEngine::hash(object.raw); }
493};
494
496template<> struct std::hash<CeresEngine::VertexElementType> {
497 inline size_t operator()(const CeresEngine::VertexElementType object) const noexcept { return CeresEngine::hash(object.raw); }
498};
499
501template<> struct std::hash<CeresEngine::VertexElementComponentType> {
502 inline size_t operator()(const CeresEngine::VertexElementComponentType object) const noexcept { return CeresEngine::hash(object.raw); }
503};
504
506template<> struct std::hash<CeresEngine::VertexElement> {
507 inline size_t operator()(const CeresEngine::VertexElement& object) const noexcept {
508 return CeresEngine::hash(object.semantic, object.type, object.componentType, object.normalized);
509 }
510};
511
513template<> struct std::hash<CeresEngine::VertexDeclaration> {
514 inline size_t operator()(const CeresEngine::VertexDeclaration& object) const noexcept { return CeresEngine::hash(object.elements); }
515};
516
517
518
519
520
521
#define CE_ASSERT(...)
Definition Macros.hpp:323
#define CE_STRUCT_ENUM_DECL(T)
Definition StructEnum.hpp:49
A memory view is a class which attaches to an chunk of memory and provides a view to it (optionally c...
Definition MemoryView.hpp:62
A memory view is a class which attaches to an chunk of memory and provides a view to it (optionally c...
Definition MemoryView.hpp:439
Definition StructEnum.hpp:18
UInt32 UnderlyingType
Definition StructEnum.hpp:20
Determines how a single element should be a vertex.
Definition VertexDeclaration.hpp:153
bool is() const noexcept
Checks if the vertex element type and component type matches the C++ type T.
Definition VertexDeclaration.hpp:480
VertexElementSemantic semantic
The semantic that is used for identifying the meaning of the element in a vertex buffer.
Definition VertexDeclaration.hpp:157
friend bool operator==(const VertexElement &lhs, const VertexElement &rhs) noexcept
Definition VertexDeclaration.hpp:198
friend bool operator!=(const VertexElement &lhs, const VertexElement &rhs) noexcept
Definition VertexDeclaration.hpp:201
std::size_t getSize() const noexcept
Returns the length, in bytes, of the vertex element.
Definition Application.hpp:19
Byte
Definition DataTypes.hpp:40
std::uint64_t UInt64
Definition DataTypes.hpp:26
std::int32_t Int32
Definition DataTypes.hpp:21
std::uint16_t UInt16
Definition DataTypes.hpp:20
std::uint8_t UInt8
Definition DataTypes.hpp:17
std::int64_t Int64
Definition DataTypes.hpp:24
sfl::small_vector< T, N, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > SmallVector
SmallVector is a sequence container similar to Vector.
Definition SmallVector.hpp:31
std::uint32_t UInt32
Definition DataTypes.hpp:23
tcb ::span< T, Extent > Span
Span describes an object that can refer to a contiguous sequence of objects with the first element of...
Definition Span.hpp:708
std::int8_t Int8
Definition DataTypes.hpp:15
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
std::int16_t Int16
Definition DataTypes.hpp:18
Definition Span.hpp:668
Determines how a single VertexElement is laid out on the vertex buffer.
Definition VertexDeclaration.hpp:283
UInt64 offset
The offset to where this vertex element starts.
Definition VertexDeclaration.hpp:289
friend bool operator!=(const VertexBufferLayoutElement &lhs, const VertexBufferLayoutElement &rhs) noexcept
friend bool operator==(const VertexBufferLayoutElement &lhs, const VertexBufferLayoutElement &rhs) noexcept
UInt64 stride
The stride, the amount of bytes to skip to reach the next vertex data.
Definition VertexDeclaration.hpp:293
VertexElement element
The vertex element description.
Definition VertexDeclaration.hpp:286
String toString() const noexcept
Gets a string representation of the VertexBufferLayoutElement.
Determines how a vertex buffer is laid out in memory.
Definition VertexDeclaration.hpp:318
void offsetBy(const Int64 offset) const
Offsets the vertex buffer by the given amount.
String toString() const noexcept
Gets a string representation of the VertexBufferLayout.
StridedMemoryView< const T > getElementView(const MemoryView< const Byte > &data, const VertexElementSemantic &semantic, const UInt32 index=0)
Definition VertexDeclaration.hpp:356
static VertexBufferLayout interleaved(const Span< const VertexElement > &elements, UInt64 vertexCount)
SmallVector< VertexBufferLayoutElement, 10 > elements
The elements on the vertex stream layout.
Definition VertexDeclaration.hpp:320
friend bool operator==(const VertexBufferLayout &lhs, const VertexBufferLayout &rhs) noexcept
static VertexBufferLayout interleaved(const VertexDeclaration &declaration, const UInt64 vertexCount)
Definition VertexDeclaration.hpp:392
const VertexBufferLayoutElement * getElement(const VertexElementSemantic &semantic, UInt32 index=0) const noexcept
Finds a VertexElement with the given semantic.
std::size_t getSize() const noexcept
Computes the size of a single vertex, in bytes.
friend bool operator!=(const VertexBufferLayout &lhs, const VertexBufferLayout &rhs) noexcept
void resize(UInt64 newVertexCount)
Resizes the vertex buffer layout to accommodate newVertexCount vertices.
UInt64 length
The total number of vertices in the vertex buffer.
Definition VertexDeclaration.hpp:323
Determines how vertices are laid-out on a vertex buffer or a mesh data.
Definition VertexDeclaration.hpp:205
friend bool operator!=(const VertexDeclaration &lhs, const VertexDeclaration &rhs) noexcept
VertexElement & addElement(const VertexElementSemantic &semantic, const VertexElementType &type, const VertexElementComponentType &componentType=VertexElementComponentType::Float32, bool normalized=false)
Adds a new element to the declaration.
friend bool operator==(const VertexDeclaration &lhs, const VertexDeclaration &rhs) noexcept
SmallVector< VertexElement, 10 > elements
Definition VertexDeclaration.hpp:206
const VertexElement * getElement(const VertexElementSemantic &semantic, UInt32 index=0) const noexcept
Finds a VertexElement with the given semantic.
Determines the data type used for the each component of a VertexElement.
Definition VertexDeclaration.hpp:103
StringView toString() const noexcept
Gets a string representation of VertexElementComponentType.
enum CeresEngine::VertexElementComponentType::@30 raw
The underlying raw value of VertexElementComponentType.
static constexpr VertexElementComponentType fromType() noexcept
Creates a new VertexElementComponentType from the C++ type T.
Definition VertexDeclaration.hpp:454
std::size_t getSize() const noexcept
Gets the size of a single component.
@ Float64
Each component of the element is a 64-bit floating point (double).
Definition VertexDeclaration.hpp:113
@ Int64
Each component of the element is a 64-bit signed integer.
Definition VertexDeclaration.hpp:134
@ Float32
Each component of the element is a 32-bit floating point (float).
Definition VertexDeclaration.hpp:110
@ UInt8
Each component of the element is a 8-bit unsigned integer.
Definition VertexDeclaration.hpp:119
@ Int32
Each component of the element is a 32-bit signed integer.
Definition VertexDeclaration.hpp:128
@ UInt16
Each component of the element is a 16-bit unsigned integer.
Definition VertexDeclaration.hpp:125
@ Int16
Each component of the element is a 16-bit signed integer.
Definition VertexDeclaration.hpp:122
@ Int8
Each component of the element is a 8-bit signed integer.
Definition VertexDeclaration.hpp:116
@ UInt64
Each component of the element is a 64-bit unsigned integer.
Definition VertexDeclaration.hpp:137
@ Float16
Each component of the element is a 16-bit floating point (half float).
Definition VertexDeclaration.hpp:107
@ Boolean
Each component of the element is a 32-bit boolean type.
Definition VertexDeclaration.hpp:140
@ UInt32
Each component of the element is a 32-bit unsigned integer.
Definition VertexDeclaration.hpp:131
Definition VertexDeclaration.hpp:431
Determines the semantic of a VertexElement.
Definition VertexDeclaration.hpp:24
enum CeresEngine::VertexElementSemantic::@28 raw
The underlying raw value of VertexElementSemantic.
@ Color
The vertex element represents a vertex color channel.
Definition VertexDeclaration.hpp:46
@ TexCoord
The vertex element represents the vertex texture coordinate.
Definition VertexDeclaration.hpp:37
@ Normal
The vertex element represents the vertex normal vector.
Definition VertexDeclaration.hpp:34
@ Position
The vertex element represents the vertex position.
Definition VertexDeclaration.hpp:31
@ Bitangent
The vertex element represents the vertex bi-tangent vector.
Definition VertexDeclaration.hpp:43
@ None
The vertex element should be ignored and don't represent anything.
Definition VertexDeclaration.hpp:28
@ Tangent
The vertex element represents the vertex tangent vector.
Definition VertexDeclaration.hpp:40
Definition VertexDeclaration.hpp:460
Enumeration that determines the type of a VertexElement.
Definition VertexDeclaration.hpp:52
@ Vector3
The vertex element is a 3-component vector.
Definition VertexDeclaration.hpp:66
@ Scalar
The vertex element is a scalar.
Definition VertexDeclaration.hpp:60
@ Vector2
The vertex element is a 2-component vector.
Definition VertexDeclaration.hpp:63
@ Vector4
The vertex element is a 4-component vector.
Definition VertexDeclaration.hpp:69
@ Matrix4
The vertex element is a 4x4 matrix.
Definition VertexDeclaration.hpp:78
@ Matrix2
The vertex element is a 2x2 matrix.
Definition VertexDeclaration.hpp:72
@ None
The vertex element has no type and thus no size.
Definition VertexDeclaration.hpp:57
@ Matrix3
The vertex element is a 3x3 matrix.
Definition VertexDeclaration.hpp:75
static constexpr VertexElementType fromType() noexcept
Creates a new VertexElementType from the C++ type T.
Definition VertexDeclaration.hpp:427
bool isMatrix() const noexcept
Returns true if the element type is a matrix type.
Definition VertexDeclaration.hpp:99
bool isScalar() const noexcept
Returns true if the element type is a vector type.
Definition VertexDeclaration.hpp:93
bool isNone() const noexcept
Returns true if the element type is a vector type.
Definition VertexDeclaration.hpp:90
bool isVector() const noexcept
Returns true if the element type is a vector type.
Definition VertexDeclaration.hpp:96
std::size_t getComponentCount() const noexcept
Gets the number of components on the type.
enum CeresEngine::VertexElementType::@29 raw
The underlying raw value of VertexElementType.
Definition VertexDeclaration.hpp:418