You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

排查与解决思路

  1. 版本兼容性问题:iterateAccessorWithIndex是fastgltf较新版本才新增的函数,如果你使用的是vk-guide教程指定的旧版本库,大概率不存在这个函数。直接检查你当前依赖的fastgltf版本,升级到最新稳定版即可。
  2. 参数const属性不匹配:查看iterateAccessorWithIndex的定义,第一个参数是否要求const fastgltf::Asset&?你的代码中gltfAsset是非const对象,尝试在调用时传入const_cast<const fastgltf::Asset&>(gltfAsset),或者将gltfAsset声明为const。
  3. Lambda参数类型严格匹配:将Lambda中的size_t index改为std::size_t index,避免平台typedef差异导致的类型不匹配。
  4. 模板类型内存布局问题:fastgltf对模板参数的内存布局有严格要求,尝试用原生数组(如float[3])替代glm::vec3测试,如果能编译通过,再调整glm类型的使用方式(比如确保glm的内存布局与GLTF要求一致)。

如果以上方法都无效,直接查看你本地fastgltf头文件tools.hpp中是否存在iterateAccessorWithIndex的定义,确认函数签名与你调用的是否完全一致。

内容的提问来源于stack exchange,提问作者qiyuewuyi2333

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:54:50