Giter VIP home page Giter VIP logo

Comments (2)

jessey-git avatar jessey-git commented on September 28, 2024

Alright here goes. It's not really that simple -- partly because the glTF spec defines a rather large hierarchy of things that need to be present and partly because c++ doesn't have nice aggregate initialization yet.

In addition to those 2 things, remember that the buffer in question is basically a raw buffer of bytes -- c++ does not make it easy to serialize floats/ints into bytes so we'll have to write something ourselves.

First let's make some helpers:

struct vec3
{
    float x;
    float y;
    float z;
};

template <typename T>
uint32_t serialize(std::vector<T> const & from, std::vector<uint8_t> & to, std::size_t offset)
{
    uint32_t bytesToSerialize = sizeof(T) * static_cast<uint32_t>(from.size());

    to.resize(to.size() + bytesToSerialize);
    std::memcpy(&to[offset], &from[0], bytesToSerialize);

    return bytesToSerialize;
}

Main fun stuff

    // Let's create geometry for a square
    //   4 vec3's defining the vertex positions
    //   4 vec3's defining the vertex normals (all point same way)
    //   Index buffer so the gfx api knows what how to draw the 2 triangles
    std::vector<vec3> positions{ vec3{-1,0,1}, vec3{1,0,-1}, vec3{-1,0,-1}, vec3{1,0,1} };
    std::vector<vec3> normals{ vec3{0,1,0}, vec3{0,1,0}, vec3{0,1,0}, vec3{0,1,0} };
    std::vector<uint32_t> indices{ 0,1,2, 0,3,1 };

    // "Serialize" the above information into a raw byte array
    // Note: this implementation is unoptimized and potentially dangerous. Review for your
    // own projects accordingly...
    fx::gltf::Buffer buffer{};
    uint32_t indexSize = serialize(indices, buffer.data, 0);
    uint32_t positionSize = serialize(positions, buffer.data, indexSize);
    uint32_t normalSize = serialize(normals, buffer.data, indexSize + positionSize);

    // At this point our raw buffer contains 120 total bytes of information
    // It's arranged as follows: [indices | positions | normals]
    buffer.byteLength = static_cast<uint32_t>(buffer.data.size());
    buffer.SetEmbeddedResource();

    // Build the document
    fx::gltf::Document doc{};
    doc.asset.generator = "Test Generator";
    doc.asset.version = "2.0";

    doc.buffers.push_back(buffer);

    // Build the "views" into the "buffer"
    fx::gltf::BufferView indexBufferView{};
    fx::gltf::BufferView positionBufferView{};
    fx::gltf::BufferView normalBufferView{};
    indexBufferView.buffer = 0;
    indexBufferView.byteLength = indexSize;
    indexBufferView.byteOffset = 0;
    positionBufferView.buffer = 0;
    positionBufferView.byteLength = positionSize;
    positionBufferView.byteOffset = indexSize;
    normalBufferView.buffer = 0;
    normalBufferView.byteLength = normalSize;
    normalBufferView.byteOffset = indexSize + positionSize;

    doc.bufferViews.push_back(indexBufferView);
    doc.bufferViews.push_back(positionBufferView);
    doc.bufferViews.push_back(normalBufferView);

    // Now we need "accessors" to know how to interpret each of those "views"
    fx::gltf::Accessor indexAccessor{};
    fx::gltf::Accessor positionAccessor{};
    fx::gltf::Accessor normalAccessor{};
    indexAccessor.bufferView = 0;
    indexAccessor.componentType = fx::gltf::Accessor::ComponentType::UnsignedInt;
    indexAccessor.count = static_cast<uint32_t>(indices.size());
    indexAccessor.type = fx::gltf::Accessor::Type::Scalar;
    positionAccessor.bufferView = 1;
    positionAccessor.componentType = fx::gltf::Accessor::ComponentType::Float;
    positionAccessor.count = static_cast<uint32_t>(positions.size());
    positionAccessor.type = fx::gltf::Accessor::Type::Vec3;
    normalAccessor.bufferView = 2;
    normalAccessor.componentType = fx::gltf::Accessor::ComponentType::Float;
    normalAccessor.count = static_cast<uint32_t>(normals.size());
    normalAccessor.type = fx::gltf::Accessor::Type::Vec3;

    // My viewer requires min/max (shame)
    indexAccessor.min = { 0 };
    indexAccessor.max = { 3 };
    positionAccessor.min = { -1, 0, -1 };
    positionAccessor.max = { 1, 0, 1 };
    normalAccessor.min = { 0, 1, 0 };
    normalAccessor.max = { 0, 1, 0 };

    doc.accessors.push_back(indexAccessor);
    doc.accessors.push_back(positionAccessor);
    doc.accessors.push_back(normalAccessor);

    // We need "meshes" to describe how to assemble the darn thing...
    fx::gltf::Mesh squareMesh{};
    fx::gltf::Primitive squarePrimitive{};
    squareMesh.name = "SampleSquare";
    squarePrimitive.indices = 0;  // accessor 0
    squarePrimitive.attributes["POSITION"] = 1;  // accessor 1
    squarePrimitive.attributes["NORMAL"] = 2;  // accessor 2
    squareMesh.primitives.push_back(squarePrimitive);

    doc.meshes.push_back(squareMesh);

    // We need "nodes" to list what "meshes" to use...
    fx::gltf::Node node{};
    node.mesh = 0;

    doc.nodes.push_back(node);

    // We need a "scene" to list what "nodes" to use...
    fx::gltf::Scene scene{};
    scene.nodes.push_back(0);

    doc.scenes.push_back(scene);
    doc.scene = 0;

    // Simple right?
    fx::gltf::Save(doc, "square.gltf", false);

Edit 2019-02-09: Simplified the setting of min/max accessor values

from fx-gltf.

jessey-git avatar jessey-git commented on September 28, 2024

No response after 6 months. Closing.

from fx-gltf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.