candlewick 0.1.0
A renderer
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
21namespace candlewick {
22
23constexpr Uint64 vertexElementSize(SDL_GPUVertexElementFormat format) {
24 switch (format) {
25 case SDL_GPU_VERTEXELEMENTFORMAT_INVALID:
26 return 0u;
27 case SDL_GPU_VERTEXELEMENTFORMAT_INT:
28 return sizeof(Sint32);
29 case SDL_GPU_VERTEXELEMENTFORMAT_INT2:
30 return sizeof(Sint32[2]);
31 case SDL_GPU_VERTEXELEMENTFORMAT_INT3:
32 return sizeof(Sint32[3]);
33 case SDL_GPU_VERTEXELEMENTFORMAT_INT4:
34 return sizeof(Sint32[4]);
35 case SDL_GPU_VERTEXELEMENTFORMAT_UINT:
36 return sizeof(Uint32);
37 case SDL_GPU_VERTEXELEMENTFORMAT_UINT2:
38 return sizeof(Uint32[2]);
39 case SDL_GPU_VERTEXELEMENTFORMAT_UINT3:
40 return sizeof(Uint32[3]);
41 case SDL_GPU_VERTEXELEMENTFORMAT_UINT4:
42 return sizeof(Uint32[4]);
43 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT:
44 return sizeof(float);
45 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT2:
46 return sizeof(float[2]);
47 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT3:
48 return sizeof(float[3]);
49 case SDL_GPU_VERTEXELEMENTFORMAT_FLOAT4:
50 return sizeof(float[4]);
51 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE2:
52 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2:
53 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE2_NORM:
54 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE2_NORM:
55 return 16u;
56 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE4:
57 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4:
58 case SDL_GPU_VERTEXELEMENTFORMAT_BYTE4_NORM:
59 case SDL_GPU_VERTEXELEMENTFORMAT_UBYTE4_NORM:
60 return 32u;
61 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT2:
62 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT2:
63 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT2_NORM:
64 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT2_NORM:
65 case SDL_GPU_VERTEXELEMENTFORMAT_HALF2:
66 return 32ul;
67 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT4:
68 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT4:
69 case SDL_GPU_VERTEXELEMENTFORMAT_SHORT4_NORM:
70 case SDL_GPU_VERTEXELEMENTFORMAT_USHORT4_NORM:
71 case SDL_GPU_VERTEXELEMENTFORMAT_HALF4:
72 return 64ul;
73 }
74}
75
90
99public:
100 MeshLayout() : m_bufferDescs{}, m_attrs{}, m_totalVertexSize(0) {}
101
111 MeshLayout &addBinding(Uint32 slot, Uint32 pitch) {
112 m_bufferDescs.emplace_back(slot, pitch, SDL_GPU_VERTEXINPUTRATE_VERTEX, 0u);
113 return *this;
114 }
115
123 constexpr MeshLayout &addAttribute(VertexAttrib loc, Uint32 binding,
124 SDL_GPUVertexElementFormat format,
125 Uint32 offset) {
126 const Uint16 _loc = static_cast<Uint16>(loc);
127 m_attrs.emplace_back(_loc, binding, format, offset);
128 const Uint32 attrSize =
129 math::roundUpTo16(Uint32(vertexElementSize(format)));
130 m_totalVertexSize = std::max(m_totalVertexSize, offset + attrSize);
131 return *this;
132 }
133
134 const SDL_GPUVertexAttribute *getAttribute(VertexAttrib loc) const noexcept {
135 for (Uint32 i = 0; i < numAttributes(); i++) {
136 if (m_attrs[i].location == static_cast<Uint16>(loc)) {
137 return &m_attrs[i];
138 }
139 }
140 return nullptr;
141 }
142
147 SDL_GPUVertexInputState toVertexInputState() const noexcept {
148 return {
149 m_bufferDescs.data(),
150 numBuffers(),
151 m_attrs.data(),
153 };
154 }
155
156 operator SDL_GPUVertexInputState() const noexcept {
157 return toVertexInputState();
158 }
159
160 bool operator==(const MeshLayout &other) const noexcept {
161 if (numBuffers() != other.numBuffers() &&
162 numAttributes() != other.numAttributes())
163 return false;
164
165 // for (Uint16 i = 0; i < numBuffers(); i++) {
166 // if (m_bufferDescs[i] != other.m_bufferDescs[i])
167 // return false;
168 // }
169 if (m_bufferDescs != other.m_bufferDescs)
170 return false;
171 // for (Uint16 i = 0; i < numAttributes(); i++) {
172 // if (m_attrs[i] != other.m_attrs[i])
173 // return false;
174 // }
175 if (m_attrs != other.m_attrs)
176 return false;
177 return true;
178 }
179
181 Uint32 numBuffers() const { return Uint32(m_bufferDescs.size()); }
183 Uint32 numAttributes() const { return Uint32(m_attrs.size()); }
186 Uint32 vertexSize() const { return m_totalVertexSize; }
188 Uint32 indexSize() const { return sizeof(Uint32); }
189
190 std::vector<SDL_GPUVertexBufferDescription> m_bufferDescs;
191 std::vector<SDL_GPUVertexAttribute> m_attrs;
192
193private:
194 Uint32 m_totalVertexSize;
195};
196
199inline bool validateMeshLayout(const MeshLayout &layout) {
200 return (layout.numBuffers() > 0) && (layout.numAttributes() > 0);
201}
202
205template <typename V>
206concept IsVertexType = std::is_standard_layout_v<V> && (alignof(V) == 16);
207
208template <IsVertexType V> struct VertexTraits;
209
211template <IsVertexType V> MeshLayout meshLayoutFor() {
213}
214
215} // namespace candlewick
#define _c(field)
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:98
SDL_GPUVertexInputState toVertexInputState() const noexcept
Cast to the SDL_GPU vertex input state struct, used to create pipelines.
Definition MeshLayout.h:147
bool operator==(const MeshLayout &other) const noexcept
Definition MeshLayout.h:160
std::vector< SDL_GPUVertexBufferDescription > m_bufferDescs
Definition MeshLayout.h:190
Uint32 indexSize() const
Size of mesh indices (in bytes).
Definition MeshLayout.h:188
constexpr MeshLayout & addAttribute(VertexAttrib loc, Uint32 binding, SDL_GPUVertexElementFormat format, Uint32 offset)
Add a vertex attribute.
Definition MeshLayout.h:123
Uint32 vertexSize() const
Total size of a vertex (in bytes).
Definition MeshLayout.h:186
const SDL_GPUVertexAttribute * getAttribute(VertexAttrib loc) const noexcept
Definition MeshLayout.h:134
std::vector< SDL_GPUVertexAttribute > m_attrs
Definition MeshLayout.h:191
MeshLayout & addBinding(Uint32 slot, Uint32 pitch)
Add a binding (i.e. a vertex binding) for the mesh.
Definition MeshLayout.h:111
MeshLayout()
Definition MeshLayout.h:100
Uint32 numBuffers() const
Number of vertex buffers.
Definition MeshLayout.h:181
Uint32 numAttributes() const
Number of vertex attributes.
Definition MeshLayout.h:183
Basic concept checking if type V has the correct layout and alignment requirements to be a vertex ele...
Definition MeshLayout.h:206
constexpr Uint32 roundUpTo16(Uint32 value)
Definition math_types.h:160
Definition Camera.h:8
VertexAttrib
Fixed vertex attributes.
Definition MeshLayout.h:80
@ Color1
Definition MeshLayout.h:86
@ TexCoord0
Definition MeshLayout.h:87
@ Position
Definition MeshLayout.h:81
@ Tangent
Definition MeshLayout.h:83
@ Normal
Definition MeshLayout.h:82
@ Color0
Definition MeshLayout.h:85
@ TexCoord1
Definition MeshLayout.h:88
@ Bitangent
Definition MeshLayout.h:84
constexpr Uint64 vertexElementSize(SDL_GPUVertexElementFormat format)
Definition MeshLayout.h:23
bool validateMeshLayout(const MeshLayout &layout)
Validation function. Checks if a MeshLayout produces invalid data for a Mesh.
Definition MeshLayout.h:199
MeshLayout meshLayoutFor()
Shortcut for extracting layout from compile-time struct.
Definition MeshLayout.h:211
Definition MeshLayout.h:208