candlewick 0.10.1-7-ge7f2
A tiny cross-platform renderer based on SDL3
Loading...
Searching...
No Matches
MeshLayout.h
Go to the documentation of this file.
1#pragma once
2
3#include <SDL3/SDL_gpu.h>
4#include "math_types.h"
5#include <vector>
6
7inline bool operator==(const SDL_GPUVertexBufferDescription &lhs,
8 const SDL_GPUVertexBufferDescription &rhs) {
9#define _c(field) lhs.field == rhs.field
10 return _c(slot) && _c(pitch) && _c(input_rate) && _c(instance_step_rate);
11#undef _c
12}
13
14inline bool operator==(const SDL_GPUVertexAttribute &lhs,
15 const SDL_GPUVertexAttribute &rhs) {
16#define _c(field) lhs.field == rhs.field
17 return _c(location) && _c(buffer_slot) && _c(format) && _c(offset);
18#undef _c
19}
20
21inline std::strong_ordering
22operator<=>(const SDL_GPUVertexAttribute &lhs,
23 const SDL_GPUVertexAttribute &rhs) noexcept {
24 if (auto cmp = lhs.location <=> rhs.location; cmp != 0)
25 return cmp;
26 if (auto cmp = lhs.buffer_slot <=> rhs.buffer_slot; cmp != 0)
27 return cmp;
28 if (auto cmp = lhs.format <=> rhs.format; cmp != 0)
29 return cmp;
30 return lhs.offset <=> rhs.offset;
31}
32
33inline std::strong_ordering
34operator<=>(const SDL_GPUVertexBufferDescription &lhs,
35 const SDL_GPUVertexBufferDescription &rhs) noexcept {
36 if (auto cmp = lhs.slot <=> rhs.slot; cmp != 0)
37 return cmp;
38 if (auto cmp = lhs.pitch <=> rhs.pitch; cmp != 0)
39 return cmp;
40 if (auto cmp = lhs.input_rate <=> rhs.input_rate; cmp != 0)
41 return cmp;
42 return lhs.instance_step_rate <=> rhs.instance_step_rate;
43}
44
45namespace candlewick {
46
47constexpr Uint64 vertexElementSize(SDL_GPUVertexElementFormat format) {
48 switch (format) {
49 case SDL_GPU_VERTEXELEMENTFORMAT_INVALID:
50 return 0u;
51 case SDL_GPU_VERTEXELEMENTFORMAT_INT:
52 return sizeof(Sint32);
53 case SDL_GPU_VERTEXELEMENTFORMAT_INT2:
54 return sizeof(Sint32[2]);
55 case SDL_GPU_VERTEXELEMENTFORMAT_INT3:
56 return sizeof(Sint32[3]);
57 case SDL_GPU_VERTEXELEMENTFORMAT_INT4:
58 return sizeof(Sint32[4]);
59 case SDL_GPU_VERTEXELEMENTFORMAT_UINT:
60 return sizeof(Uint32);
61 case SDL_GPU_VERTEXELEMENTFORMAT_UINT2:
62 return sizeof(Uint32[2]);
63 case SDL_GPU_VERTEXELEMENTFORMAT_UINT3:
64 return sizeof(Uint32[3]);
65 case SDL_GPU_VERTEXELEMENTFORMAT_UINT4:
66 return sizeof(Uint32[4]);
67 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT:
68 return sizeof(float);
69 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2:
70 return sizeof(float[2]);
71 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3:
72 return sizeof(float[3]);
73 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4:
74 return sizeof(float[4]);
75 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE2:
76 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2:
77 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE2_NORM:
78 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2_NORM:
79 return 16u;
80 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE4:
81 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4:
82 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE4_NORM:
83 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM:
84 return 32u;
85 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT2:
86 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT2:
87 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT2_NORM:
88 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT2_NORM:
89 case SDL_GPU_VERTEXELEMENTFORMAT_HALF2:
90 return 32ul;
91 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT4:
92 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT4:
93 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT4_NORM:
94 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT4_NORM:
95 case SDL_GPU_VERTEXELEMENTFORMAT_HALF4:
96 return 64ul;
97 default:
98 return 0l;
99 }
100}
101
116
125public:
126 MeshLayout() : m_bufferDescs{}, m_attrs{}, m_totalVertexSize(0) {}
127
137 MeshLayout &addBinding(Uint32 slot, Uint32 pitch) {
138 m_bufferDescs.emplace_back(slot, pitch, SDL_GPU_VERTEXINPUTRATE_VERTEX, 0u);
139 return *this;
140 }
141
149 constexpr MeshLayout &addAttribute(VertexAttrib loc, Uint32 binding,
150 SDL_GPUVertexElementFormat format,
151 Uint32 offset) {
152 const Uint16 _loc = static_cast<Uint16>(loc);
153 m_attrs.emplace_back(_loc, binding, format, offset);
154 const Uint32 attrSize =
155 math::roundUpTo16(Uint32(vertexElementSize(format)));
156 m_totalVertexSize = std::max(m_totalVertexSize, offset + attrSize);
157 return *this;
158 }
159
160 const SDL_GPUVertexAttribute *getAttribute(VertexAttrib loc) const noexcept {
161 for (Uint32 i = 0; i < numAttributes(); i++) {
162 if (m_attrs[i].location == static_cast<Uint16>(loc)) {
163 return &m_attrs[i];
164 }
165 }
166 return nullptr;
167 }
168
173 SDL_GPUVertexInputState toVertexInputState() const noexcept {
174 return {
175 m_bufferDescs.data(),
176 numBuffers(),
177 m_attrs.data(),
179 };
180 }
181
182 operator SDL_GPUVertexInputState() const noexcept {
183 return toVertexInputState();
184 }
185
186 std::strong_ordering operator<=>(const MeshLayout &other) const noexcept;
187
188 bool operator==(const MeshLayout &other) const noexcept = default;
189
191 Uint32 numBuffers() const { return Uint32(m_bufferDescs.size()); }
193 Uint32 numAttributes() const { return Uint32(m_attrs.size()); }
196 Uint32 vertexSize() const { return m_totalVertexSize; }
198 Uint32 indexSize() const { return sizeof(Uint32); }
199
200 std::vector<SDL_GPUVertexBufferDescription> m_bufferDescs;
201 std::vector<SDL_GPUVertexAttribute> m_attrs;
202
203private:
204 Uint32 m_totalVertexSize;
205};
206
207inline std::strong_ordering
208MeshLayout::operator<=>(const MeshLayout &other) const noexcept {
209 if (auto cmp = numBuffers() <=> other.numBuffers(); cmp != 0)
210 return cmp;
211 if (auto cmp = numAttributes() <=> other.numAttributes(); cmp != 0)
212 return cmp;
213 if (auto cmp = m_bufferDescs <=> other.m_bufferDescs; cmp != 0)
214 return cmp;
215 return m_attrs <=> other.m_attrs;
216}
217
220inline bool validateMeshLayout(const MeshLayout &layout) {
221 return (layout.numBuffers() > 0) && (layout.numAttributes() > 0);
222}
223
226template <typename V>
227concept IsVertexType = std::is_standard_layout_v<V> && (alignof(V) == 16);
228
229template <IsVertexType V> struct VertexTraits;
230
232template <IsVertexType V> MeshLayout meshLayoutFor() {
234}
235
236} // namespace candlewick
#define _c(field)
std::strong_ordering operator<=>(const SDL_GPUVertexAttribute &lhs, const SDL_GPUVertexAttribute &rhs) noexcept
Definition MeshLayout.h:22
bool operator==(const SDL_GPUVertexBufferDescription &lhs, const SDL_GPUVertexBufferDescription &rhs)
Definition MeshLayout.h:7
This class defines the layout of a mesh's vertices.
Definition MeshLayout.h:124
bool operator==(const MeshLayout &other) const noexcept=default
SDL_GPUVertexInputState toVertexInputState() const noexcept
Cast to the SDL_GPU vertex input state struct, used to create pipelines.
Definition MeshLayout.h:173
std::vector< SDL_GPUVertexBufferDescription > m_bufferDescs
Definition MeshLayout.h:200
Uint32 indexSize() const
Size of mesh indices (in bytes).
Definition MeshLayout.h:198
constexpr MeshLayout & addAttribute(VertexAttrib loc, Uint32 binding, SDL_GPUVertexElementFormat format, Uint32 offset)
Add a vertex attribute.
Definition MeshLayout.h:149
Uint32 vertexSize() const
Total size of a vertex (in bytes).
Definition MeshLayout.h:196
const SDL_GPUVertexAttribute * getAttribute(VertexAttrib loc) const noexcept
Definition MeshLayout.h:160
std::vector< SDL_GPUVertexAttribute > m_attrs
Definition MeshLayout.h:201
MeshLayout & addBinding(Uint32 slot, Uint32 pitch)
Add a binding (i.e. a vertex binding) for the mesh.
Definition MeshLayout.h:137
MeshLayout()
Definition MeshLayout.h:126
Uint32 numBuffers() const
Number of vertex buffers.
Definition MeshLayout.h:191
Uint32 numAttributes() const
Number of vertex attributes.
Definition MeshLayout.h:193
std::strong_ordering operator<=>(const MeshLayout &other) const noexcept
Definition MeshLayout.h:208
Basic concept checking if type V has the correct layout and alignment requirements to be a vertex ele...
Definition MeshLayout.h:227
constexpr Uint32 roundUpTo16(Uint32 value)
Definition math_types.h:160
Definition Camera.h:8
VertexAttrib
Fixed vertex attributes.
Definition MeshLayout.h:106
@ Color1
Definition MeshLayout.h:112
@ TexCoord0
Definition MeshLayout.h:113
@ Position
Definition MeshLayout.h:107
@ Tangent
Definition MeshLayout.h:109
@ Normal
Definition MeshLayout.h:108
@ Color0
Definition MeshLayout.h:111
@ TexCoord1
Definition MeshLayout.h:114
@ Bitangent
Definition MeshLayout.h:110
constexpr Uint64 vertexElementSize(SDL_GPUVertexElementFormat format)
Definition MeshLayout.h:47
bool validateMeshLayout(const MeshLayout &layout)
Validation function. Checks if a MeshLayout produces invalid data for a Mesh.
Definition MeshLayout.h:220
MeshLayout meshLayoutFor()
Shortcut for extracting layout from compile-time struct.
Definition MeshLayout.h:232
Definition MeshLayout.h:229