diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp index d0a9495cddbedc4ca33a0d1754e12e7b405c6954..1fdb693226a4308f93b6458bf6a5d85a1de1edff 100644 --- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp +++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp @@ -8,6 +8,7 @@ #define STBI_ONLY_PNG #include <stb_image.h> #include <vkcv/Logger.hpp> +#include <algorithm> namespace vkcv::asset { @@ -392,25 +393,39 @@ int loadScene(const std::string &path, Scene &scene){ } } - indexType = getIndexType(indexAccessor.componentType); - if (indexType == IndexType::UNDEFINED) return 0; // TODO return vkcv::error; + indexType = getIndexType(indexAccessor.componentType); + if (indexType == IndexType::UNDEFINED) return 0; // TODO return vkcv::error; } const fx::gltf::BufferView& vertexBufferView = sceneObjects.bufferViews[posAccessor.bufferView]; const fx::gltf::Buffer& vertexBuffer = sceneObjects.buffers[vertexBufferView.buffer]; + // only copy relevant part of vertex data + uint32_t relevantBufferOffset = std::numeric_limits<uint32_t>::max(); + uint32_t relevantBufferEnd = 0; + for (const auto &attribute : vertexAttributes) { + relevantBufferOffset = std::min(attribute.offset, relevantBufferOffset); + const uint32_t attributeEnd = attribute.offset + attribute.length; + relevantBufferEnd = std::max(relevantBufferEnd, attributeEnd); // TODO: need to incorporate stride? + } + const uint32_t relevantBufferSize = relevantBufferEnd - relevantBufferOffset; + // FIXME: This only works when all vertex attributes are in one buffer std::vector<uint8_t> vertexBufferData; - vertexBufferData.resize(vertexBuffer.byteLength); + vertexBufferData.resize(relevantBufferSize); { - const size_t off = 0; - const void *const ptr = ((char*)vertexBuffer.data.data()) + off; - if (!memcpy(vertexBufferData.data(), ptr, vertexBuffer.byteLength)) { + const void *const ptr = ((char*)vertexBuffer.data.data()) + relevantBufferOffset; + if (!memcpy(vertexBufferData.data(), ptr, relevantBufferSize)) { std::cerr << "ERROR copying vertex buffer data.\n"; return 0; } } + // make vertex attributes relative to copied section + for (auto &attribute : vertexAttributes) { + attribute.offset -= relevantBufferOffset; + } + const size_t numVertexGroups = objectMesh.primitives.size(); vertexGroups.reserve(numVertexGroups); diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp index 8f8fbb18a7882eae600b8db4a41ca97ad9884077..7cabe46a22dc155d0489dead37e30e07b7db8d94 100644 --- a/projects/first_scene/src/main.cpp +++ b/projects/first_scene/src/main.cpp @@ -43,7 +43,7 @@ int main(int argc, const char** argv) { vkcv::asset::Scene scene; - const char* path = argc > 1 ? argv[1] : "resources/Sponza/Sponza.gltf"; + const char* path = argc > 1 ? argv[1] : "resources/Cutlery/CutlerySzene.gltf"; int result = vkcv::asset::loadScene(path, scene); if (result == 1) { @@ -55,7 +55,7 @@ int main(int argc, const char** argv) { } assert(!scene.vertexGroups.empty()); - std::vector<uint8_t> vBuffers; + std::vector<std::vector<uint8_t>> vBuffers; std::vector<std::vector<uint8_t>> iBuffers; //vBuffers.reserve(scene.vertexGroups.size()); //iBuffers.reserve(scene.vertexGroups.size()); @@ -66,20 +66,7 @@ int main(int argc, const char** argv) { for (int i = 0; i < scene.vertexGroups.size(); i++){ - /*auto vertexBuffer = core.createBuffer<uint8_t>( - vkcv::BufferType::VERTEX, - scene.vertexGroups[i].vertexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - vertexBuffer.fill(scene.vertexGroups[i].vertexBuffer.data);*/ - vBuffers.insert(vBuffers.end(), scene.vertexGroups[i].vertexBuffer.data.begin(),scene.vertexGroups[i].vertexBuffer.data.end()); - - /*auto indexBuffer = core.createBuffer<uint8_t>( - vkcv::BufferType::INDEX, - scene.vertexGroups[i].indexBuffer.data.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - indexBuffer.fill(scene.vertexGroups[i].indexBuffer.data);*/ + vBuffers.push_back(scene.vertexGroups[i].vertexBuffer.data); iBuffers.push_back(scene.vertexGroups[i].indexBuffer.data); auto& attributes = scene.vertexGroups[i].vertexBuffer.attributes; @@ -89,12 +76,13 @@ int main(int argc, const char** argv) { }); } - auto vertexBuffer = core.createBuffer<uint8_t>( + std::vector<vkcv::Buffer<uint8_t>> vertexBuffers; + for(const vkcv::asset::VertexGroup &group : scene.vertexGroups){ + vertexBuffers.push_back(core.createBuffer<uint8_t>( vkcv::BufferType::VERTEX, - vBuffers.size(), - vkcv::BufferMemoryType::DEVICE_LOCAL - ); - vertexBuffer.fill(vBuffers); + group.vertexBuffer.data.size())); + vertexBuffers.back().fill(group.vertexBuffer.data); + } std::vector<vkcv::Buffer<uint8_t>> indexBuffers; for (const auto& dataBuffer : iBuffers) { @@ -104,13 +92,15 @@ int main(int argc, const char** argv) { indexBuffers.back().fill(dataBuffer); } - for (int m = 0; m < scene.vertexGroups.size(); m++){ - for (int k = 0; k < scene.vertexGroups[m].vertexBuffer.attributes.size(); k++){ - vAttributes.push_back(scene.vertexGroups[m].vertexBuffer.attributes[k]); - vBufferBindings.push_back(vkcv::VertexBufferBinding(scene.vertexGroups[m].vertexBuffer.attributes[k].offset, vertexBuffer.getVulkanHandle())); + int vertexBufferIndex = 0; + for (const auto &vertexGroup : scene.vertexGroups){ + for (const auto &attribute : vertexGroup.vertexBuffer.attributes){ + vAttributes.push_back(attribute); + vBufferBindings.push_back(vkcv::VertexBufferBinding(attribute.offset, vertexBuffers[vertexBufferIndex].getVulkanHandle())); } vertexBufferBindings.push_back(vBufferBindings); vBufferBindings.clear(); + vertexBufferIndex++; } // an example attachment for passes that output to the window