From d1b6b3a5aaf55ea50984c52594941462cee26e1b Mon Sep 17 00:00:00 2001 From: Dov Grobgeld Date: Fri, 26 Feb 2021 09:30:05 +0200 Subject: [PATCH] Add example for creating a triangle gltf file from scratch --- examples/build-gltf/create_triangle_gltf.cpp | 121 +++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 examples/build-gltf/create_triangle_gltf.cpp diff --git a/examples/build-gltf/create_triangle_gltf.cpp b/examples/build-gltf/create_triangle_gltf.cpp new file mode 100644 index 0000000..be92981 --- /dev/null +++ b/examples/build-gltf/create_triangle_gltf.cpp @@ -0,0 +1,121 @@ +// An example of how to generate a gltf file from scratch. This example +// was translated from the pygltlib documentation in the pypi project page, +// which in turn is based on the Khronos Sample Models at: +// +// https://github.com/KhronosGroup/glTF-Sample-Models +// +// This example is released under the MIT license. +// +// 2021-02-25 Thu +// Dov Grobgeld + + +// Define these only in *one* .cc file. +#define TINYGLTF_IMPLEMENTATION +#define STB_IMAGE_IMPLEMENTATION +#define STB_IMAGE_WRITE_IMPLEMENTATION + +// #define TINYGLTF_NOEXCEPTION // optional. disable exception handling. +#include "tiny_gltf.h" + +int main(int argc, char **argv) +{ + // Create a model with a single mesh and save it as a gltf file + tinygltf::Model m; + tinygltf::Scene scene; + tinygltf::Mesh mesh; + tinygltf::Primitive primitive; + tinygltf::Node node; + tinygltf::Buffer buffer; + tinygltf::BufferView bufferView1; + tinygltf::BufferView bufferView2; + tinygltf::Accessor accessor1; + tinygltf::Accessor accessor2; + tinygltf::Asset asset; + + // This is the raw data buffer. + buffer.data = { + // 6 bytes of indices and two bytes of padding + 0x00,0x00,0x01,0x00,0x02,0x00,0x00,0x00, + // 36 bytes of floating point numbers + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f, + 0x00,0x00,0x00,0x00}; + + // "The indices of the vertices (ELEMENT_ARRAY_BUFFER) take up 6 bytes in the + // start of the buffer. + bufferView1.buffer = 0; + bufferView1.byteOffset=0; + bufferView1.byteLength=6; + bufferView1.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; + + // The vertices take up 36 bytes (3 vertices * 3 floating points * 4 bytes) + // at position 8 in the buffer and are of type ARRAY_BUFFER + bufferView2.buffer = 0; + bufferView2.byteOffset=8; + bufferView2.byteLength=36; + bufferView2.target = TINYGLTF_TARGET_ARRAY_BUFFER; + + // Describe the layout of bufferView1, the indices of the vertices + accessor1.bufferView = 0; + accessor1.byteOffset = 0; + accessor1.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT; + accessor1.count = 3; + accessor1.type = TINYGLTF_TYPE_SCALAR; + accessor1.maxValues.push_back(2); + accessor1.minValues.push_back(0); + + // Describe the layout of bufferView2, the vertices themself + accessor2.bufferView = 1; + accessor2.byteOffset = 0; + accessor2.componentType = TINYGLTF_COMPONENT_TYPE_FLOAT; + accessor2.count = 3; + accessor2.type = TINYGLTF_TYPE_VEC3; + accessor2.maxValues = {1.0, 1.0, 0.0}; + accessor2.minValues = {0.0, 0.0, 0.0}; + + // Build the mesh primitive and add it to the mesh + primitive.indices = 0; // The index of the accessor for the vertex indices + primitive.attributes["POSITION"] = 1; // The index of the accessor for positions + primitive.material = 0; + primitive.mode = TINYGLTF_MODE_TRIANGLES; + mesh.primitives.push_back(primitive); + + // Other tie ups + node.mesh = 0; + scene.nodes.push_back(0); // Default scene + + // Define the asset. The version is required + asset.version = "2.0"; + asset.generator = "tinygltf"; + + // Now all that remains is to tie back all the loose objects into the + // our single model. + m.scenes.push_back(scene); + m.meshes.push_back(mesh); + m.nodes.push_back(node); + m.buffers.push_back(buffer); + m.bufferViews.push_back(bufferView1); + m.bufferViews.push_back(bufferView2); + m.accessors.push_back(accessor1); + m.accessors.push_back(accessor2); + m.asset = asset; + + // Create a simple material + tinygltf::Material mat; + mat.pbrMetallicRoughness.baseColorFactor = {1.0f, 0.9f, 0.9f, 1.0f}; + mat.doubleSided = true; + m.materials.push_back(mat); + + // Save it to a file + tinygltf::TinyGLTF gltf; + gltf.WriteGltfSceneToFile(&m, "triangle.gltf", + true, // embedImages + true, // embedBuffers + true, // pretty print + false); // write binary + + exit(0); +}