Make gfx::load_mesh return structured data instead of a tuple

This commit is contained in:
Nikita Lisitsa 2021-07-11 11:38:00 +03:00
parent e831eb8567
commit 39855a5d84
2 changed files with 46 additions and 11 deletions

View file

@ -96,6 +96,8 @@ namespace psemek::gfx
}
struct imported_mesh;
/* A generic mesh class
* Supports both indexed & non-indexed rendering
* Supports both instanced & non-instanced rendering
@ -154,6 +156,8 @@ namespace psemek::gfx
template <typename Vertex, typename Index, std::size_t N>
void load(std::vector<Vertex> const & vertices, std::vector<geom::simplex<Index, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
void load_raw(imported_mesh const & m);
// Index-only vertex data
template <typename Index>
@ -337,6 +341,31 @@ namespace psemek::gfx
load_instance(instances.data(), instances.size(), usage);
}
std::tuple<attribs_description, util::span<char const>, util::span<std::uint32_t const>> load_mesh(std::string_view data);
struct imported_mesh
{
attribs_description attribs;
util::span<char const> vertices;
util::span<std::uint32_t const> indices;
struct bone
{
std::uint32_t parent;
static constexpr std::uint32_t null = std::uint32_t(-1);
};
util::span<bone> bones;
struct bone_pose
{
geom::vector<float, 3> translation;
float scale;
geom::quaternion<float> rotation;
};
std::unordered_map<std::string_view, util::span<bone_pose>> poses;
};
imported_mesh load_mesh(std::string_view data);
}

View file

@ -143,6 +143,11 @@ namespace psemek::gfx
info_.index_type_ = index_type;
}
void mesh::load_raw(imported_mesh const & m)
{
load_raw(m.vertices.data(), m.attribs.vertex_size, m.vertices.size() / m.attribs.vertex_size, m.indices.data(), gl::UNSIGNED_INT, m.indices.size(), gl::TRIANGLES, gl::STATIC_DRAW);
}
void mesh::draw() const
{
draw(0, is_indexed() ? index_count() : vertex_count(), instance_count());
@ -198,7 +203,7 @@ namespace psemek::gfx
}
}
std::tuple<attribs_description, util::span<char const>, util::span<std::uint32_t const>> load_mesh(std::string_view data)
imported_mesh load_mesh(std::string_view data)
{
// These should be in sync with convert-mesh.py
static std::uint32_t const POSITION_MASK = 1;
@ -208,31 +213,32 @@ namespace psemek::gfx
util::binary_istream s{data};
imported_mesh result;
auto vertex_format = s.read<std::uint32_t>();
attribs_description attrs;
if (vertex_format & POSITION_MASK)
attrs += make_attribs_description<geom::point<float, 3>>();
result.attribs += make_attribs_description<geom::point<float, 3>>();
if (vertex_format & NORMALS_MASK)
attrs += make_attribs_description<geom::vector<float, 3>>();
result.attribs += make_attribs_description<geom::vector<float, 3>>();
if (vertex_format & COLORS_MASK)
attrs += make_attribs_description<gfx::normalized<geom::vector<std::uint8_t, 4>>>();
result.attribs += make_attribs_description<gfx::normalized<geom::vector<std::uint8_t, 4>>>();
if (vertex_format & TEXCOORDS_MASK)
attrs += make_attribs_description<geom::vector<float, 2>>();
result.attribs += make_attribs_description<geom::vector<float, 2>>();
auto vertex_count = s.read<std::uint32_t>();
auto vertex_ptr = s.read_raw(vertex_count * attrs.vertex_size);
auto vertex_ptr = s.read_raw(vertex_count * result.attribs.vertex_size);
auto index_count = s.read<std::uint32_t>();
auto index_ptr = reinterpret_cast<std::uint32_t const *>(s.read_raw(index_count * sizeof(std::uint32_t)));
util::span<char const> vertices{vertex_ptr, vertex_ptr + vertex_count * attrs.vertex_size};
util::span<std::uint32_t const> indices{index_ptr, index_ptr + index_count};
result.vertices = {vertex_ptr, vertex_ptr + vertex_count * result.attribs.vertex_size};
result.indices = {index_ptr, index_ptr + index_count};
return {attrs, vertices, indices};
return result;
}
}