glTFでのモデルの描画
glTFでモデルの描画
joint情報を読み込み、静止モデルの描画をしてみた。
モデルの権利表記
配布元リポジトリ
https://github.com/TheThinMatrix/OpenGL-AnimationUnlicense license
https://unlicense.org/
glTFフォーマットの読み込み方
tiny glTFを用いてglTFのモデルを読み込んでいる。ライセンスはMITライセンス。
https://github.com/syoyo/tinygltf
使い方は以下のgit hubにあるコードを参考にした。ライセンスはApache 2.0。
https://github.com/techlabxe/vk_raytracing_book_1/blob/master/Common/include/util/VkrModel.h
https://github.com/techlabxe/vk_raytracing_book_1/tree/master/Common/src/util
glTFの構造については仕様書にまとめられている。
glTF™ 2.0 Specification
アニメーションの読み込みと描画に成功すれば、情報を改めてまとめ直したいと思っているが、とりあえずコードは以下のようなもの。
using namespace tinygltf; std::vector<glm::uvec4> tmpJoint; std::vector<glm::vec4> tmpWeight; const uint8_t* jointSrc; const glm::vec4* weightSrc; for(auto& primitive : model.meshes[0].primitives){ //each primitive Geometry geo = {}; for(auto& attr : primitive.attributes) { std::string attName = attr.first; //positions if (std::regex_search(attName, std::regex("position", std::regex::icase))) { const auto &posAccr = model.accessors[attr.second]; const auto &posBufView = model.bufferViews[posAccr.bufferView]; size_t offsetByte = posAccr.byteOffset + posBufView.byteOffset; const auto *src = reinterpret_cast<const glm::vec3 *>(&(model.buffers[posBufView.buffer].data[offsetByte])); size_t vertexSize = posAccr.count; for (uint32_t i = 0; i < vertexSize; i++) { geo.positions.emplace_back(src[i]); } //indices const auto &indexAccr = model.accessors[primitive.indices]; const auto &indexBufView = model.bufferViews[indexAccr.bufferView]; size_t indexOffsetByte = indexAccr.byteOffset + indexBufView.byteOffset; const auto *indexSrc = reinterpret_cast<const uint16_t *>(&(model.buffers[indexBufView.buffer].data[indexOffsetByte])); for (uint32_t i = 0; i < indexAccr.count; i++) geo.indices.emplace_back((uint32_t) indexSrc[i]); } //texture coord if (std::regex_search(attName, std::regex("texcoord", std::regex::icase))) { const auto &tcAccr = model.accessors[attr.second]; const auto &tcBufView = model.bufferViews[tcAccr.bufferView]; size_t offsetByte = tcAccr.byteOffset + tcBufView.byteOffset; const auto *tcSrc = reinterpret_cast<const glm::vec2 *>(&model.buffers[tcBufView.buffer].data[offsetByte]); for (uint32_t i = 0; i < tcAccr.count; i++) geo.texCoords.emplace_back(tcSrc[i]); } //joint information if(std::regex_search(attName, std::regex("joint", std::regex::icase))){ const auto& jointAccr = model.accessors[attr.second]; const auto& jointBufView = model.bufferViews[jointAccr.bufferView]; size_t offsetByte = jointAccr.byteOffset + jointBufView.byteOffset; //in case of acc.componentType = TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE jointSrc = reinterpret_cast<const uint8_t*>(&model.buffers[jointBufView.buffer].data[offsetByte]); for(uint32_t i = 0; i < jointAccr.count; i++){ uint32_t index = i * 4; glm::uvec4 u(jointSrc[index], jointSrc[index + 1], jointSrc[index + 2], jointSrc[index + 3]); tmpJoint.emplace_back(u); } } //weight information if(std::regex_search(attName, std::regex("weight", std::regex::icase))){ const auto& weightAccr = model.accessors[attr.second]; const auto& weightBufView = model.bufferViews[weightAccr.bufferView]; size_t offsetByte = weightAccr.byteOffset + weightBufView.byteOffset; weightSrc = reinterpret_cast<const glm::vec4*>(&model.buffers[weightBufView.buffer].data[offsetByte]); for(uint32_t i = 0; i < weightAccr.count; i++) tmpWeight.emplace_back(weightSrc[i]); } } mGeometries.emplace_back(geo); }