SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
MeshBatch.hpp
Go to the documentation of this file.
1#ifndef _MESHBATCH_HPP_
2#define _MESHBATCH_HPP_
3
4#include <Core/OSDef.hpp>
7#include <Memory/RefPtr.hpp>
8#include <cstddef>
9#include <cstdint>
10
11namespace Sleak {
12
13 class Material;
14
15 namespace RenderEngine {
16 class BufferBase;
17 }
18
19 /// Lightweight handle for GPU mesh buffers created outside the
20 /// GameObject/Component system, for bulk draw submission with
21 /// minimal per-object overhead (no per-draw component work).
22 /// @ingroup rendering
23 struct ENGINE_API MeshHandle {
26 uint32_t indexCount = 0;
27 /// Registered custom vertex layout of this mesh; 0 means the engine default Vertex.
28 uint32_t vertexFormat = 0;
29
30 /// Special members defined out-of-line in MeshBatch.cpp so
31 /// RefPtr<BufferBase>::release() sees a complete BufferBase type;
32 /// a forward declaration alone would skip ~BufferBase() and leak the GPU buffer.
37 MeshHandle& operator=(const MeshHandle&);
38 MeshHandle& operator=(MeshHandle&&) noexcept;
39
40 bool IsValid() const {
41 return vertexBuffer.IsValid() && indexBuffer.IsValid() && indexCount > 0;
42 }
43 };
44
45 /// GPU mesh handle pool for bulk static geometry. Draw through BeginBatch/Draw/EndBatch.
46 ///
47 /// Use this when you have far more geometry than you want GameObjects
48 /// for: terrain chunks, voxel columns, instanced scatter, anything
49 /// where per-object component overhead would dominate. CreateMesh()
50 /// uploads vertex and index data and hands back a MeshHandle you store
51 /// yourself; MeshBatch does not track it for you.
52 ///
53 /// The two CreateMesh() overloads cover the two vertex paths. The
54 /// VertexGroup overload uses the engine's built-in vertex layout. The
55 /// raw-bytes overload takes a VertexFormatHandle from
56 /// VertexFormatRegistry::Register, and the backend binds the pipeline
57 /// that matches that handle.
58 ///
59 /// Drawing is a three-step batch: BeginBatch() binds the material and
60 /// an identity transform once, each Draw() issues one indexed draw
61 /// call, and EndBatch() closes the batch. Passing `castsShadow = false`
62 /// keeps distant geometry out of the shadow pass.
63 ///
64 /// Every entry point touches renderer state, so call them from the
65 /// thread that drives the frame, and call Shutdown() before the
66 /// renderer is torn down.
67 ///
68 /// @code{.cpp}
69 /// // Once at startup, describe and register the vertex layout
70 /// Sleak::VertexLayoutDesc desc;
71 /// desc.stride = sizeof(MyVertex);
72 /// desc.attributes = {
73 /// {0, Sleak::VertexAttribFormat::Float3, offsetof(MyVertex, pos)},
74 /// {1, Sleak::VertexAttribFormat::Float3, offsetof(MyVertex, normal)},
75 /// };
76 /// desc.shaderStem = "my_forward";
77 /// Sleak::VertexFormatHandle fmt =
78 /// Sleak::VertexFormatRegistry::Register(desc);
79 ///
80 /// // Per chunk, build GPU buffers
81 /// Sleak::MeshHandle mesh = Sleak::MeshBatch::CreateMesh(
82 /// fmt, vertices.data(), vertices.size() * sizeof(MyVertex),
83 /// indices.data(), indices.size());
84 ///
85 /// // Every frame, submit the visible ones
86 /// Sleak::MeshBatch::BeginBatch(material);
87 /// for (const auto& chunk : visibleChunks) {
88 /// if (chunk.mesh.IsValid()) Sleak::MeshBatch::Draw(chunk.mesh);
89 /// }
90 /// Sleak::MeshBatch::EndBatch();
91 /// @endcode
92 ///
93 /// @see MeshHandle, VertexLayoutDesc, VertexFormatRegistry, Material,
94 /// MeshComponent
95 /// @ingroup rendering
96 class ENGINE_API MeshBatch {
97 public:
98 /// Create GPU vertex+index buffers from CPU mesh data.
99 static MeshHandle CreateMesh(VertexGroup& vertices, IndexGroup& indices);
100
101 /// Create GPU buffers from raw vertex bytes laid out per a registered
102 /// custom vertex format. The handle keys the pipeline the backend binds.
104 const void* vertexData,
105 size_t vertexBytes,
106 const uint32_t* indices,
107 size_t indexCount);
108
109 /// Begin a batch: binds the material and an identity-transform
110 /// constant buffer once. All subsequent Draw() calls share them.
111 static void BeginBatch(Material* material);
112
113 /// Submit one indexed draw call (vertex + index buffer bind + DrawIndexed).
114 /// castsShadow=false makes the draw skip the shadow pass (distant geometry).
115 static void Draw(const MeshHandle& mesh, bool castsShadow = true);
116
117 /// End the batch (currently a no-op, reserved for future use).
118 static void EndBatch();
119
120 /// Release static resources before renderer cleanup.
121 static void Shutdown();
122 };
123
124}
125
126#endif
static void Shutdown()
Release static resources before renderer cleanup.
static MeshHandle CreateMesh(VertexGroup &vertices, IndexGroup &indices)
Create GPU vertex+index buffers from CPU mesh data.
Definition MeshBatch.cpp:22
static void EndBatch()
End the batch (currently a no-op, reserved for future use).
static void BeginBatch(Material *material)
Binds the batch material and (re)uploads the shared identity-world transform buffer once per batch.
Definition MeshBatch.cpp:68
static void Draw(const MeshHandle &mesh, bool castsShadow=true)
Submits an indexed draw for a mesh already created via CreateMesh.
Definition MeshBatch.cpp:94
Backend-agnostic GPU buffer: vertex, index, constant, or resource view target.
Backend-facing rendering layer shared by the four graphics backends.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10
uint32_t VertexFormatHandle
List< IndexType > IndexGroup
Definition MeshData.hpp:12
uint32_t vertexFormat
Registered custom vertex layout of this mesh; 0 means the engine default Vertex.
Definition MeshBatch.hpp:28
uint32_t indexCount
Definition MeshBatch.hpp:26
RefPtr< RenderEngine::BufferBase > vertexBuffer
Definition MeshBatch.hpp:24
MeshHandle(const MeshHandle &)
MeshHandle(MeshHandle &&) noexcept
RefPtr< RenderEngine::BufferBase > indexBuffer
Definition MeshBatch.hpp:25
bool IsValid() const
Definition MeshBatch.hpp:40