diff --git a/modules/scene/include/vkcv/scene/MeshPart.hpp b/modules/scene/include/vkcv/scene/MeshPart.hpp index 8d77efd7a112ea92a6c4192e5a5cf43cea53e800..0114398cd60be96ee4071ab1d1afe9d711618ca0 100644 --- a/modules/scene/include/vkcv/scene/MeshPart.hpp +++ b/modules/scene/include/vkcv/scene/MeshPart.hpp @@ -36,11 +36,6 @@ namespace vkcv::scene { */ BufferHandle m_vertices; - /** - * The list of the used vertex buffer bindings. - */ - std::vector<VertexBufferBinding> m_vertexBindings; - /** * The buffer handle of its index buffer. */ @@ -50,6 +45,11 @@ namespace vkcv::scene { * The amount of indices in its index buffer. */ size_t m_indexCount; + + /** + * The descriptor set handle of its vertex data. + */ + DescriptorSetHandle m_descriptorSet; /** * Axis aligned bounding box of the mesh part. diff --git a/modules/scene/include/vkcv/scene/Scene.hpp b/modules/scene/include/vkcv/scene/Scene.hpp index c482b464a8a24e83f1ba12d8294749d7b0cae48a..12323fbfbaea7c8d02d4537e97412511d81591b4 100644 --- a/modules/scene/include/vkcv/scene/Scene.hpp +++ b/modules/scene/include/vkcv/scene/Scene.hpp @@ -54,6 +54,11 @@ namespace vkcv::scene { * A list of nodes in the first level of the scene graph. */ std::vector<Node> m_nodes; + + /** + * A handle to the descriptor set layout used by meshes in this scene. + */ + DescriptorSetLayoutHandle m_descriptorSetLayout; /** * Constructor of a scene instance with a given Core instance. @@ -152,6 +157,13 @@ namespace vkcv::scene { */ [[nodiscard]] const material::Material& getMaterial(size_t index) const; + + /** + * Returns the descriptor set layout handle used by the meshes in the scene. + * @return Descriptor set layout handle + */ + [[nodiscard]] + const DescriptorSetLayoutHandle& getDescriptorSetLayout() const; /** * Record drawcalls of all meshes of this scene with CPU-side frustum culling. diff --git a/modules/scene/src/vkcv/scene/MeshPart.cpp b/modules/scene/src/vkcv/scene/MeshPart.cpp index 50d14ed49d43496ada3853034be1455b044bd902..e220f52e37f6ff9cba50709e0eac8efb8746d390 100644 --- a/modules/scene/src/vkcv/scene/MeshPart.cpp +++ b/modules/scene/src/vkcv/scene/MeshPart.cpp @@ -4,12 +4,17 @@ namespace vkcv::scene { + struct vertex_t { + float positionU [4]; + float normalV [4]; + }; + MeshPart::MeshPart(Scene& scene) : m_scene(scene), m_vertices(), - m_vertexBindings(), m_indices(), m_indexCount(0), + m_descriptorSet(), m_bounds(), m_materialIndex(std::numeric_limits<size_t>::max()) {} @@ -18,23 +23,51 @@ namespace vkcv::scene { std::vector<DrawcallInfo>& drawcalls) { Core& core = *(m_scene.m_core); - auto vertexBuffer = core.createBuffer<uint8_t>( - BufferType::VERTEX, vertexGroup.vertexBuffer.data.size() + auto vertexBuffer = core.createBuffer<vertex_t>( + BufferType::STORAGE, vertexGroup.numVertices ); - vertexBuffer.fill(vertexGroup.vertexBuffer.data); - m_vertices = vertexBuffer.getHandle(); - - auto attributes = vertexGroup.vertexBuffer.attributes; - - std::sort(attributes.begin(), attributes.end(), [](const vkcv::asset::VertexAttribute& x, const vkcv::asset::VertexAttribute& y) { - return static_cast<uint32_t>(x.type) < static_cast<uint32_t>(y.type); - }); + std::vector<vertex_t> vertices; + vertices.reserve(vertexBuffer.getCount()); - for (const auto& attribute : attributes) { - m_vertexBindings.emplace_back(attribute.offset, vertexBuffer.getVulkanHandle()); + for (const auto& attribute : vertexGroup.vertexBuffer.attributes) { + if (attribute.componentType != vkcv::asset::ComponentType::FLOAT32) { + continue; + } + + size_t offset = attribute.offset; + + for (size_t i = 0; i < vertexBuffer.getCount(); i++) { + const auto *data = reinterpret_cast<const float*>( + vertexGroup.vertexBuffer.data.data() + offset + ); + + switch (attribute.type) { + case vkcv::asset::PrimitiveType::POSITION: + memcpy(vertices[i].positionU, data, sizeof(float) * attribute.componentCount); + break; + case vkcv::asset::PrimitiveType::NORMAL: + memcpy(vertices[i].normalV, data, sizeof(float) * attribute.componentCount); + break; + case vkcv::asset::PrimitiveType::TEXCOORD_0: + if (attribute.componentCount != 2) { + break; + } + + vertices[i].positionU[3] = data[0]; + vertices[i].normalV[3] = data[1]; + break; + default: + break; + } + + offset += attribute.stride; + } } + vertexBuffer.fill(vertices); + m_vertices = vertexBuffer.getHandle(); + auto indexBuffer = core.createBuffer<uint8_t>( BufferType::INDEX, vertexGroup.indexBuffer.data.size() ); @@ -43,6 +76,12 @@ namespace vkcv::scene { m_indices = indexBuffer.getHandle(); m_indexCount = vertexGroup.numIndices; + m_descriptorSet = core.createDescriptorSet(m_scene.getDescriptorSetLayout()); + + DescriptorWrites writes; + writes.writeStorageBuffer(0, m_vertices); + core.writeDescriptorSet(m_descriptorSet, writes); + m_bounds.setMin(glm::vec3( vertexGroup.min.x, vertexGroup.min.y, @@ -74,6 +113,9 @@ namespace vkcv::scene { IndexBitCount indexBitCount; switch (vertexGroup.indexBuffer.type) { + case asset::IndexType::UINT8: + indexBitCount = IndexBitCount::Bit8; + break; case asset::IndexType::UINT16: indexBitCount = IndexBitCount::Bit16; break; @@ -87,8 +129,11 @@ namespace vkcv::scene { } drawcalls.push_back(DrawcallInfo( - vkcv::Mesh(m_vertexBindings, indexBuffer.getVulkanHandle(), m_indexCount, indexBitCount), - { DescriptorSetUsage(0, material.getDescriptorSet()) } + vkcv::Mesh(indexBuffer.getVulkanHandle(), m_indexCount, indexBitCount), + { + DescriptorSetUsage(0, m_descriptorSet), + DescriptorSetUsage(1, material.getDescriptorSet()) + } )); } } @@ -100,9 +145,9 @@ namespace vkcv::scene { MeshPart::MeshPart(const MeshPart &other) : m_scene(other.m_scene), m_vertices(other.m_vertices), - m_vertexBindings(other.m_vertexBindings), m_indices(other.m_indices), m_indexCount(other.m_indexCount), + m_descriptorSet(other.m_descriptorSet), m_bounds(other.m_bounds), m_materialIndex(other.m_materialIndex) { m_scene.increaseMaterialUsage(m_materialIndex); @@ -111,9 +156,9 @@ namespace vkcv::scene { MeshPart::MeshPart(MeshPart &&other) noexcept : m_scene(other.m_scene), m_vertices(other.m_vertices), - m_vertexBindings(other.m_vertexBindings), m_indices(other.m_indices), m_indexCount(other.m_indexCount), + m_descriptorSet(other.m_descriptorSet), m_bounds(other.m_bounds), m_materialIndex(other.m_materialIndex) { m_scene.increaseMaterialUsage(m_materialIndex); @@ -125,9 +170,9 @@ namespace vkcv::scene { } m_vertices = other.m_vertices; - m_vertexBindings = other.m_vertexBindings; m_indices = other.m_indices; m_indexCount = other.m_indexCount; + m_descriptorSet = other.m_descriptorSet; m_bounds = other.m_bounds; m_materialIndex = other.m_materialIndex; @@ -136,9 +181,9 @@ namespace vkcv::scene { MeshPart &MeshPart::operator=(MeshPart &&other) noexcept { m_vertices = other.m_vertices; - m_vertexBindings = other.m_vertexBindings; m_indices = other.m_indices; m_indexCount = other.m_indexCount; + m_descriptorSet = other.m_descriptorSet; m_bounds = other.m_bounds; m_materialIndex = other.m_materialIndex; diff --git a/modules/scene/src/vkcv/scene/Scene.cpp b/modules/scene/src/vkcv/scene/Scene.cpp index 9a8ded0f70880125ed1efeda9a6845e1dc735d22..629f44d95babfa0ce4f2dadd0630093c58b1cb31 100644 --- a/modules/scene/src/vkcv/scene/Scene.cpp +++ b/modules/scene/src/vkcv/scene/Scene.cpp @@ -8,10 +8,28 @@ namespace vkcv::scene { + static DescriptorBindings getDescriptorBindings() { + DescriptorBindings bindings = {}; + + auto binding_0 = DescriptorBinding { + 0, + DescriptorType::STORAGE_BUFFER, + 1, + ShaderStage::VERTEX, + false, + false + }; + + bindings.insert(std::make_pair(0, binding_0)); + + return bindings; + } + Scene::Scene(Core* core) : m_core(core), m_materials(), - m_nodes() {} + m_nodes(), + m_descriptorSetLayout(core->createDescriptorSetLayout(getDescriptorBindings())) {} Scene::~Scene() { m_nodes.clear(); @@ -21,7 +39,8 @@ namespace vkcv::scene { Scene::Scene(const Scene &other) : m_core(other.m_core), m_materials(other.m_materials), - m_nodes() { + m_nodes(), + m_descriptorSetLayout(other.m_descriptorSetLayout) { m_nodes.resize(other.m_nodes.size(), Node(*this)); for (size_t i = 0; i < m_nodes.size(); i++) { @@ -32,7 +51,8 @@ namespace vkcv::scene { Scene::Scene(Scene &&other) noexcept : m_core(other.m_core), m_materials(other.m_materials), - m_nodes() { + m_nodes(), + m_descriptorSetLayout(other.m_descriptorSetLayout) { m_nodes.resize(other.m_nodes.size(), Node(*this)); for (size_t i = 0; i < m_nodes.size(); i++) { @@ -54,6 +74,8 @@ namespace vkcv::scene { m_nodes[i] = other.m_nodes[i]; } + m_descriptorSetLayout = other.m_descriptorSetLayout; + return *this; } @@ -67,6 +89,8 @@ namespace vkcv::scene { m_nodes[i] = std::move(other.m_nodes[i]); } + m_descriptorSetLayout = other.m_descriptorSetLayout; + return *this; } @@ -111,6 +135,10 @@ namespace vkcv::scene { return m_materials[index].m_data; } + const DescriptorSetLayoutHandle &Scene::getDescriptorSetLayout() const { + return m_descriptorSetLayout; + } + void Scene::recordDrawcalls(CommandStreamHandle &cmdStream, const camera::Camera &camera, const PassHandle &pass,