Mandrill 2025.6.0
Loading...
Searching...
No Matches
Scene.h
1#pragma once
2
3#include "Common.h"
4
5#include "AccelerationStructure.h"
6#include "Camera.h"
7#include "Descriptor.h"
8#include "Device.h"
9#include "Layout.h"
10#include "Sampler.h"
11#include "Swapchain.h"
12#include "Texture.h"
13
14namespace Mandrill
15{
16 struct Vertex {
17 alignas(16) glm::vec3 position; // Position of vertex in 3D space
18 alignas(16) glm::vec3 normal; // Normal vector of vertex
19 alignas(16) glm::vec2 texcoord; // Texture coordinates
20 alignas(16) glm::vec3 tangent; // Tangent vector for normal mapping
21 alignas(16) glm::vec3 binormal; // Binormal vector for normal mapping
22
28 bool operator==(const Vertex& other) const
29 {
30 return position == other.position && normal == other.normal && texcoord == other.texcoord &&
31 tangent == other.tangent && binormal == other.binormal;
32 }
33 };
34
35 struct Mesh {
36 std::vector<Vertex> vertices;
37 std::vector<uint32_t> indices;
38 uint32_t materialIndex{};
39
40 // Device offset are set when uploading to device
41 VkDeviceSize deviceVerticesOffset{};
42 VkDeviceSize deviceIndicesOffset{};
43 };
44
45 struct alignas(16) MaterialParams {
46 glm::vec3 diffuse;
47 float shininess;
48 glm::vec3 specular;
49 float indexOfRefraction;
50 glm::vec3 ambient;
51 float opacity;
52 glm::vec3 emission;
53 uint32_t hasTexture;
54 };
55
56 struct alignas(16) MaterialDevice {
57 MaterialParams params;
58 uint32_t diffuseTextureIndex;
59 uint32_t specularTextureIndex;
60 uint32_t ambientTextureIndex;
61 uint32_t emissionTextureIndex;
62 uint32_t normalTextureIndex;
63 };
64
65 struct Material {
66 MaterialParams params{};
67 MaterialParams* paramsDevice{}; // This is set during Scene::compile()
68 VkDeviceSize paramsOffset{}; // This is set during Scene::compile()
69
70 std::string diffuseTexturePath;
71 std::string specularTexturePath;
72 std::string ambientTexturePath;
73 std::string emissionTexturePath;
74 std::string normalTexturePath;
75
76 ptr<Descriptor> pDescriptor;
77 };
78
79 struct InstanceData {
80 uint32_t verticesOffset; // Offset into global vertex buffer
81 uint32_t indicesOffset; // Offset into global index buffer
82 };
83
84 class Scene; // Forward declare scene so Node can befriend it
85 class Pipeline;
86
90 class Node
91 {
92 public:
97 MANDRILL_API Node();
98
103 MANDRILL_API ~Node();
104
112 MANDRILL_API void render(VkCommandBuffer cmd, const ptr<Camera> pCamera, const ptr<const Scene> pScene) const;
113
119 MANDRILL_API void addMesh(uint32_t meshIndex)
120 {
121 mMeshIndices.push_back(meshIndex);
122 }
123
129 MANDRILL_API void setPipeline(ptr<Pipeline> pPipeline)
130 {
131 mpPipeline = pPipeline;
132 }
133
138 MANDRILL_API glm::mat4 getTransform() const
139 {
140 return mTransform;
141 }
142
148 MANDRILL_API void setTransform(glm::mat4 transform)
149 {
150 mTransform = transform;
151 }
152
158 MANDRILL_API void setVisible(bool visible)
159 {
160 mVisible = visible;
161 }
162
167 MANDRILL_API bool getVisible() const
168 {
169 return mVisible;
170 }
171
176 MANDRILL_API std::vector<uint32_t>& getMeshIndices()
177 {
178 return mMeshIndices;
179 }
180
181 private:
182 friend Scene;
183
184 ptr<Pipeline> mpPipeline;
185
186 std::vector<uint32_t> mMeshIndices;
187
188 glm::mat4 mTransform;
189 glm::mat4* mpTransformDevice;
190 ptr<Descriptor> pDescriptor;
191 std::vector<VkDescriptorSet> mDescriptors;
192
193 bool mVisible;
194
195 std::vector<Node*> mChildren;
196 };
197
201 class Scene : public std::enable_shared_from_this<Scene>
202 {
203 public:
204 MANDRILL_NON_COPYABLE(Scene)
205
206
237 MANDRILL_API Scene(ptr<Device> pDevice, ptr<Swapchain> pSwapchain, bool supportRayTracing = false);
238
243 MANDRILL_API ~Scene();
244
251 MANDRILL_API void render(VkCommandBuffer cmd, const ptr<Camera> pCamera) const;
252
257 MANDRILL_API ptr<Node> addNode();
258
264 MANDRILL_API uint32_t addMaterial(Material material);
265
273 MANDRILL_API uint32_t addMesh(const std::vector<Vertex> vertices, const std::vector<uint32_t> indices,
274 uint32_t materialIndex);
275
283 MANDRILL_API std::vector<uint32_t> addMeshFromFile(const std::filesystem::path& path,
284 const std::filesystem::path& materialPath = "");
285
290 MANDRILL_API void compile();
291
303 MANDRILL_API void syncToDevice();
304
312 MANDRILL_API void updateAccelerationStructure(
313 VkBuildAccelerationStructureFlagsKHR flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR);
314
324 MANDRILL_API void bindRayTracingDescriptors(VkCommandBuffer cmd, ptr<Camera> pCamera, VkPipelineLayout layout);
325
331 MANDRILL_API void setSampler(const ptr<Sampler> pSampler);
332
361 MANDRILL_API ptr<Layout> getLayout();
362
367 MANDRILL_API std::vector<Node>& getNodes()
368 {
369 return mNodes;
370 }
371
376 MANDRILL_API uint32_t getVertexCount() const
377 {
378 return mVertexCount;
379 }
380
385 MANDRILL_API uint32_t getIndexCount() const
386 {
387 return mIndexCount;
388 }
389
394 MANDRILL_API uint32_t getMeshCount()
395 {
396 return count(mMeshes);
397 }
398
403 MANDRILL_API uint32_t getMaterialCount() const
404 {
405 return count(mMaterials);
406 }
407
412 MANDRILL_API uint32_t getTextureCount() const
413 {
414 return count(mTextures);
415 }
416
422 MANDRILL_API uint32_t getMeshVertexCount(uint32_t meshIndex) const
423 {
424 return count(mMeshes[meshIndex].vertices);
425 }
426
432 MANDRILL_API uint32_t getMeshIndexCount(uint32_t meshIndex) const
433 {
434 return count(mMeshes[meshIndex].indices);
435 }
436
442 MANDRILL_API VkDeviceAddress getMeshVertexAddress(uint32_t meshIndex) const
443 {
444 return mpVertexBuffer->getDeviceAddress() + mMeshes[meshIndex].deviceVerticesOffset;
445 }
446
452 MANDRILL_API VkDeviceAddress getMeshIndexAddress(uint32_t meshIndex) const
453 {
454 return mpIndexBuffer->getDeviceAddress() + mMeshes[meshIndex].deviceIndicesOffset;
455 }
456
462 MANDRILL_API uint32_t getMeshMaterialIndex(uint32_t meshIndex) const
463 {
464 return mMeshes[meshIndex].materialIndex;
465 }
466
471 MANDRILL_API ptr<AccelerationStructure> getAccelerationStructure() const
472 {
473 return mpAccelerationStructure;
474 }
475
481 MANDRILL_API void setEnvironmentMap(ptr<Texture> pTexture)
482 {
483 mpEnvironmentMap = pTexture;
484 }
485
486 private:
487 friend Node;
488
489 std::vector<uint32_t> loadFromOBJ(const std::filesystem::path& path,
490 const std::filesystem::path& materialPath = "");
491 std::vector<uint32_t> loadFromGLTF(const std::filesystem::path& path,
492 const std::filesystem::path& materialPath = "");
493 void addTexture(std::string texturePath);
494 void createDescriptors();
495
496 ptr<Device> mpDevice;
497 ptr<Swapchain> mpSwapchain;
498
499 std::vector<Mesh> mMeshes;
500 std::vector<Node> mNodes;
501 std::vector<Material> mMaterials;
502 std::unordered_map<std::string, ptr<Texture>> mTextures;
503 ptr<Texture> mpEnvironmentMap;
504 ptr<Descriptor> mpEnvironmentMapDescriptor;
505
506 ptr<Buffer> mpVertexBuffer;
507 ptr<Buffer> mpIndexBuffer;
508 ptr<Buffer> mpTransforms;
509 ptr<Buffer> mpMaterialParams;
510
511 ptr<Texture> mpMissingTexture;
512
513 bool mSupportRayTracing;
514 ptr<AccelerationStructure> mpAccelerationStructure;
515 ptr<Descriptor> mpRayTracingDescriptor;
516 ptr<Buffer> mpMaterialBuffer; // Almost same as mpMaterialParams but for ray tracing
517 ptr<Buffer> mpInstanceDataBuffer;
518
519 uint32_t mVertexCount;
520 uint32_t mIndexCount;
521 };
522}; // namespace Mandrill
Scene node class for managing a single node in a scene graph. This class can hold meshes and transfor...
Definition Scene.h:91
MANDRILL_API void addMesh(uint32_t meshIndex)
Add a mesh to the node.
Definition Scene.h:119
MANDRILL_API void render(VkCommandBuffer cmd, const ptr< Camera > pCamera, const ptr< const Scene > pScene) const
Render a node in the scene.
Definition Scene.cpp:32
MANDRILL_API glm::mat4 getTransform() const
Get the TRS transform of the node.
Definition Scene.h:138
MANDRILL_API void setTransform(glm::mat4 transform)
Set the TRS transform of the node.
Definition Scene.h:148
MANDRILL_API void setVisible(bool visible)
Set weather the node should be rendered or not.
Definition Scene.h:158
MANDRILL_API void setPipeline(ptr< Pipeline > pPipeline)
Set pipeline to use when rendering node.
Definition Scene.h:129
MANDRILL_API ~Node()
Destructor for scene node.
Definition Scene.cpp:28
MANDRILL_API Node()
Create a new scene node.
Definition Scene.cpp:21
MANDRILL_API bool getVisible() const
Get the visibility of the node.
Definition Scene.h:167
MANDRILL_API std::vector< uint32_t > & getMeshIndices()
Get the mesh indices.
Definition Scene.h:176
Scene class that manages a collection of nodes, materials, meshes, and rendering operations.
Definition Scene.h:202
MANDRILL_API ptr< AccelerationStructure > getAccelerationStructure() const
Get the acceleration structure of the scene.
Definition Scene.h:471
MANDRILL_API VkDeviceAddress getMeshIndexAddress(uint32_t meshIndex) const
Get the address of a mesh's indices buffer.
Definition Scene.h:452
MANDRILL_API void updateAccelerationStructure(VkBuildAccelerationStructureFlagsKHR flags=VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR)
Build and update acceleration structure of the scene. This is needed for ray tracing the scene....
Definition Scene.cpp:328
MANDRILL_API std::vector< uint32_t > addMeshFromFile(const std::filesystem::path &path, const std::filesystem::path &materialPath="")
Add several meshes to a scene by reading them from an OBJ-file.
Definition Scene.cpp:166
MANDRILL_API ~Scene()
Destructor for scene.
Definition Scene.cpp:84
MANDRILL_API uint32_t getTextureCount() const
Get the number of textures in the scene.
Definition Scene.h:412
MANDRILL_API void setEnvironmentMap(ptr< Texture > pTexture)
Set an environment map for the scene.
Definition Scene.h:481
MANDRILL_API std::vector< Node > & getNodes()
Get the list of all nodes in the scene.
Definition Scene.h:367
MANDRILL_API void compile()
Calculate sizes of buffers and allocate resources. Call this after all nodes have been added.
Definition Scene.cpp:191
MANDRILL_API uint32_t getMeshMaterialIndex(uint32_t meshIndex) const
Get the matieral index of a mesh.
Definition Scene.h:462
MANDRILL_API uint32_t getIndexCount() const
Get the number of indices in the scene.
Definition Scene.h:385
MANDRILL_API void setSampler(const ptr< Sampler > pSampler)
Set sampler to use for rendering materials.
Definition Scene.cpp:363
MANDRILL_API uint32_t getMeshVertexCount(uint32_t meshIndex) const
Get the number of vertices in a mesh.
Definition Scene.h:422
MANDRILL_API void bindRayTracingDescriptors(VkCommandBuffer cmd, ptr< Camera > pCamera, VkPipelineLayout layout)
Bind descriptors for ray tracing.
Definition Scene.cpp:349
MANDRILL_API ptr< Node > addNode()
Add a node to the scene.
Definition Scene.cpp:95
MANDRILL_API ptr< Layout > getLayout()
Get the layout used by the scene (as described in the comments for the Scene() constructor above).
Definition Scene.cpp:372
MANDRILL_API void syncToDevice()
Synchronize buffers to device.
Definition Scene.cpp:299
MANDRILL_API uint32_t addMaterial(Material material)
Add a material to the scene.
Definition Scene.cpp:104
MANDRILL_API uint32_t addMesh(const std::vector< Vertex > vertices, const std::vector< uint32_t > indices, uint32_t materialIndex)
Add a mesh to the scene.
Definition Scene.cpp:128
MANDRILL_API uint32_t getMeshIndexCount(uint32_t meshIndex) const
Get the number of indices in a mesh.
Definition Scene.h:432
MANDRILL_API void render(VkCommandBuffer cmd, const ptr< Camera > pCamera) const
Render all the nodes in the scene.
Definition Scene.cpp:88
MANDRILL_API uint32_t getMaterialCount() const
Get the number of materials in the scene.
Definition Scene.h:403
MANDRILL_API uint32_t getMeshCount()
Get the number of meshes in the scene.
Definition Scene.h:394
MANDRILL_API uint32_t getVertexCount() const
Get the number of vertices in the scene.
Definition Scene.h:376
MANDRILL_API VkDeviceAddress getMeshVertexAddress(uint32_t meshIndex) const
Get the address of a mesh's vertices buffer.
Definition Scene.h:442