Redesign gfx::mesh: stores primitive type, supports loading from pointers & simplices (deduces primitive type in the latter case)
This commit is contained in:
parent
5d44efa2ea
commit
8877f6dedd
2 changed files with 137 additions and 18 deletions
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include <psemek/geom/vector.hpp>
|
||||
#include <psemek/geom/point.hpp>
|
||||
#include <psemek/geom/simplex.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
|
|
@ -277,23 +278,75 @@ namespace psemek::gfx
|
|||
}
|
||||
|
||||
template <typename Vertex>
|
||||
void load(std::vector<Vertex> const & vertices, GLenum usage = gl::STREAM_DRAW)
|
||||
void load(Vertex const * vertices, std::size_t count, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
if (sizeof(Vertex) != stride_)
|
||||
throw std::runtime_error("Vertex size not equal to sum of attribute sizes");
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), usage);
|
||||
switch (primitive_type)
|
||||
{
|
||||
case gl::LINES:
|
||||
if ((count % 2) != 0) throw std::runtime_error("Vertex count for GL_LINES should be a multiple of 2");
|
||||
break;
|
||||
case gl::TRIANGLES:
|
||||
if ((count % 3) != 0) throw std::runtime_error("Vertex count for GL_TRIANGLES should be a multiple of 3");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
count_ = vertices.size();
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, count * sizeof(Vertex), vertices, usage);
|
||||
|
||||
count_ = count;
|
||||
primitive_type_ = primitive_type;
|
||||
}
|
||||
|
||||
void draw(GLenum mode) const
|
||||
template <typename Vertex>
|
||||
void load(std::vector<Vertex> const & vertices, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
load(vertices.data(), vertices.size(), primitive_type, usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, std::size_t N>
|
||||
void load(geom::simplex<Vertex, N> const * simplices, std::size_t count, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
static_assert(sizeof(geom::simplex<Vertex, N>) == (N + 1) * sizeof(Vertex));
|
||||
|
||||
GLenum primitive_type;
|
||||
|
||||
if constexpr (N == 0)
|
||||
{
|
||||
primitive_type = gl::POINTS;
|
||||
}
|
||||
else if constexpr (N == 1)
|
||||
{
|
||||
primitive_type = gl::LINES;
|
||||
}
|
||||
else if constexpr (N == 2)
|
||||
{
|
||||
primitive_type = gl::TRIANGLES;
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert("unknown primitive type");
|
||||
}
|
||||
|
||||
load(reinterpret_cast<Vertex const *>(simplices), count * (N + 1), primitive_type, usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, std::size_t N>
|
||||
void load(std::vector<geom::simplex<Vertex, N>> const & simplices, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
load(simplices.data(), simplices.size(), usage);
|
||||
}
|
||||
|
||||
void draw() const
|
||||
{
|
||||
if (count_ == 0) return;
|
||||
|
||||
gl::BindVertexArray(array_);
|
||||
gl::DrawArrays(mode, 0, count_);
|
||||
gl::DrawArrays(primitive_type_, 0, count_);
|
||||
}
|
||||
|
||||
GLsizei count() const
|
||||
|
|
@ -301,6 +354,11 @@ namespace psemek::gfx
|
|||
return count_;
|
||||
}
|
||||
|
||||
GLenum primitive_type() const
|
||||
{
|
||||
return primitive_type_;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint array_;
|
||||
GLuint buffer_;
|
||||
|
|
@ -309,6 +367,8 @@ namespace psemek::gfx
|
|||
|
||||
std::size_t stride_ = 0;
|
||||
|
||||
GLenum primitive_type_;
|
||||
|
||||
mesh(int);
|
||||
};
|
||||
|
||||
|
|
@ -337,26 +397,78 @@ namespace psemek::gfx
|
|||
}
|
||||
|
||||
template <typename Vertex, typename Index>
|
||||
void load(std::vector<Vertex> const & vertices, std::vector<Index> const & indices, GLenum usage = gl::STREAM_DRAW)
|
||||
void load(Vertex const * vertices, std::size_t vertex_count, Index const * indices, std::size_t index_count, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
if (sizeof(Vertex) != stride_)
|
||||
throw std::runtime_error("Vertex size not equal to sum of attribute sizes");
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), usage);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, index_buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, indices.size() * sizeof(Index), indices.data(), usage);
|
||||
switch (primitive_type)
|
||||
{
|
||||
case gl::LINES:
|
||||
if ((index_count % 2) != 0) throw std::runtime_error("Index count for GL_LINES should be a multiple of 2");
|
||||
break;
|
||||
case gl::TRIANGLES:
|
||||
if ((index_count % 3) != 0) throw std::runtime_error("Index count for GL_TRIANGLES should be a multiple of 3");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
count_ = indices.size();
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, vertex_count * sizeof(Vertex), vertices, usage);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, index_buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, index_count * sizeof(Index), indices, usage);
|
||||
|
||||
count_ = index_count;
|
||||
index_type_ = detail::gl_type_v<Index>;
|
||||
primitive_type_ = primitive_type;
|
||||
}
|
||||
|
||||
void draw(GLenum mode) const
|
||||
template <typename Vertex, typename Index>
|
||||
void load(std::vector<Vertex> const & vertices, std::vector<Index> const & indices, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
load(vertices.data(), vertices.size(), indices.data(), indices.size(), primitive_type, usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, std::size_t N, typename Index>
|
||||
void load(geom::simplex<Vertex, N> const * simplices, std::size_t simplex_count, Index const * indices, std::size_t index_count, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
static_assert(sizeof(geom::simplex<Vertex, N>) == (N + 1) * sizeof(Vertex));
|
||||
|
||||
GLenum primitive_type;
|
||||
|
||||
if constexpr (N == 0)
|
||||
{
|
||||
primitive_type = gl::POINTS;
|
||||
}
|
||||
else if constexpr (N == 1)
|
||||
{
|
||||
primitive_type = gl::LINES;
|
||||
}
|
||||
else if constexpr (N == 2)
|
||||
{
|
||||
primitive_type = gl::TRIANGLES;
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert("unknown primitive type");
|
||||
}
|
||||
|
||||
load(reinterpret_cast<Vertex const *>(simplices), simplex_count * (N + 1), indices, index_count, primitive_type, usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, std::size_t N, typename Index>
|
||||
void load(std::vector<geom::simplex<Vertex, N>> const & simplices, std::vector<Index> const & indices, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
load(simplices.data(), simplices.size(), indices.data(), indices.size(), usage);
|
||||
}
|
||||
|
||||
void draw() const
|
||||
{
|
||||
if (count_ == 0) return;
|
||||
|
||||
gl::BindVertexArray(array_);
|
||||
gl::DrawElements(mode, count_, index_type_, nullptr);
|
||||
gl::DrawElements(primitive_type_, count_, index_type_, nullptr);
|
||||
}
|
||||
|
||||
GLsizei count() const
|
||||
|
|
@ -364,6 +476,11 @@ namespace psemek::gfx
|
|||
return count_;
|
||||
}
|
||||
|
||||
GLenum primitive_type() const
|
||||
{
|
||||
return primitive_type_;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint array_;
|
||||
GLuint buffer_;
|
||||
|
|
@ -374,6 +491,8 @@ namespace psemek::gfx
|
|||
|
||||
std::size_t stride_ = 0;
|
||||
|
||||
GLenum primitive_type_;
|
||||
|
||||
indexed_mesh(int);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -424,24 +424,24 @@ namespace psemek::gfx
|
|||
|
||||
void painter::render(geom::matrix<float, 4, 4> const & transform)
|
||||
{
|
||||
impl().mesh.load(impl().vertices, impl().indices, gl::STREAM_DRAW);
|
||||
impl().mesh.load(impl().vertices, impl().indices, gl::TRIANGLES, gl::STREAM_DRAW);
|
||||
impl().vertices.clear();
|
||||
impl().indices.clear();
|
||||
|
||||
impl().text_mesh.load(impl().text_vertices, impl().text_indices, gl::STREAM_DRAW);
|
||||
impl().text_mesh.load(impl().text_vertices, impl().text_indices, gl::TRIANGLES, gl::STREAM_DRAW);
|
||||
impl().text_vertices.clear();
|
||||
impl().text_indices.clear();
|
||||
|
||||
impl().program.bind();
|
||||
impl().program["u_transform"] = transform;
|
||||
impl().mesh.draw(gl::TRIANGLES);
|
||||
impl().mesh.draw();
|
||||
|
||||
impl().text_program.bind();
|
||||
impl().text_program["u_transform"] = transform;
|
||||
impl().text_program["u_texture"] = 0;
|
||||
impl().text_program["u_texture_size"] = impl().font_texture.size();
|
||||
impl().font_texture.bind();
|
||||
impl().text_mesh.draw(gl::TRIANGLES);
|
||||
impl().text_mesh.draw();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue