使用fastgltf时遭遇iterateAccessorWithIndex函数匹配错误求助
fastgltf库中
iterateAccessorWithIndex调用报错:无匹配函数 我在跟随vk-guide教程,使用fastgltf库加载GLTF模型时,遇到编译错误:no matching function for call to 'iterateAccessorWithIndex'。奇怪的是iterateAccessor函数可以正常使用,只有带索引的这个版本报错。我检查了函数定义未发现问题,请问这是库的bug吗?
错误信息
Severity Code Description Project File Line Suppression State Details Error GAF447572 no matching function for call to 'iterateAccessorWithIndex' F:\dev\vulkan\VulkanEngine\out\build\debug\VulkanEngine F:\dev\vulkan\VulkanEngine\renderer\src\huan\utils\gltf\gltf_loader.cpp 67
相关代码
#include "huan/utils/gltf/gltf_loader.hpp" #include <spdlog/spdlog.h> #include <fastgltf/core.hpp> #include <fastgltf/tools.hpp> #include <glm/glm.hpp> namespace huan { std::optional<std::vector<Ref<MeshAsset>>> loadGltfMeshes(VulkanEngine* engine, std::filesystem::path filePath) { spdlog::info("Loading GLTF meshes from {}", filePath.string()); auto data = fastgltf::GltfDataBuffer::FromPath(filePath); if (data.error() != fastgltf::Error::None) { spdlog::error("Failed to load GLTF data from {}", filePath.string()); return std::nullopt; } constexpr auto gltfOptions = fastgltf::Options::LoadGLBBuffers | fastgltf::Options::LoadExternalBuffers; fastgltf::Parser parser{}; fastgltf::Asset gltfAsset; auto load = parser.loadGltfBinary(data.get(), filePath.parent_path(), gltfOptions); if (load.error() == fastgltf::Error::None) { gltfAsset = std::move(load.get()); } else { spdlog::error("Failed to parse GLTF binary from {}", filePath.string()); return std::nullopt; } std::vector<Ref<MeshAsset>> meshes; // Process the GLTF asset to extract mesh data std::vector<uint32_t> indices; std::vector<Vertex> vertices; for (const auto& mesh : gltfAsset.meshes) { Ref<MeshAsset> newMesh = std::make_shared<MeshAsset>(); // Populate meshAsset with data from mesh newMesh->name = mesh.name; indices.clear(); vertices.clear(); for (auto&& prim : mesh.primitives) { GeometrySuface newSurface; newSurface.startIndex = (uint32_t)indices.size(); newSurface.count = (uint32_t)gltfAsset.accessors[prim.indicesAccessor.value()].count; size_t initialVerticesSize = vertices.size(); // load indices { fastgltf::Accessor& indexAccessor = gltfAsset.accessors[prim.indicesAccessor.value()]; indices.reserve(indices.size() + indexAccessor.count); fastgltf::iterateAccessor<std::uint32_t>(gltfAsset, indexAccessor, [&](std::uint32_t index) { indices.push_back(index + initialVerticesSize); }); } // load vertices { fastgltf::Accessor& positionAccessor = gltfAsset.accessors[prim.findAttribute("POSITION")->accessorIndex]; vertices.resize(vertices.size() + positionAccessor.count); fastgltf::iterateAccessorWithIndex<glm::vec3>( gltfAsset, positionAccessor, [&](glm::vec3 v, size_t index) { auto& curVertex = vertices[initialVerticesSize + index]; curVertex.position = v; curVertex.normal = {1, 0, 0}; curVertex.color = glm::vec4(1.0f); curVertex.uvX = 0; curVertex.uvY = 0; }); } // load normal if (auto normalAccessor = prim.findAttribute("NORMAL")) { fastgltf::Accessor& normalAcc = gltfAsset.accessors[normalAccessor->accessorIndex]; fastgltf::iterateAccessorWithIndex<glm::vec3>( gltfAsset, normalAcc, [&](glm::vec3 n, std::size_t index) { vertices[initialVerticesSize + index].normal = n; }); } // load UVs if (auto uvAccessor = prim.findAttribute("TEXCOORD_0")) { fastgltf::Accessor& uvAcc = gltfAsset.accessors[uvAccessor->accessorIndex]; fastgltf::iterateAccessorWithIndex<glm::vec2>(gltfAsset, uvAcc, [&](glm::vec2 uv, std::size_t index) { vertices[initialVerticesSize + index].uvX = uv.x; vertices[initialVerticesSize + index].uvY = uv.y; }); } // load vertex color if (auto colorAccessor = prim.findAttribute("COLOR_0")) { fastgltf::Accessor& colorAcc = gltfAsset.accessors[colorAccessor->accessorIndex]; fastgltf::iterateAccessorWithIndex<glm::vec4>( gltfAsset, colorAcc, [&](glm::vec4 color, std::size_t index) { vertices[initialVerticesSize + index].color = color; }); } newMesh->surfaces.push_back(newSurface); } /** * @brief Display the vertex normal */ constexpr bool overrideColors = true; if (overrideColors) { for (auto& vertex : vertices) { vertex.color = glm::vec4(vertex.normal * 0.5f + 0.5f, 1.0f); } } newMesh->meshBuffers = engine->uploadMesh(indices, vertices); meshes.push_back(newMesh); } return meshes; } } // namespace huan
排查与解决思路
- 版本兼容性问题:
iterateAccessorWithIndex是fastgltf较新版本才新增的函数,如果你使用的是vk-guide教程指定的旧版本库,大概率不存在这个函数。直接检查你当前依赖的fastgltf版本,升级到最新稳定版即可。 - 参数const属性不匹配:查看
iterateAccessorWithIndex的定义,第一个参数是否要求const fastgltf::Asset&?你的代码中gltfAsset是非const对象,尝试在调用时传入const_cast<const fastgltf::Asset&>(gltfAsset),或者将gltfAsset声明为const。 - Lambda参数类型严格匹配:将Lambda中的
size_t index改为std::size_t index,避免平台typedef差异导致的类型不匹配。 - 模板类型内存布局问题:fastgltf对模板参数的内存布局有严格要求,尝试用原生数组(如
float[3])替代glm::vec3测试,如果能编译通过,再调整glm类型的使用方式(比如确保glm的内存布局与GLTF要求一致)。
如果以上方法都无效,直接查看你本地fastgltf头文件tools.hpp中是否存在iterateAccessorWithIndex的定义,确认函数签名与你调用的是否完全一致。
内容的提问来源于stack exchange,提问作者qiyuewuyi2333
相关产品推荐
相关产品推荐

