ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TinyGLTF 实战指南:在 Vulkan 工程中集成 Header-Only 的 C++ glTF 2.0 加载器与序列化器

TinyGLTF 实战指南:在 Vulkan 工程中集成 Header-Only 的 C++ glTF 2.0 加载器与序列化器 示例工程图形学【免费下载链接】VulkanC examples for the Vulkan graphics API项目地址https://gitcode.com/gh_mirrors/vu/Vulkan点击查看免费下载本文以仓库内 external/tinygltf/README.md 为核心结合该库在 Vulkan 示例工程中的真实集成代码系统讲解 TinyGLTF 的定位、特性、编译选项、加载/保存流程与测试方法。读完本文你将掌握如何在任意 C11 工程中仅靠拷贝头文件引入 TinyGLTF如何加载 ASCII glTF.gltf与二进制 GLB.glb场景、处理内嵌 Base64/DataURI 数据与外部资源如何通过自定义回调接管图像解码与文件系统访问以及如何像本仓库的 Vulkan 示例一样把 glTF 场景无缝接入 GPU 渲染管线。TinyGLTF 是什么项目定位与技术形态TinyGLTF 是一个Header-Only仅头文件的 C11 glTF 2.0 加载器与序列化器。它不对应某个图形 API而是负责把符合 Khronos glTF 2.0 规范的.gltf/.glb文件解析成可供上层渲染引擎直接使用的内存结构tinygltf::Model。技术形态全部实现集中在单个头文件 external/tinygltf/tiny_gltf.h约 7600 行并在仓库内随附三个运行时依赖头文件external/tinygltf/json.hpp、external/tinygltf/stb_image.hstb_image_write.h 仅在某些编译选项下需要。编译依赖依赖 Niels Lohmann 的json.hpp即 nlohmann/json解析 JSON因此要求C11 编译器历史上曾存在面向 C03 的devel-picojson分支但当前主线以 C11 为基线。标准遵循完整实现 glTF 规范 v2.0.0同时覆盖 ASCII glTF 与二进制 GLB 两种容器格式的加载与保存。在 README.md 的自述中官方明确列出其跨平台验证矩阵macOS clang(LLVM)、iOS clang、Linux gcc/clang、Windows MinGW、Windows Visual Studio 2015 Update 3 及以上VS2013 因 C11 支持不完整无法编译json.hpp而不被支持、Android NDK、Android CrystaX(NDK 替代品) GCC、WebEmscripten/LLVM。从源码结构看tiny_gltf.h 还为 Android__ANDROID__与 OpenHarmony__OHOS__预置了平台资源加载的接入点这与本仓库同时提供android/与openharmony/平台工程的事实相互印证。版本演进与状态README 与头文件内的版本注释共同勾勒了 TinyGLTF 的能力演进路线以仓库内头文件 tiny_gltf.h 注释为准其版本号已迭代至 v2.4.2版本关键变更v2.0.02018-08-22正式切换到 glTF 2.0v2.0.1增加比较comparison特性v2.1.0增加 Draco 网格压缩加载支持v2.2.0支持 16bit PNG 加载支持 Sparse accessor稀疏访问器v2.3.0依据 glTF 2.0 schema 重构 Material 表示引入TextureInfo类Value::IsNumber()语义变化v2.3.1Sampler中minFilter/magFilter默认值改为 -1v2.4.0实验性 RapidJSON 支持实验性 C14 支持可能带来更好性能v2.4.1修复部分 glTF 对象类缺少extensions/extras属性的问题v2.4.2解码百分号编码的 URI功能特性总览README 的功能清单可以归纳为以下五个能力维度每一条都能在 tiny_gltf.h 的公开接口与结构体定义中得到印证容器格式ASCII glTF加载 ✅ / 保存 ✅、Binary GLB加载 ✅ / 保存 ✅支持将 .bin 内嵌为单一 .glb。缓冲区Buffers解析 Base64 编码的内嵌缓冲区数据DataURI加载外部.bin文件保存时可写入文件或内嵌。图像Images基于 stb_image解析 Base64 内嵌图像 DataURI加载外部图像文件支持 PNG8bit 与 16bit、JPEG仅 8bit、BMP、GIF提供自定义图像解码回调例如用于解码 OpenEXR 等 stb_image 不支持的格式。几何数据支持 Morph target支持 Sparse accessor稀疏访问器用于高效表达只有部分元素被修改的顶点数据见 tiny_gltf.h 中 v2.2.0 变更记录。扩展与可定制性支持从内存直接加载 glTF支持自定义回调图像加载、图像保存、文件系统访问支持 Draco 网格解码扩展✅ 已实现❌ 编码尚不支持。接口层面的能力入口集中在 tiny_gltf.h 的class TinyGLTFLoadASCIIFromFile/LoadASCIIFromString/LoadBinaryFromFile/LoadBinaryFromMemory四个加载入口WriteGltfSceneToStream/WriteGltfSceneToFile两个保存入口外加SetImageLoader/SetImageWriter/SetFsCallbacks三个回调注册入口。在 Vulkan 示例仓库中的实际集成本仓库正是 TinyGLTF 的上游文档所列举的Projects using TinyGLTF典型场景——用 Vulkan 渲染 glTF 2.0 模型。仓库内的集成方式可作为标准接入范本通用模型加载器base/VulkanglTFModel.h 与 base/VulkanglTFModel.cpp 定义了vkglTF::Model类它封装了 TinyGLTF 解析、Vulkan 缓冲/纹理上传、场景图与动画驱动等完整流程。其中 VulkanglTFModel.h 在包含tiny_gltf.h前定义了TINYGLTF_NO_STB_IMAGE_WRITEAndroid 平台还额外定义TINYGLTF_ANDROID_LOAD_FROM_ASSETS说明该工程不需要 stb_image_write 的序列化能力。独立的简化加载示例examples/gltfloading/gltfloading.cpp 用约 700 行代码自建了一个仅含基础功能的 glTF 加载类展示了不依赖vkglTF::Model的最小集成路径同类独立封装还出现在 examples/gltfscenerendering/gltfscenerendering.h 与 examples/gltfskinning/gltfskinning.h 中。多目标编译提示apple/examples.h 的注释说明除自行封装 tiny_gltf 的示例外其余示例统一通过编译base/VulkanglTFModel.cpp引入实现。自定义图像加载回调的典型用法base/VulkanglTFModel.cpp 展示了 README 中SetImageLoader回调机制的实战写法仓库为支持KTX 纹理自定义了loadImageDataFunc当图像 URI 以.ktx结尾时直接返回true把解码交给 Vulkan 侧 KTX 加载代码其余情况回落到 TinyGLTF 默认的tinygltf::LoadImageData对于不需要贴图的示例则注册loadImageDataFuncEmpty空实现配合FileLoadingFlags::DontLoadImages跳过图像解码以加快加载。对应地base/VulkanglTFModel.cpp 的vkglTF::Model::loadFromFile是标准接入流程的浓缩构造tinygltf::Model与tinygltf::TinyGLTF→ 按需SetImageLoader→Android/OpenHarmony 平台把应用资源管理器指针赋给tinygltf::asset_manager/tinygltf::rawfile_manager→LoadASCIIFromFile解析 → 成功后依次执行loadImages/loadMaterials/ 场景节点遍历loadNode/loadAnimations/loadSkins。这也印证了 README 中加载 GLB 只需把LoadASCIIFromFile换成LoadBinaryFromFile的说法。快速集成最小可运行示例按照 README 的 Build 章节将stb_image.h、stb_image_write.h仅当需要图像写出时、json.hpp与tiny_gltf.h拷贝到你的工程即可无需链接任何库。由于json.hpp与 stb 系列头文件都已被tiny_gltf.h内部条件包含实际项目中通常只需手动放置 tiny_gltf.h 与对应依赖文件。关键规则实现宏只能在一个.cc编译单元中定义一次否则会造成重复符号/重复实例化// 仅在工程中的 *一个* .cc 文件里定义以下宏 #define TINYGLTF_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION // #define TINYGLTF_NOEXCEPTION // 可选。禁用异常处理。 #include tiny_gltf.h其余所有包含tiny_gltf.h的文件都不再需要定义TINYGLTF_IMPLEMENTATION只需#include tiny_gltf.htiny_gltf.h 中#if defined(TINYGLTF_IMPLEMENTATION)的守卫保证了实现只在你指定的编译单元中展开一次。本仓库的 examples/gltfloading/gltfloading.cpp 即为这种单编译单元定义实现的范例。加载 glTF 2.0 模型的完整流程README 给出的加载示例是接入 TinyGLTF 的标准姿势完整代码如下using namespace tinygltf; Model model; TinyGLTF loader; std::string err; std::string warn; bool ret loader.LoadASCIIFromFile(model, err, warn, argv[1]); // bool ret loader.LoadBinaryFromFile(model, err, warn, argv[1]); // 用于二进制 glTF(.glb) if (!warn.empty()) { printf(Warn: %s\n, warn.c_str()); } if (!err.empty()) { printf(Err: %s\n, err.c_str()); } if (!ret) { printf(Failed to parse glTF\n); return -1; }要点拆解err与warn语义warn收集非致命问题如某些资源加载失败见 tiny_gltf.h 中Set warning message towarnfor example it fails to load asserts的注释err只在解析真正失败时被填充ret false即表示解析失败。LoadASCIIFromString/LoadBinaryFromMemoryREADME 强调支持从内存加载对应 tiny_gltf.h 中两个内存入口后者额外接受base_dir参数用于解析内存数据中引用的外部资源相对路径。校验级别参数所有加载入口的最后一个参数check_sections默认为REQUIRE_VERSION即加载时会校验 glTF 资产头部的asset.version字段确保版本与库支持的 2.0 规范一致。model结构解析完成后tinygltf::Model内含scenes/nodes/meshes/accessors/bufferViews/buffers/images/textures/materials/animations/skins等与 glTF 2.0 schema 一一对应的容器上层渲染代码如 base/VulkanglTFModel.cpp从model.scenes[model.defaultScene]出发遍历场景图即可。编译选项全解析README 列出了全部 11 个编译期宏开关它们是 TinyGLTF 可裁剪性的核心。以下逐项说明其作用并结合 tiny_gltf.h 中的实际条件编译逻辑补充取值语义宏作用与使用场景TINYGLTF_NOEXCEPTION禁用 JSON 解析中的 C 异常。可与编译器-fno-exceptions配合或同时定义符号JSON_NOEXCEPTION与TINYGLTF_NOEXCEPTION以彻底移除异常代码。适用于对二进制体积或异常安全敏感的嵌入式/低延迟场景TINYGLTF_NO_STB_IMAGE不通过 stb_image 加载图像改由TinyGLTF::SetImageLoader(LoadImageDataFunction, void *user_data)注册回调自行解码。从实现看tiny_gltf.h未定义此宏时默认图像加载器就是tinygltf::LoadImageDataTINYGLTF_NO_STB_IMAGE_WRITE不通过 stb_image_write 写出图像改由TinyGLTF::SetImageWriter(WriteImageDataFunction, void *user_data)注册回调。本仓库 VulkanglTFModel.h 即定义了此宏纯加载用途无序列化需求TINYGLTF_NO_EXTERNAL_IMAGE解析期间不尝试加载外部图像文件适合先解析场景结构、后按需加载贴图的延迟加载架构TINYGLTF_ANDROID_LOAD_FROM_ASSETS所有文件改为从打包进 APK 的 assets 读取而非常规文件系统。注意使用前必须把应用的有效AAssetManager指针赋给tinygltf::asset_manager。仓库的 Android 示例正是通过tinygltf::asset_manager androidApp-activity-assetManager完成赋值见 base/VulkanglTFModel.cppTINYGLTF_ENABLE_DRACO启用 Draco 压缩网格解码。需要在工程文件中额外提供 Draco 的 include 路径并链接对应库tiny_gltf.h 在启用时引入draco/compression/decode.h等头文件TINYGLTF_NO_INCLUDE_JSON禁止tiny_gltf.h内部自动#include json.hpp——适用于json.hpp已在之前被包含或希望用自定义路径包含它的情况tiny_gltf.hTINYGLTF_NO_INCLUDE_STB_IMAGE同理禁止内部自动包含stb_image.hTINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE同理禁止内部自动包含stb_image_write.hTINYGLTF_USE_RAPIDJSON使用 RapidJSON 作为 JSON 解析/序列化引擎实验性。RapidJSON 文件不随 TinyGLTF 分发启用时需自行设置 include 路径tiny_gltf.h 会改为包含document.h、writer.h等 RapidJSON 头文件TINYGLTF_USE_CPP14启用 C14 特性需 C14 编译器README 说明可能带来优于 C11 的解析性能除上述宏外tiny_gltf.h 的实现还预留了TINYGLTF_NO_FS宏禁用内置文件系统回调配合TinyGLTF::SetFsCallbacks(FsCallbacks)可完全接管FileExists/ExpandFilePath/ReadWholeFile/WriteWholeFile四个文件系统操作——这与TINYGLTF_ANDROID_LOAD_FROM_ASSETS的定制思路一脉相承是 TinyGLTF 可移植性的底层机制。关于扩展属性ExtensionMap的取值细节glTF 规范允许任意对象携带extensions与extras。TinyGLTF 将其解析为ExtensionMap值为tinygltf::Value的映射。README 专门给出两个易踩坑的语义说明JSON number 的双重表示扩展属性中的数值会被解析为 int 或 float 并存入tinygltf::Value。若想要浮点数值必须使用GetNumberAsDouble()方法显式获取例如某个扩展约定scale为 2底层存储是 INT_TYPE直接取 double 需要走该方法。IsNumber()的判定范围IsNumber()在底层值是整数或浮点数时均返回true自 v2.3.0 起该行为被正式确认见 tiny_gltf.h 版本注释因此它只能回答是不是数值不能区分 int 与 double需要进一步判断类型时可参考tinygltf::Type枚举tiny_gltf.h 中INT_TYPE/REAL_TYPE等。另外所有 glTF 对象类Image、Texture、Node、Material等都内置Value extras与ExtensionMap extensions字段且通过TinyGLTF::SetStoreOriginalJSONForExtrasAndExtensions(true)可让库额外保存extras/extensions的原始 JSON 字符串见 tiny_gltf.h 与Image结构体的extras_json_string字段tiny_gltf.h便于上层重建自定义数据结构。SetSerializeDefaultValues(true)则会在保存时强制序列化默认值用于输出完整的 glTF 描述。保存 glTF 模型TinyGLTF 同时提供序列化能力通过WriteGltfSceneToStream/WriteGltfSceneToFile输出。README 明确了两条保存路径的能力边界缓冲区Buffers✅ 写入外部文件✅ 内嵌到文件内❌ Draco 压缩后保存未实现。图像Images✅ 写入外部文件✅ 内嵌。二进制.glb✅ 支持 .bin 内嵌的单一 .glb❌ 外部 .bin 形式未实现。WriteGltfSceneToFile的完整签名tiny_gltf.h为bool WriteGltfSceneToFile(Model *model, const std::string filename, bool embedImages, bool embedBuffers, bool prettyPrint, bool writeBinary);其中embedImages/embedBuffers控制资源是否内嵌为 DataURIprettyPrint控制 JSON 是否美化输出writeBinary控制输出 GLB 还是 ASCII JSON。附带的示例程序README 随库分发的三个示例程序上游 examples 目录可作为上手参考glview简单的 glTF 几何查看器适合理解最小的加载 绘制闭环。validator基于 JSON schema 的简单 glTF 校验器适合检查模型文件是否符合规范。basic带纹理支持的基础 glTF 查看器。需要说明的是本仓库仅镜像了 TinyGLTF 的运行时头文件external/tinygltf/ 下仅有tiny_gltf.h、json.hpp、stb_image.h、README.md与LICENSE示例程序对应的实际工程级范例见仓库自身的 examples/gltfloading/gltfloading.cpp、examples/gltfscenerendering/gltfscenerendering.h、examples/gltfskinning/gltfskinning.h含动画与骨骼等 Vulkan 示例其效果截图位于 screenshots/ 目录gltfloading.jpg、gltfscenerendering.jpg、gltfskinning.jpg。测试与验证README 给出三层测试体系可在接入后用于回归验证glTF 解析测试需 Python 2.6/2.7将 KhronosGroup 的 glTF-Sample-Models 样例模型集克隆到本地编译loader_example后编辑test_runner.py运行$ python test_runner.py批量验证各种合法/非法模型文件的解析结果。单元测试$ cd tests $ make $ ./tester $ ./tester_noexcepttester与tester_noexcept分别验证默认构建与TINYGLTF_NOEXCEPTION构建下的正确性。模糊测试Fuzzing详见tests/fuzzer。README 记录其作者在 Ryzen9 3950X 上连续运行一周模糊测试的结果——LoadASCIIFromString除模糊器自身的 OOM内存耗尽外未发现其他崩溃点同时坦言为更稳妥起见后续应考虑在解析 glTF 数据时引入有界的bounded内存大小检查。许可证与第三方依赖TinyGLTF 本体采用MIT 许可证仓库内见 external/tinygltf/LICENSE。其依赖的第三方组件许可情况如下json.hppCopyright (c) 2013-2017 Niels LohmannMIT 许可证。base64base64 编解码Copyright (C) 2004-2008 René Nyffenegger。stb_image.hv2.08public domain公有领域图像加载库。stb_image_write.hv1.09public domain 图像写出库。catch单元测试框架Copyright (c) 2012 Two Blue Cubes Ltd.Boost Software License 1.0。RapidJSON可选 JSON 引擎Copyright (C) 2015 THL A29 Limited腾讯公司与 Milo Yip保留所有权利。dliburidecode/uriencode 工具函数Copyright (C) 2003 Davis E. KingBoost Software License 1.0。由于 TinyGLTF 本体与主要依赖json.hpp、stb_image均为宽松许可在 Vulkan 这类跨平台图形工程中按 README 建议拷贝头文件 单编译单元定义TINYGLTF_IMPLEMENTATION即可合规引入无需额外链接或构建步骤。赞分享示例工程图形学【免费下载链接】VulkanC examples for the Vulkan graphics API项目地址https://gitcode.com/gh_mirrors/vu/Vulkan点击查看免费下载相关推荐如何使用STMViewer进行实时变量监控零基础入门到精通教程如何使用STMViewer进行实时变量监控零基础入门到精通教程 STMViewer是一款强大的实时STM32变量与跟踪查看器Real time STM32开发工具调试器嵌入式桌面应用Warp C CUBIN 集成实战用 Python 编写 Kernel、在 C CUDA 程序中加载与启动Warp C CUBIN 集成实战用 Python 编写 Kernel、在 C CUDA 程序中加载与启动 本指南基于 warp/examples/c高性能计算物理引擎图形学机器人ncnn Vulkan 驱动加载器simplevk完全指南工作原理、加载顺序与实战用法ncnn Vulkan 驱动加载器simplevk完全指南工作原理、加载顺序与实战用法 导读 本指南以 docs/developer guide/vulk人工智能深度学习推理引擎本地部署上一篇Microsoft UFO项目文档架构深度解析与技术指南下一篇Synology_HDD_db项目解决DSM 7.2.2-72803版本硬盘兼容性警告问题创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表