candlewick 0.11.0
A tiny cross-platform renderer based on SDL3
Loading...
Searching...
No Matches
MeshData.h
Go to the documentation of this file.
1#pragma once
2
3#include "Utils.h"
4#include "StridedView.h"
5#include "../core/errors.h"
8#include "../core/Tags.h"
9
10#include <span>
11#include <SDL3/SDL_assert.h>
12#include <SDL3/SDL_gpu.h>
13
14namespace candlewick {
15
16template <typename Derived> struct MeshDataBase {
17 Derived &derived() { return static_cast<Derived &>(*this); }
18 const Derived &derived() const { return static_cast<const Derived &>(*this); }
19
20 Uint32 numVertices() const { return derived().numVertices(); }
21
22 Uint32 numIndices() const {
23 return static_cast<Uint32>(derived().indexData.size());
24 }
25 bool isIndexed() const { return numIndices() > 0; }
26};
27
33class MeshData : public MeshDataBase<MeshData> {
34 std::vector<char> m_vertexData; //< Type-erased vertex data
35 Uint32 m_numVertices; //< Actual number of vertices
36
37 MeshData(const MeshData &) = default;
38
39public:
40 using IndexType = Uint32;
41 SDL_GPUPrimitiveType primitiveType; //< Geometry primitive for the mesh.
42 MeshLayout layout; //< %Mesh layout.
43 std::vector<IndexType> indexData; //< Indices for indexed mesh. Optional.
44 PbrMaterial material; //< Mesh material.
45
46 explicit MeshData(NoInitT);
47
48 template <IsVertexType VertexT>
49 explicit MeshData(SDL_GPUPrimitiveType primitiveType,
50 std::vector<VertexT> vertexData,
51 std::vector<IndexType> indexData = {});
52
53 explicit MeshData(SDL_GPUPrimitiveType primitiveType,
54 const MeshLayout &layout, std::vector<char> vertexData,
55 std::vector<IndexType> indexData = {});
56
57 MeshData(MeshData &&) noexcept = default;
58 MeshData &operator=(MeshData &&) noexcept = default;
59 MeshData &operator=(const MeshData &) noexcept = delete;
60
62 [[nodiscard]] static MeshData copy(const MeshData &other) {
63 return MeshData{other};
64 };
65
67 Uint32 numVertices() const noexcept { return m_numVertices; }
69 Uint32 vertexSize() const noexcept { return layout.vertexSize(); }
71 Uint64 vertexBytes() const noexcept { return m_vertexData.size(); }
72
76 template <typename U> std::span<U> viewAs() {
77 U *begin = reinterpret_cast<U *>(m_vertexData.data());
78 return std::span<U>(begin, m_numVertices);
79 }
80
82 template <typename U> std::span<const U> viewAs() const {
83 const U *begin = reinterpret_cast<const U *>(m_vertexData.data());
84 return std::span<const U>(begin, m_numVertices);
85 }
86
89 template <typename T>
90 [[nodiscard]] strided_view<T>
91 getAttribute(const SDL_GPUVertexAttribute &attr) {
92 const Uint32 stride = layout.vertexSize();
93 auto ptr = m_vertexData.data() + attr.offset;
94 return strided_view(reinterpret_cast<T *>(ptr), m_numVertices, stride);
95 }
96
97 template <typename T>
98 [[nodiscard]] strided_view<const T>
99 getAttribute(const SDL_GPUVertexAttribute &attr) const {
100 const Uint32 stride = layout.vertexSize();
101 auto ptr = m_vertexData.data() + attr.offset;
102 return strided_view(reinterpret_cast<const T *>(ptr), m_numVertices,
103 stride);
104 }
105
106 template <typename T>
108 if (auto attr = layout.getAttribute(loc)) {
109 return this->getAttribute<T>(*attr);
110 }
111 terminate_with_message("Vertex attribute {:d} not found.", Uint32(loc));
112 }
113
114 template <typename T>
116 if (auto attr = layout.getAttribute(loc)) {
117 return this->getAttribute<T>(*attr);
118 }
119 terminate_with_message("Vertex attribute {:d} not found.", Uint32(loc));
120 }
121
122 std::span<const char> vertexData() const { return m_vertexData; }
123};
124
125template <IsVertexType VertexT>
126MeshData::MeshData(SDL_GPUPrimitiveType primitiveType,
127 std::vector<VertexT> vertexData,
128 std::vector<IndexType> indexData)
129 : MeshData(primitiveType, meshLayoutFor<VertexT>(),
130 std::vector<char>{reinterpret_cast<char *>(vertexData.data()),
131 reinterpret_cast<char *>(vertexData.data() +
132 vertexData.size())},
133 std::move(indexData)) {}
134
140[[nodiscard]] Mesh createMesh(const Device &device, const MeshData &meshData,
141 bool upload = false);
142
146[[nodiscard]] Mesh createMesh(const Device &device, const MeshData &meshData,
147 SDL_GPUBuffer *vertexBuffer,
148 SDL_GPUBuffer *indexBuffer);
149
156[[nodiscard]] Mesh createMeshFromBatch(const Device &device,
157 std::span<const MeshData> meshDatas,
158 bool upload);
159
163void uploadMeshToDevice(const Device &device, const MeshView &meshView,
164 const MeshData &meshData);
165
167void uploadMeshToDevice(const Device &device, const Mesh &mesh,
168 const MeshData &meshData);
169
170inline void extractMaterials(std::span<const MeshData> meshDatas,
171 std::vector<PbrMaterial> &out) {
172 for (size_t i = 0; i < meshDatas.size(); i++) {
173 out.push_back(meshDatas[i].material);
174 }
175}
176
177[[nodiscard]] inline std::vector<PbrMaterial>
178extractMaterials(std::span<const MeshData> meshDatas) {
179 std::vector<PbrMaterial> out;
180 out.reserve(meshDatas.size());
181 extractMaterials(meshDatas, out);
182 return out;
183}
184
185} // namespace candlewick
A class to store type-erased vertex data and index data.
Definition MeshData.h:33
SDL_GPUPrimitiveType primitiveType
Definition MeshData.h:41
std::span< U > viewAs()
Obtain a typed view to the underlying vertex data.
Definition MeshData.h:76
Uint64 vertexBytes() const noexcept
Size of the overall vertex data, in bytes.
Definition MeshData.h:71
std::vector< IndexType > indexData
Definition MeshData.h:43
strided_view< const T > getAttribute(const SDL_GPUVertexAttribute &attr) const
Definition MeshData.h:99
std::span< const char > vertexData() const
Definition MeshData.h:122
strided_view< T > getAttribute(VertexAttrib loc)
Definition MeshData.h:107
Uint32 vertexSize() const noexcept
Size of each vertex, in bytes.
Definition MeshData.h:69
strided_view< const T > getAttribute(VertexAttrib loc) const
Definition MeshData.h:115
MeshData(SDL_GPUPrimitiveType primitiveType, const MeshLayout &layout, std::vector< char > vertexData, std::vector< IndexType > indexData={})
Uint32 IndexType
Definition MeshData.h:40
MeshLayout layout
Definition MeshData.h:42
PbrMaterial material
Definition MeshData.h:44
std::span< const U > viewAs() const
Obtain a typed view to the underlying vertex data.
Definition MeshData.h:82
MeshData(MeshData &&) noexcept=default
strided_view< T > getAttribute(const SDL_GPUVertexAttribute &attr)
Access an attribute. Use this when the underlying vertex data type is unknown.
Definition MeshData.h:91
Uint32 numVertices() const noexcept
Number of individual vertices.
Definition MeshData.h:67
static MeshData copy(const MeshData &other)
Explicit copy function, uses private copy ctor.
Definition MeshData.h:62
This class defines the layout of a mesh's vertices.
Definition MeshLayout.h:124
A view into a Mesh object.
Definition Mesh.h:22
Handle class for meshes (vertex buffers and an optional index buffer) on the GPU.
Definition Mesh.h:57
A strided view to data, allowing for type-erased data.
Definition StridedView.h:14
Definition Camera.h:8
VertexAttrib
Fixed vertex attributes.
Definition MeshLayout.h:106
Mesh createMeshFromBatch(const Device &device, std::span< const MeshData > meshDatas, bool upload)
Create a Mesh from a batch of MeshData.
Mesh createMesh(const Device &device, const MeshData &meshData, bool upload=false)
Convert MeshData to a GPU Mesh object. This creates the required vertex buffer and index buffer (if r...
void uploadMeshToDevice(const Device &device, const MeshView &meshView, const MeshData &meshData)
Upload the contents of a single, individual mesh to the GPU device.
void extractMaterials(std::span< const MeshData > meshDatas, std::vector< PbrMaterial > &out)
Definition MeshData.h:170
strided_view(T *first, size_t, size_t) -> strided_view< T >
terminate_with_message(std::string_view, Ts &&...) -> terminate_with_message< Ts... >
MeshLayout meshLayoutFor()
Shortcut for extracting layout from compile-time struct.
Definition MeshLayout.h:232
RAII wrapper for SDL_GPUDevice.
Definition Device.h:17
Definition MeshData.h:16
Derived & derived()
Definition MeshData.h:17
Uint32 numVertices() const
Definition MeshData.h:20
Uint32 numIndices() const
Definition MeshData.h:22
bool isIndexed() const
Definition MeshData.h:25
const Derived & derived() const
Definition MeshData.h:18
Tag type for non-initializing constructors (for e.g. RAII classes)
Definition Tags.h:6
PBR material for metallic-roughness workflow.
Definition MaterialUniform.h:8