Implement Mesh partitioning
This commit is contained in:
45
src/mesh.cpp
45
src/mesh.cpp
@@ -7,7 +7,8 @@ namespace Fan
|
||||
{
|
||||
|
||||
Rc<Mesh> Mesh::create(const std::vector<Vertex>& vertices,
|
||||
const std::vector<GLuint>& indices/* = {}*/)
|
||||
const std::vector<GLuint>& indices/* = {}*/,
|
||||
const std::vector<SubMesh>& submeshes/* = {}*/)
|
||||
{
|
||||
GLuint VBO{}, VAO{}, EBO{};
|
||||
bool has_indices = !indices.empty();
|
||||
@@ -38,7 +39,18 @@ Rc<Mesh> Mesh::create(const std::vector<Vertex>& vertices,
|
||||
glEnableVertexAttribArray(1);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
return make_rc<Mesh>(vertices, indices, has_indices, VBO, VAO, EBO);
|
||||
// Submesh setup
|
||||
std::vector<SubMesh> final_submeshes = submeshes;
|
||||
|
||||
// If no submeshes were explicitly defined, create one default submesh spanning the entire mesh
|
||||
if (final_submeshes.empty()) {
|
||||
SubMesh default_submesh{};
|
||||
default_submesh.index_offset = 0;
|
||||
default_submesh.index_count = indices.empty() ? vertices.size() : indices.size();
|
||||
final_submeshes.push_back(default_submesh);
|
||||
}
|
||||
|
||||
return make_rc<Mesh>(vertices, indices, final_submeshes, has_indices, VBO, VAO, EBO);
|
||||
}
|
||||
|
||||
Mesh::~Mesh()
|
||||
@@ -51,6 +63,7 @@ Mesh::~Mesh()
|
||||
Mesh::Mesh(Mesh&& other) noexcept
|
||||
: m_vertices(std::move(other.m_vertices))
|
||||
, m_indices(std::move(other.m_indices))
|
||||
, m_submeshes(std::move(other.m_submeshes))
|
||||
, m_has_indices(std::exchange(other.m_has_indices, false))
|
||||
, m_VBO(std::exchange(other.m_VBO, 0))
|
||||
, m_VAO(std::exchange(other.m_VAO, 0))
|
||||
@@ -64,6 +77,7 @@ Mesh& Mesh::operator=(Mesh&& other) noexcept
|
||||
|
||||
std::swap(m_vertices, other.m_vertices);
|
||||
std::swap(m_indices, other.m_indices);
|
||||
std::swap(m_submeshes, other.m_submeshes);
|
||||
std::swap(m_has_indices, other.m_has_indices);
|
||||
std::swap(m_VBO, other.m_VBO);
|
||||
std::swap(m_VAO, other.m_VAO);
|
||||
@@ -72,15 +86,34 @@ Mesh& Mesh::operator=(Mesh&& other) noexcept
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::vector<Mesh::SubMesh>& Mesh::get_submeshes() const
|
||||
{
|
||||
return m_submeshes;
|
||||
}
|
||||
|
||||
void Mesh::draw() const
|
||||
{
|
||||
glBindVertexArray(m_VAO);
|
||||
|
||||
if (m_has_indices) {
|
||||
glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, 0);
|
||||
} else {
|
||||
glDrawArrays(GL_TRIANGLES, 0, m_vertices.size());
|
||||
for (const auto& submesh : m_submeshes) {
|
||||
draw_submesh(submesh.index_offset, submesh.index_count);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void Mesh::draw_submesh(GLuint index_offset, GLuint index_count) const
|
||||
{
|
||||
glBindVertexArray(m_VAO);
|
||||
|
||||
if (m_has_indices) {
|
||||
glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT,
|
||||
reinterpret_cast<const void*>(index_offset * sizeof(GLuint)));
|
||||
} else {
|
||||
glDrawArrays(GL_TRIANGLES, index_offset, index_count);
|
||||
}
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
} // namespace Fan
|
||||
|
||||
Reference in New Issue
Block a user