当前位置:   article > 正文

OpenGL 3D渲染技术:渲染glTF模型,音视频时代你还不会NDK开发_opengl gltf shader

opengl gltf shader

“metallicFactor”: 0.0
},
“name”: “Texture”
}
],
“textures”: [
{
“sampler”: 0,
“source”: 0
}
],
“images”: [
{
“uri”: “CesiumLogoFlat.png”
}
],
“samplers”: [
{
“magFilter”: 9729,
“minFilter”: 9986,
“wrapS”: 10497,
“wrapT”: 10497
}
],
“bufferViews”: [
{
“buffer”: 0,
“byteOffset”: 768,
“byteLength”: 72,
“target”: 34963
},
{
“buffer”: 0,
“byteOffset”: 0,
“byteLength”: 576,
“byteStride”: 12,
“target”: 34962
},
{
“buffer”: 0,
“byteOffset”: 576,
“byteLength”: 192,
“byteStride”: 8,
“target”: 34962
}
],
“buffers”: [
{
“byteLength”: 840,
“uri”: “BoxTextured0.bin”
}
]
}

下面我们来打造一个小型3D引擎来渲染它,其中的类名和作用保持和glTF中的一致,主要有EngineSceneNodeMeshPrimitiveMaterial

glTF模型解析

glTF模型的解析有一些开源库可以使用,这里我们使用tinygltf这个库,这个库挺好用的,很小巧,接入简单,我们先来看一下解析代码:

void Engine::loadGLTF(const std::string &path) {
tinygltf::TinyGLTF loader;
std::string err;
std::string warn;
loader.LoadASCIIFromFile(&model_, &err, &warn, path);
}

解析后会得到一个tinygltf::Model,里面的成员变量的名字和层级与glTF里的保持一致,用起来非常友好,并且还包括了bin数据读取、图片数据读取,而不仅仅是字段的解析,连数据都帮你读好了。

数据加载

有了model之后,我们来根据这个model里的数据创建相应的GL资源备用。

我们先来看buffer

“buffers”: [
{
“byteLength”: 840,
“uri”: “BoxTextured0.bin”
}
]

在这个立方体模型中,只有一个buffer,我们来把它加载到GL buffer中去,也就是常说的vbo

std::shared_ptr<std::vector>
Engine::buildBuffers(const tinygltf::Model &model) {
auto buffers = std::make_shared<std::vector>(model.buffers.size(), 0);
GL_CHECK(glGenBuffers(buffers->size(), buffers->data()));
for (auto i = 0; i < model.buffers.size(); ++i) {
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, buffers->at(i)));
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, model.buffers[i].data.size(),
model.buffers[i].data.data(), GL_STATIC_DRAW));
}
GL_CHECK(glBindBuffer(GL_ARRAY_BUFFER, 0));
return buffers;
}

这里vbo里装的就是这个glTF模型所有的数值数据了,包括顶点、纹理坐标、法向量、索引等都在这了。

接下来我们来加载纹理:

std::shared_ptr<std::vector>
Engine::buildTextures(const tinygltf::Model &model) {
auto textures = std::make_shared<std::vector>(model.textures.size());
GL_CHECK(glGenTextures(textures->size(), textures->data()));
for (auto i = 0; i < textures->size(); ++i) {
GL_CHECK(glBindTexture(GL_TEXTURE_2D, textures->at(i)));
const auto &texture = model.textures[i];
const auto &image = model.images[texture.source];
auto minFilter =
texture.sampler >= 0 && model.samplers[texture.sampler].minFilter != -1
? model.samplers[texture.sampler].minFilter
: GL_LINEAR;
auto magFilter =
texture.sampler >= 0 && model.samplers[texture.sampler].magFilter != -1
? model.samplers[texture.sampler].magFilter
: GL_LINEAR;
auto wrapS =

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/665017
推荐阅读
相关标签
  

闽ICP备14008679号