缓冲区视图中的字节偏移量大于字节长度

Byte offset greater than Byte Length in BufferView

本文关键字:字节 大于 偏移量 缓冲区 视图      更新时间:2023-10-16

我正在尝试使用 Microsoft::glTF SDK 从 scene.bin 文件中读取数据。TinyGLTF不是一种选择。当我尝试读取名为TEXCOORD_0的MeshPrimitive属性时,我遇到BufferView byteOffset大于byteLength的情况。因此,我不知道如何正确读取给定的数据,我的程序崩溃了。

我尝试使用IStreamReader读取数据,这是SDK的一部分,并且使用此SDK读取bin文件时是必须的。我通过添加accessor.byteOffset + bufferView.byteOffset来计算数据偏移量,这是>字节长度。

struct BuffersAccessors {
    Microsoft::glTF::Accessor accessor;
    Microsoft::glTF::BufferView view;
    Microsoft::glTF::Buffer buffer;
    void operator=(BuffersAccessors accessors);
};
template<typename T> struct BufferInfo {
BuffersAccessors buffersAccessors;
    std::vector<T> bufferData;
    BufferInfo<T>();
    BufferInfo<T>(BuffersAccessors buffersAccessors, std::vector<T> bufferData);
    const void operator=(const BufferInfo<T> &info) {
        buffersAccessors = info.buffersAccessors;
        bufferData = info.bufferData;
    };
};
    template<typename T>
std::vector<T> readBufferData(Microsoft::glTF::Document document, BufferInfo<T> bufferInfo, std::filesystem::path path) {
    std::vector<T> stream;
    if (bufferInfo.buffersAccessors.buffer.uri.length() > 0 || bufferInfo.buffersAccessors.buffer.byteLength > 0) {
        Microsoft::glTF::Buffer buffer = bufferInfo.buffersAccessors.buffer;
        path += bufferInfo.buffersAccessors.buffer.uri;
        path = std::filesystem::absolute(path);
        buffer.uri = path.string();
        std::shared_ptr<StreamReader> streamReader = std::make_shared<StreamReader>(path);
        Microsoft::glTF::GLTFResourceReader reader(streamReader);
        stream = reader.ReadBinaryData<T>(buffer, bufferInfo.buffersAccessors.view);
    }
    return stream;
}
    template<typename T>
BufferInfo<T> getFullBufferData(Microsoft::glTF::Document document, std::string accessorKey, std::filesystem::path path) {
    BufferInfo<T> bufferInfo{};
    BuffersAccessors mainPart = getBufferAccessorFromDocument(document, accessorKey);
    bufferInfo.buffersAccessors = mainPart;
    std::vector<T> bufferData = vkglTF::readBufferData<T>(document, bufferInfo, path);
    const size_t bufferDataOffset = mainPart.accessor.byteOffset + mainPart.view.byteOffset;    //How to properly calculate offset?
    bufferData.erase(bufferData.begin(), bufferData.begin() + bufferDataOffset);
    bufferInfo.bufferData = bufferData;
    return bufferInfo;
}

我希望数据采用uint8和uint16等格式,但是我的程序在尝试执行bufferData.erase(..(时崩溃。

编辑:阅读WEIGHTS_0时也会发生这种情况。

我认为您的代码最可能的错误是字节偏移量和矢量元素索引的混合。您是否尝试过将bufferDataOffset除以sizeof(T)

其次,如果只想读取访问器的数据,请尝试使用接受访问器参数的 ReadBinaryData 重载。这样,glTF SDK 将为您处理所有偏移量计算。

没有文档,但反序列化示例演示了使用 glTF SDK 时建议的基本代码结构。