【C++】tinygltf基本使用方法加载glb/gltf格式
一、前言
1、gltf规范文档:glTF™ 2.0 Specification (khronos.org)
2、gltf在线模型查看器 :glTF Viewer (donmccurdy.com)
3、tinygltf:GitHub – syoyo/tinygltf: Header only C++11 tiny glTF 2.0 library
4、vulkan使用tinygltf官方示例:GitHub – SaschaWillems/Vulkan-glTF-PBR: Physical based rendering with Vulkan using glTF 2.0 models
二、使用
1、初始化
首先引入头文件:
#define TINYGLTF_IMPLEMENTATION #include <tiny_gltf.h>
再加载文件,注意glb格式和gltf格式调用的函数不同:
tinygltf::Model model; tinygltf::TinyGLTF loader; std::string err; std::string warn;bool load_ok; if(is_glb)load_ok = loader.LoadBinaryFromFile(&model, &err, &warn, std::string{ path_name }); elseload_ok = loader.LoadASCIIFromFile(&model, &err, &warn, std::string{ path_name });if (!warn.empty()) log_warn(“{}”, warn);if (!err.empty())log_err(“{}”, err);if (!load_ok) {log_err(“解析gltf格式失败:{}”, err);return {}; }
二、读取材质
//——————获取材质——————- mo_material.resize(model.materials.size()); for (size_t i = 0; i < model.materials.size(); ++i) {tinygltf::Material& m = model.materials[i];log_info(“材质:{},{}”, i, m.name);tinygltf::PbrMetallicRoughness& pbr = m.pbrMetallicRoughness;ModelObjectMaterial& material = mo_material[i];material._materialName = m.name;material._material._diffuseAlbedo = { (float)pbr.baseColorFactor[0],(float)pbr.baseColorFactor[1],(float)pbr.baseColorFactor[2], 1.0f };material._material._fresnelR0 = { (float)pbr.metallicFactor, (float)pbr.metallicFactor, (float)pbr.metallicFactor };material._material._roughness = (float)pbr.roughnessFactor;// 纹理导出auto fn_texture = [&](int index, std::string_view tag) {if (index == -1)return std::string{};tinygltf::Image& img = model.images[index];if (!img.uri.empty())return img.uri;std::string path_name = fmt::format(“{}{}{}#{}.png”,File::PathTemp(), res_name, tag, i);stbi_write_png(CodeCvt::Utf8ToMultiByte(path_name).c_str(),img.width, img.height,4, img.image.data(), 0);return path_name;};material._pathTexDiffuse = fn_texture(pbr.baseColorTexture.index, “”);material._pathTexNormal = fn_texture(m.normalTexture.index, “_normal”); }
for (tinygltf::Mesh& mesh : model.meshes){for (tinygltf::Primitive& prim : mesh.primitives){PrimData& prim_data = map_material[prim.material];size_t vertex_offset = prim_data._allVertex.size();// 索引{tinygltf::Accessor accessor = model.accessors[prim.indices];tinygltf::BufferView buf_view = model.bufferViews[accessor.bufferView];tinygltf::Buffer& buf = model.buffers[buf_view.buffer];int byte_stride = accessor.ByteStride(buf_view);unsigned char* p = buf.data.data() + buf_view.byteOffset + accessor.byteOffset;assert(byte_stride == 4);for (size_t i = 0; i < accessor.count; ++i){uint32_t index = *(uint32_t*)p; prim_data._allIndex.push_back(vertex_offset + index);p += byte_stride;}}// 位置auto iter_pos = prim.attributes.find(“POSITION”);if(iter_pos != prim.attributes.end()){tinygltf::Accessor accessor = model.accessors[iter_pos->second];tinygltf::BufferView buf_view = model.bufferViews[accessor.bufferView];tinygltf::Buffer& buf = model.buffers[buf_view.buffer];prim_data._allVertex.resize(vertex_offset + accessor.count);int byte_stride = accessor.ByteStride(buf_view);unsigned char* p = buf.data.data() + buf_view.byteOffset + accessor.byteOffset;for (size_t i = 0; i < accessor.count; ++i){Vertex& v = prim_data._allVertex[vertex_offset + i];v._pos = *(Position3*)p;p += byte_stride;}}// uvauto iter_uv = prim.attributes.find(“TEXCOORD_0”);if (iter_uv != prim.attributes.end()){tinygltf::Accessor accessor = model.accessors[iter_uv->second];tinygltf::BufferView buf_view = model.bufferViews[accessor.bufferView];tinygltf::Buffer& buf = model.buffers[buf_view.buffer];int byte_stride = accessor.ByteStride(buf_view);unsigned char* p = buf.data.data() + buf_view.byteOffset + accessor.byteOffset;for (size_t i = 0; i < accessor.count; ++i){Vertex& v = prim_data._allVertex[vertex_offset + i];v._uv = *(Position2*)p;p += byte_stride;}}// normalauto iter_normal = prim.attributes.find(“NORMAL”);if (iter_normal != prim.attributes.end()){tinygltf::Accessor accessor = model.accessors[iter_normal->second];tinygltf::BufferView buf_view = model.bufferViews[accessor.bufferView];tinygltf::Buffer& buf = model.buffers[buf_view.buffer];int byte_stride = accessor.ByteStride(buf_view);unsigned char* p = buf.data.data() + buf_view.byteOffset + accessor.byteOffset;for (size_t i = 0; i < accessor.count; ++i){Vertex& v = prim_data._allVertex[vertex_offset + i];v._normal = *(Position3*)p;p += byte_stride;}}// TANGENTauto iter_tangent = prim.attributes.find(“TANGENT”);if (iter_tangent != prim.attributes.end()){tinygltf::Accessor accessor = model.accessors[iter_tangent->second];tinygltf::BufferView buf_view = model.bufferViews[accessor.bufferView];tinygltf::Buffer& buf = model.buffers[buf_view.buffer];int byte_stride = accessor.ByteStride(buf_view);unsigned char* p = buf.data.data() + buf_view.byteOffset + accessor.byteOffset;for (size_t i = 0; i < accessor.count; ++i){Vertex& v = prim_data._allVertex[vertex_offset + i];v._tangent = *(Position3*)p;p += byte_stride;}}}}
三、截图
二次
代码
位置
使用
保存
光照
函数
初始
单个
单位
可靠性
图片
在线
城市
基本
失败
学习
官方
定义
导出
库比
引入
截图
提供
检查
没有
注释
点数
然后
现在
相关
简单
类型
索引
结构
绘制
网上
网格
蒂诺
规范
解析
访问
超过
适用
通用
链接
顶点
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,请不要用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性
GLB下载网 - GLB/GLTF模型与格式资源免费下载,支持在线浏览与转换 » 【C++】tinygltf基本使用方法加载glb/gltf格式
2. 分享目的仅供大家学习和交流,请不要用于商业用途!
3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员!
8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载
声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性
GLB下载网 - GLB/GLTF模型与格式资源免费下载,支持在线浏览与转换 » 【C++】tinygltf基本使用方法加载glb/gltf格式
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载要提取码
- 分享过期和重复下载怎么办
- 模型和平台不兼容怎么办
