67 lines
2 KiB
C++
67 lines
2 KiB
C++
#include <psemek/gfx/gltf_mesh.hpp>
|
|
|
|
#include <stdexcept>
|
|
|
|
namespace psemek::gfx
|
|
{
|
|
|
|
void gltf_mesh::mesh::primitive::draw() const
|
|
{
|
|
vao.bind();
|
|
gl::DrawElements(gl::TRIANGLES, index_count, index_type, reinterpret_cast<void const *>(index_offset));
|
|
}
|
|
|
|
gltf_mesh::gltf_mesh(gltf_asset const & asset, std::vector<util::span<char const>> const & buffers)
|
|
{
|
|
if (buffers.size() != asset.buffers.size())
|
|
throw std::runtime_error("wrong number of glTF buffers");
|
|
|
|
for (auto buffer : buffers)
|
|
this->buffers.emplace_back().load(buffer.data(), buffer.size(), gl::STATIC_DRAW);
|
|
|
|
for (auto const & node : asset.nodes)
|
|
{
|
|
auto & target_mesh = meshes[node.name];
|
|
|
|
auto const & mesh = asset.meshes[node.mesh];
|
|
|
|
for (auto const & primitive : mesh.primitives)
|
|
{
|
|
auto & target_primitive = target_mesh.primitives.emplace_back();
|
|
target_primitive.material = primitive.material;
|
|
|
|
target_primitive.vao.bind();
|
|
|
|
{
|
|
auto const & indices_accessor = asset.accessors[primitive.indices];
|
|
auto const & indices_view = asset.buffer_views[indices_accessor.buffer_view];
|
|
|
|
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, this->buffers[indices_view.buffer].id());
|
|
target_primitive.index_offset = indices_view.offset;
|
|
target_primitive.index_type = indices_accessor.component_type;
|
|
target_primitive.index_count = indices_accessor.count;
|
|
}
|
|
|
|
std::pair<GLuint, std::optional<std::size_t>> attributes[3] =
|
|
{
|
|
{0, primitive.position},
|
|
{1, primitive.normal},
|
|
{2, primitive.texcoord},
|
|
};
|
|
|
|
for (auto const & attribute : attributes)
|
|
{
|
|
if (!attribute.second) continue;
|
|
|
|
auto const & accessor = asset.accessors[*attribute.second];
|
|
auto const & view = asset.buffer_views[accessor.buffer_view];
|
|
|
|
gl::BindBuffer(gl::ARRAY_BUFFER, this->buffers[view.buffer].id());
|
|
gl::EnableVertexAttribArray(attribute.first);
|
|
gl::VertexAttribPointer(attribute.first, accessor.type, accessor.component_type, accessor.normalized, 0, reinterpret_cast<void const *>(view.offset));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|