MXVK Vulkan Framework 0.24.0
C++20 Vulkan rendering framework for practical 2D and 3D application development with SDL3.
Loading...
Searching...
No Matches
mxvk_point_sprite_batch.hpp
Go to the documentation of this file.
1/**
2 * @file mxvk_point_sprite_batch.hpp
3 * @brief Reusable point-sprite renderer for particle and starfield effects.
4 */
5#pragma once
6
9
10#include <volk/volk.h>
11
12#include <glm/glm.hpp>
13
14#include <string>
15#include <vector>
16
17namespace mxvk {
18
19 /**
20 * @brief Forward declaration of the MXVK window wrapper.
21 */
22 class VK_Window;
23
24 /**
25 * @brief Vertex layout consumed by VK_PointSpriteBatch.
26 *
27 * The vertex shader receives world or clip-space effect coordinates at
28 * location 0, point size at location 1, and tint color at location 2.
29 */
31 /** @brief Vertex position passed to shader location 0. */
32 float position[3]{};
33 /** @brief Rasterized point size in pixels, passed to shader location 1. */
34 float size = 0.0f;
35 /** @brief RGBA tint color passed to shader location 2. */
36 float color[4]{};
37 };
38
39 /**
40 * @class VK_PointSpriteBatch
41 * @brief Reusable Vulkan point-list renderer for textured particle effects.
42 *
43 * VK_PointSpriteBatch owns a host-visible vertex buffer, a sampled point
44 * texture, per-swapchain MVP uniform buffers, descriptors, and a point-list
45 * graphics pipeline using MXVK's dynamic rendering path. It is intended for
46 * starfields, sparks, dust, and similar effects where each vertex becomes
47 * one shader-expanded point sprite via gl_PointSize/gl_PointCoord.
48 *
49 * The caller owns simulation and fills PointSpriteVertex data each frame via
50 * upload_vertices(). The batch must be loaded only after VK_Window has created
51 * deferred render resources, usually from onRecordCustomRendering().
52 */
54 public:
55 /**
56 * @brief Construct an empty point-sprite batch.
57 */
59
60 /**
61 * @brief Destroy all owned Vulkan resources.
62 */
64
69
70 /**
71 * @brief Create texture, vertex buffer, descriptors, and point-list pipeline.
72 * @param window Active MXVK window with ready swapchain/render resources.
73 * @param texture_path PNG texture sampled by the fragment shader.
74 * @param vertex_shader_path SPIR-V vertex shader path.
75 * @param fragment_shader_path SPIR-V fragment shader path.
76 * @param max_vertices Maximum number of point vertices the batch can draw.
77 * @throws mxvk::Exception on invalid input or Vulkan resource failure.
78 */
79 void load(VK_Window *window,
80 const std::string &texture_path,
81 const std::string &vertex_shader_path,
82 const std::string &fragment_shader_path,
83 size_t max_vertices);
84
85 /**
86 * @brief Recreate swapchain-dependent resources after a window resize.
87 * @param window Active MXVK window with recreated swapchain resources.
88 */
89 void resize(VK_Window *window);
90
91 /**
92 * @brief Destroy all owned resources and reset the batch to an unloaded state.
93 */
94 void cleanup();
95
96 /**
97 * @brief Copy point vertices into the persistent mapped vertex buffer.
98 * @param vertices Pointer to @p count vertices. May be nullptr only when count is zero.
99 * @param count Number of vertices to upload and draw.
100 * @throws mxvk::Exception if @p count exceeds capacity().
101 */
102 void upload_vertices(const PointSpriteVertex *vertices, size_t count);
103
104 /**
105 * @brief Update the MVP uniform for one swapchain image.
106 * @param image_index Current swapchain image index.
107 * @param mvp Model-view-projection transform consumed by the vertex shader.
108 */
109 void update_mvp(uint32_t image_index, const glm::mat4 &mvp);
110
111 /**
112 * @brief Record point-sprite draw commands into an active rendering scope.
113 * @param cmd Command buffer in recording state inside MXVK dynamic rendering.
114 * @param image_index Current swapchain image index.
115 */
116 void render(VkCommandBuffer cmd, uint32_t image_index);
117
118 /**
119 * @brief Select additive or alpha-over color blending.
120 * @param enabled @c true for additive blending, @c false for alpha blending.
121 */
122 void set_additive_blending(bool enabled);
123
124 /**
125 * @brief Enable or disable depth testing in the point-sprite pipeline.
126 * @param enabled @c true to test against the depth attachment.
127 */
128 void set_depth_test_enabled(bool enabled);
129
130 /**
131 * @brief Enable or disable depth writes in the point-sprite pipeline.
132 * @param enabled @c true to write point depth values.
133 */
134 void set_depth_write_enabled(bool enabled);
135
136 /** @return @c true when load() has completed successfully. */
137 [[nodiscard]] bool loaded() const { return batch_loaded; }
138 /** @return Maximum number of vertices accepted by upload_vertices(). */
139 [[nodiscard]] size_t capacity() const { return max_vertices; }
140 /** @return Number of vertices that will be drawn by render(). */
141 [[nodiscard]] size_t vertex_count() const { return active_vertices; }
142
143 private:
144 /** @brief Per-frame uniform payload. */
145 struct UniformBufferObject {
146 /** @brief Model-view-projection transform. */
147 alignas(16) glm::mat4 mvp{1.0f};
148 };
149
150 /** @brief Allocate and persistently map the vertex buffer. */
151 void create_vertex_buffer();
152 /** @brief Destroy the persistent vertex buffer. */
153 void destroy_vertex_buffer();
154 /** @brief Create resources tied to current swapchain image count/formats. */
155 void create_swapchain_resources();
156 /** @brief Destroy resources tied to current swapchain image count/formats. */
157 void cleanup_swapchain_resources();
158 /** @brief Create texture and MVP descriptor set layout. */
159 void create_descriptor_set_layout();
160 /** @brief Allocate one mapped MVP uniform buffer per swapchain image. */
161 void create_uniform_buffers();
162 /** @brief Destroy all mapped MVP uniform buffers. */
163 void destroy_uniform_buffers();
164 /** @brief Create descriptor pool for all swapchain images. */
165 void create_descriptor_pool();
166 /** @brief Allocate and update descriptor sets for texture and MVP UBOs. */
167 void create_descriptor_sets();
168 /** @brief Create the dynamic-rendering point-list graphics pipeline. */
169 void create_pipeline();
170 /** @brief Destroy the graphics pipeline and layout. */
171 void destroy_pipeline();
172 /** @brief Read a SPIR-V shader file into memory. */
173 [[nodiscard]] std::vector<char> read_shader_file(const std::string &path) const;
174 /** @brief Vulkan handles required for allocation, upload, and draw resource creation. */
175 VulkanContext context{};
176 /** @brief Persistent pipeline cache borrowed from VK_Window. */
177 VkPipelineCache pipeline_cache = VK_NULL_HANDLE;
178 /** @brief Current swapchain color attachment format. */
179 VkFormat color_attachment_format = VK_FORMAT_UNDEFINED;
180 /** @brief Current depth attachment format. */
181 VkFormat depth_attachment_format = VK_FORMAT_UNDEFINED;
182 /** @brief Current swapchain image count. */
183 size_t image_count = 0;
184
185 /** @brief Source texture path used during load(). */
186 std::string texture_path{};
187 /** @brief Vertex shader SPIR-V path. */
188 std::string vertex_shader_path{};
189 /** @brief Fragment shader SPIR-V path. */
190 std::string fragment_shader_path{};
191
192 /** @brief Sampled point texture. */
193 TextureResource texture{};
194 /** @brief Host-visible vertex buffer storing PointSpriteVertex data. */
195 BufferResource vertex_buffer{};
196 /** @brief Maximum supported vertex count. */
197 size_t max_vertices = 0;
198 /** @brief Currently uploaded vertex count. */
199 size_t active_vertices = 0;
200
201 /** @brief Descriptor layout for sampled texture and MVP UBO. */
202 VkDescriptorSetLayout descriptor_set_layout = VK_NULL_HANDLE;
203 /** @brief Descriptor pool for all per-image descriptor sets. */
204 VkDescriptorPool descriptor_pool = VK_NULL_HANDLE;
205 /** @brief One descriptor set per swapchain image. */
206 std::vector<VkDescriptorSet> descriptor_sets{};
207 /** @brief One mapped MVP uniform buffer per swapchain image. */
208 std::vector<BufferResource> uniform_buffers{};
209
210 /** @brief Graphics pipeline layout. */
211 VkPipelineLayout pipeline_layout = VK_NULL_HANDLE;
212 /** @brief Point-list graphics pipeline. */
213 VkPipeline pipeline = VK_NULL_HANDLE;
214 /** @brief True for additive color blending, false for alpha-over blending. */
215 bool additive_blending = true;
216 /** @brief Whether the pipeline enables depth testing. */
217 bool depth_test_enabled = false;
218 /** @brief Whether the pipeline writes depth values. */
219 bool depth_write_enabled = false;
220 /** @brief True after successful load(). */
221 bool batch_loaded = false;
222 };
223
224} // namespace mxvk
~VK_PointSpriteBatch()
Destroy all owned Vulkan resources.
void load(VK_Window *window, const std::string &texture_path, const std::string &vertex_shader_path, const std::string &fragment_shader_path, size_t max_vertices)
Create texture, vertex buffer, descriptors, and point-list pipeline.
void set_depth_write_enabled(bool enabled)
Enable or disable depth writes in the point-sprite pipeline.
void render(VkCommandBuffer cmd, uint32_t image_index)
Record point-sprite draw commands into an active rendering scope.
void update_mvp(uint32_t image_index, const glm::mat4 &mvp)
Update the MVP uniform for one swapchain image.
void resize(VK_Window *window)
Recreate swapchain-dependent resources after a window resize.
void cleanup()
Destroy all owned resources and reset the batch to an unloaded state.
void set_additive_blending(bool enabled)
Select additive or alpha-over color blending.
void upload_vertices(const PointSpriteVertex *vertices, size_t count)
Copy point vertices into the persistent mapped vertex buffer.
VK_PointSpriteBatch(VK_PointSpriteBatch &&)=delete
void set_depth_test_enabled(bool enabled)
Enable or disable depth testing in the point-sprite pipeline.
VK_PointSpriteBatch & operator=(VK_PointSpriteBatch &&)=delete
VK_PointSpriteBatch(const VK_PointSpriteBatch &)=delete
VK_PointSpriteBatch & operator=(const VK_PointSpriteBatch &)=delete
VK_PointSpriteBatch()=default
Construct an empty point-sprite batch.
Main Vulkan window wrapper for MXVK.
Definition mxvk.hpp:37
Minimal Vulkan handles shared across MXVK helpers.
Reusable Vulkan buffer, image, upload, and one-shot command helpers.
Utilities for loading and saving PNG images.
Definition mxvk.hpp:30
Vertex layout consumed by VK_PointSpriteBatch.
float color[4]
RGBA tint color passed to shader location 2.
float size
Rasterized point size in pixels, passed to shader location 1.
float position[3]
Vertex position passed to shader location 0.
Default transform UBO payload for model shaders.