SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
VertexLayout.hpp
Go to the documentation of this file.
1#ifndef _VERTEXLAYOUT_HPP_
2#define _VERTEXLAYOUT_HPP_
3
4#include <Core/OSDef.hpp>
5#include <cstdint>
6#include <string>
7#include <vector>
8
9namespace Sleak {
10
11/// Data type of one vertex attribute as seen by the vertex shader.
12/// @ingroup vertexformats
13enum class VertexAttribFormat : uint8_t {
16};
17
18/// One attribute: shader location, component format, byte offset in the vertex.
19/// @ingroup vertexformats
25
26/// A complete custom vertex layout plus the shader stems that consume it.
27/// Register once at startup; the handle keys pipelines and mesh creation.
28/// Shader stems are consumed by the Vulkan backend; OpenGL instead binds
29/// the layout's attributes to its own fixed shader programs.
30///
31/// Fill one of these when your geometry does not fit the engine's built-in
32/// vertex type: packed voxel vertices, extra UV sets, per-vertex instance
33/// data, anything you want to define yourself. `stride` is the size of one
34/// vertex in bytes and each VertexAttribute gives a shader location, a
35/// component format, and a byte offset inside that vertex.
36///
37/// The four shader stems name the pipeline variants the format
38/// participates in. An empty stem skips that pass entirely, so a format
39/// with no `shadowShaderStem` casts no shadows and a format with no
40/// `gbufferShaderStem` is forward only. There is no fallback shader: if a
41/// named stem fails to load, the backend logs an error and skips that pass
42/// for this format.
43///
44/// @code{.cpp}
45/// struct VoxelVertex {
46/// float position[3];
47/// float normal[3];
48/// float uv[2];
49/// uint32_t packedLight;
50/// };
51///
52/// Sleak::VertexLayoutDesc desc;
53/// desc.stride = sizeof(VoxelVertex);
54/// desc.attributes = {
55/// {0, Sleak::VertexAttribFormat::Float3,
56/// offsetof(VoxelVertex, position)},
57/// {1, Sleak::VertexAttribFormat::Float3,
58/// offsetof(VoxelVertex, normal)},
59/// {2, Sleak::VertexAttribFormat::Float2, offsetof(VoxelVertex, uv)},
60/// {3, Sleak::VertexAttribFormat::UInt1,
61/// offsetof(VoxelVertex, packedLight)},
62/// };
63/// desc.shaderStem = "flat_shader";
64/// desc.shadowShaderStem = "shadow_depth_voxel";
65/// desc.gbufferShaderStem = "gbuffer_voxel";
66/// desc.transparentShaderStem = "water_shader";
67///
68/// Sleak::VertexFormatHandle handle =
69/// Sleak::VertexFormatRegistry::Register(desc);
70/// @endcode
71///
72/// @see VertexFormatRegistry, VertexAttribute, VertexAttribFormat, MeshBatch
73/// @ingroup vertexformats
75 uint32_t stride = 0;
76 std::vector<VertexAttribute> attributes;
77 std::string shaderStem; // forward/main variant
78 // Depth-only shadow variant; empty string skips the shadow pass.
79 std::string shadowShaderStem;
80 // Deferred geometry (GBuffer) variant; empty string is forward only.
81 std::string gbufferShaderStem;
82 // Forward transparent variant; empty string skips the transparent pass.
84};
85
86/// 0 is reserved for the engine's default vertex layout; registered
87/// formats start at 1.
88using VertexFormatHandle = uint32_t;
89
90/// Global registry of custom vertex layouts. Register returns a stable handle.
91///
92/// This is how a game teaches the renderer about its own geometry. Call
93/// Register() once per layout during startup, keep the returned
94/// VertexFormatHandle, and pass it to MeshBatch::CreateMesh(). The handle
95/// travels on the resulting MeshHandle, and the backend uses it to pick
96/// the pipeline for every pass the format participates in.
97///
98/// Handles are stable for the lifetime of the process and start at 1;
99/// handle 0 is reserved for the engine's built-in vertex layout. Register()
100/// does not validate the descriptor. A zero stride or an empty attribute
101/// list is caught later, at pipeline creation.
102///
103/// Register once and reuse the handle. Registering the same descriptor
104/// repeatedly creates a new handle and a new set of pipelines each time.
105/// Shutdown() is for application teardown only, and pointers returned by
106/// Get() stay valid until it runs.
107///
108/// @code{.cpp}
109/// // Startup: register the format your game uses
110/// class VoxelVertexFormat {
111/// public:
112/// static Sleak::VertexFormatHandle Handle() {
113/// static Sleak::VertexFormatHandle handle = Register();
114/// return handle;
115/// }
116///
117/// private:
118/// static Sleak::VertexFormatHandle Register() {
119/// Sleak::VertexLayoutDesc desc;
120/// desc.stride = sizeof(VoxelVertex);
121/// desc.attributes = MakeVoxelAttributes();
122/// desc.shaderStem = "flat_shader";
123/// return Sleak::VertexFormatRegistry::Register(desc);
124/// }
125/// };
126///
127/// // Mesh creation: key the buffers to that handle
128/// Sleak::MeshHandle mesh = Sleak::MeshBatch::CreateMesh(
129/// VoxelVertexFormat::Handle(),
130/// verts.data(), verts.size() * sizeof(VoxelVertex),
131/// indices.data(), indices.size());
132///
133/// // Teardown
134/// Sleak::VertexFormatRegistry::Shutdown();
135/// @endcode
136///
137/// @see VertexLayoutDesc, VertexFormatHandle, MeshBatch, MeshHandle
138/// @ingroup vertexformats
139class ENGINE_API VertexFormatRegistry {
140public:
141 static VertexFormatHandle Register(const VertexLayoutDesc& desc);
142
143 /// Returns nullptr for handle 0 or an unknown handle. The returned
144 /// pointer stays valid until Shutdown(), which is intended for
145 /// application teardown only.
146 static const VertexLayoutDesc* Get(VertexFormatHandle handle);
147
148 /// Clears the registry; call only during application teardown.
149 static void Shutdown();
150};
151
152} // namespace Sleak
153
154#endif
static VertexFormatHandle Register(const VertexLayoutDesc &desc)
static const VertexLayoutDesc * Get(VertexFormatHandle handle)
static void Shutdown()
Clears the registry; call only during application teardown.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10
uint32_t VertexFormatHandle
VertexAttribFormat format
std::string transparentShaderStem
std::vector< VertexAttribute > attributes