Refactor meshes: single unified mesh class
This commit is contained in:
parent
726b8486c7
commit
e9af93b747
8 changed files with 294 additions and 818 deletions
|
|
@ -173,9 +173,9 @@ struct cloud_app
|
|||
std::vector<geom::point<float, 3>> bbox_vertices;
|
||||
std::vector<geom::segment<std::uint32_t>> bbox_edges;
|
||||
|
||||
gfx::indexed_mesh bbox_mesh;
|
||||
gfx::mesh bbox_mesh;
|
||||
|
||||
gfx::indexed_mesh slice_mesh;
|
||||
gfx::mesh slice_mesh;
|
||||
|
||||
gfx::mesh light_mesh;
|
||||
std::vector<geom::vector<float, 3>> dirs;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ private:
|
|||
|
||||
gfx::program program_{vertex_source, fragment_source};
|
||||
|
||||
gfx::instanced_mesh mesh_;
|
||||
gfx::mesh mesh_;
|
||||
|
||||
gfx::texture_2d texture_;
|
||||
gfx::texture_2d noise_texture_;
|
||||
|
|
@ -229,7 +229,6 @@ void candle_renderer::render(geom::camera const & camera, float time)
|
|||
texture_.bind();
|
||||
gl::ActiveTexture(gl::TEXTURE1);
|
||||
noise_texture_.bind();
|
||||
(void)time;
|
||||
mesh_.draw();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ struct grass_app
|
|||
pcg::perlin<float, 2> density;
|
||||
|
||||
gfx::program ground_program{ground_vs, ground_fs};
|
||||
gfx::indexed_mesh ground_mesh;
|
||||
gfx::mesh ground_mesh;
|
||||
|
||||
gfx::program grass_program{grass_vs, grass_fs};
|
||||
gfx::indexed_mesh grass_mesh;
|
||||
gfx::mesh grass_mesh;
|
||||
gfx::texture_1d grass_texture;
|
||||
|
||||
gfx::program grass_slice_program{grass_slice_vs, grass_slice_fs};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
indexed_mesh const & fullscreen_quad();
|
||||
mesh const & fullscreen_quad();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include <psemek/gfx/gl.hpp>
|
||||
#include <psemek/gfx/drawable.hpp>
|
||||
#include <psemek/gfx/array.hpp>
|
||||
#include <psemek/gfx/buffer.hpp>
|
||||
|
||||
#include <psemek/geom/vector.hpp>
|
||||
#include <psemek/geom/point.hpp>
|
||||
|
|
@ -386,10 +388,7 @@ namespace psemek::gfx
|
|||
template <typename T>
|
||||
static constexpr GLenum gl_type_v = gl_type<T>::value;
|
||||
|
||||
void check_vertex_size(std::size_t vertex_size, std::size_t stride);
|
||||
void check_instance_size(std::size_t instance_size, std::size_t stride);
|
||||
|
||||
static std::size_t index_size(GLenum type)
|
||||
inline std::size_t index_size(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
|
@ -401,573 +400,277 @@ namespace psemek::gfx
|
|||
return 0;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
GLenum get_primitive_type()
|
||||
{
|
||||
if constexpr (N == 0)
|
||||
{
|
||||
return gl::POINTS;
|
||||
}
|
||||
else if constexpr (N == 1)
|
||||
{
|
||||
return gl::LINES;
|
||||
}
|
||||
else if constexpr (N == 2)
|
||||
{
|
||||
return gl::TRIANGLES;
|
||||
}
|
||||
else
|
||||
{
|
||||
static_assert("unknown primitive type");
|
||||
}
|
||||
}
|
||||
|
||||
inline std::optional<std::size_t> get_primitive_type_vertex_count(GLenum type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case gl::LINES:
|
||||
return 2;
|
||||
case gl::TRIANGLES:
|
||||
return 3;
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ... Args>
|
||||
struct has_instanced_attribs_impl
|
||||
: std::false_type
|
||||
{};
|
||||
|
||||
template <typename T, typename ... Args>
|
||||
struct has_instanced_attribs_impl<T, Args...>
|
||||
: has_instanced_attribs_impl<Args...>
|
||||
{};
|
||||
|
||||
template <typename T, typename ... Args>
|
||||
struct has_instanced_attribs_impl<instanced<T>, Args...>
|
||||
: std::true_type
|
||||
{};
|
||||
|
||||
template <typename ... Args>
|
||||
constexpr bool has_instanced_attribs = has_instanced_attribs_impl<Args...>::value;
|
||||
}
|
||||
|
||||
/* A generic mesh class
|
||||
* Supports both indexed & non-indexed rendering
|
||||
* Supports both instanced & non-instanced rendering
|
||||
* Checks vertex & instance size, may throw on load
|
||||
* Strong exception guarantees
|
||||
*/
|
||||
|
||||
struct mesh
|
||||
: drawable
|
||||
{
|
||||
static mesh null();
|
||||
|
||||
mesh();
|
||||
mesh() = default;
|
||||
mesh(mesh &&);
|
||||
mesh(mesh const &) = delete;
|
||||
|
||||
mesh & operator = (mesh &&);
|
||||
|
||||
mesh(mesh const &) = delete;
|
||||
mesh & operator = (mesh const &) = delete;
|
||||
|
||||
~mesh();
|
||||
|
||||
template <typename ... Attribs>
|
||||
void setup()
|
||||
{
|
||||
gl::BindVertexArray(array_);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
void setup();
|
||||
|
||||
stride_ = detail::mesh_setup<Attribs...>::setup();
|
||||
}
|
||||
// Non-indexed vertex data
|
||||
|
||||
template <typename Vertex>
|
||||
void load(Vertex const * vertices, std::size_t count, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
detail::check_vertex_size(sizeof(Vertex), stride_);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, count * sizeof(Vertex), vertices, usage);
|
||||
|
||||
count_ = count;
|
||||
primitive_type_ = primitive_type;
|
||||
}
|
||||
void load(Vertex const * vertices, std::size_t count, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
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);
|
||||
}
|
||||
void load(std::vector<Vertex> const & vertices, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
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);
|
||||
}
|
||||
void load(geom::simplex<Vertex, N> const * simplices, std::size_t count, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
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 load(std::vector<geom::simplex<Vertex, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
void draw() const override
|
||||
{
|
||||
draw(0, count_);
|
||||
}
|
||||
|
||||
void draw(GLsizei first, GLsizei count) const
|
||||
{
|
||||
assert(first + count <= count_);
|
||||
|
||||
if (count == 0) return;
|
||||
|
||||
gl::BindVertexArray(array_);
|
||||
gl::DrawArrays(primitive_type_, first, count);
|
||||
}
|
||||
|
||||
GLsizei count() const
|
||||
{
|
||||
return count_;
|
||||
}
|
||||
|
||||
GLenum primitive_type() const
|
||||
{
|
||||
return primitive_type_;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint array_;
|
||||
GLuint buffer_;
|
||||
|
||||
GLsizei count_ = 0;
|
||||
|
||||
std::size_t stride_ = 0;
|
||||
|
||||
GLenum primitive_type_;
|
||||
|
||||
mesh(int);
|
||||
};
|
||||
|
||||
struct indexed_mesh
|
||||
: drawable
|
||||
{
|
||||
static indexed_mesh null();
|
||||
|
||||
indexed_mesh();
|
||||
indexed_mesh(indexed_mesh &&);
|
||||
indexed_mesh(indexed_mesh const &) = delete;
|
||||
|
||||
indexed_mesh & operator =(indexed_mesh &&);
|
||||
indexed_mesh & operator =(indexed_mesh const &) = delete;
|
||||
|
||||
~indexed_mesh();
|
||||
|
||||
template <typename ... Attribs>
|
||||
void setup()
|
||||
{
|
||||
gl::BindVertexArray(array_);
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
|
||||
stride_ = detail::mesh_setup<Attribs...>::setup();
|
||||
|
||||
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, index_buffer_);
|
||||
}
|
||||
// Indexed vertex data
|
||||
|
||||
template <typename Vertex, typename Index>
|
||||
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)
|
||||
{
|
||||
detail::check_vertex_size(sizeof(Vertex), stride_);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 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);
|
||||
|
||||
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);
|
||||
}
|
||||
void load(std::vector<Vertex> const & vertices, std::vector<Index> const & indices, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
template <typename Vertex, typename Index, std::size_t N>
|
||||
void load(Vertex const * vertices, std::size_t vertex_count, geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
static_assert(sizeof(geom::simplex<Index, N>) == (N + 1) * sizeof(Index));
|
||||
|
||||
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(vertices, vertex_count, reinterpret_cast<Index const *>(simplices), simplex_count * (N + 1), primitive_type, usage);
|
||||
}
|
||||
void load(Vertex const * vertices, std::size_t vertex_count, geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
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)
|
||||
{
|
||||
load(vertices.data(), vertices.size(), simplices.data(), simplices.size(), usage);
|
||||
}
|
||||
void load(std::vector<Vertex> const & vertices, std::vector<geom::simplex<Index, N>> const & simplices, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
void draw() const override
|
||||
{
|
||||
draw(0, count_);
|
||||
}
|
||||
|
||||
void draw(GLsizei first, GLsizei count) const
|
||||
{
|
||||
if (count == 0) return;
|
||||
assert(first + count <= count_);
|
||||
|
||||
gl::BindVertexArray(array_);
|
||||
gl::DrawElements(primitive_type_, count, index_type_, reinterpret_cast<char const *>(0) + first * detail::index_size(index_type_));
|
||||
}
|
||||
|
||||
GLsizei index_count() const
|
||||
{
|
||||
return count_;
|
||||
}
|
||||
|
||||
GLenum primitive_type() const
|
||||
{
|
||||
return primitive_type_;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint array_;
|
||||
GLuint buffer_;
|
||||
GLuint index_buffer_;
|
||||
|
||||
GLsizei count_ = 0;
|
||||
GLenum index_type_ = 0;
|
||||
|
||||
std::size_t stride_ = 0;
|
||||
|
||||
GLenum primitive_type_;
|
||||
|
||||
indexed_mesh(int);
|
||||
};
|
||||
|
||||
struct instanced_mesh
|
||||
: drawable
|
||||
{
|
||||
static instanced_mesh null();
|
||||
|
||||
instanced_mesh();
|
||||
instanced_mesh(instanced_mesh &&);
|
||||
instanced_mesh(instanced_mesh const &) = delete;
|
||||
|
||||
instanced_mesh & operator = (instanced_mesh &&);
|
||||
instanced_mesh & operator = (instanced_mesh const &) = delete;
|
||||
|
||||
~instanced_mesh();
|
||||
|
||||
template <typename ... Attribs>
|
||||
void setup()
|
||||
{
|
||||
gl::BindVertexArray(array_);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
stride_ = detail::instanced_mesh_vertex_setup<Attribs...>::setup();
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, instance_buffer_);
|
||||
instance_stride_ = detail::instanced_mesh_instance_setup<Attribs...>::setup();
|
||||
}
|
||||
|
||||
template <typename Vertex>
|
||||
void load(Vertex const * vertices, std::size_t count, GLenum primitive_type, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
detail::check_vertex_size(sizeof(Vertex), stride_);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, count * sizeof(Vertex), vertices, usage);
|
||||
|
||||
count_ = count;
|
||||
primitive_type_ = primitive_type;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// Instance data
|
||||
|
||||
template <typename Instance>
|
||||
void load_instance(Instance const * instances, std::size_t count, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
detail::check_instance_size(sizeof(Instance), instance_stride_);
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, instance_buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, count * sizeof(Instance), instances, usage);
|
||||
instance_count_ = count;
|
||||
}
|
||||
void load_instance(Instance const * instances, std::size_t count, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
template <typename Instance>
|
||||
void load_instance(std::vector<Instance> const & instances, GLenum usage = gl::STREAM_DRAW)
|
||||
{
|
||||
load_instance(instances.data(), instances.size(), usage);
|
||||
}
|
||||
void load_instance(std::vector<Instance> const & instances, GLenum usage = gl::STREAM_DRAW);
|
||||
|
||||
void draw() const override
|
||||
{
|
||||
draw(0, count_, instance_count_);
|
||||
}
|
||||
// Info
|
||||
|
||||
void draw(GLsizei first, GLsizei count, GLsizei instance_count) const
|
||||
{
|
||||
assert(first + count <= count_);
|
||||
assert(instance_count <= instance_count_);
|
||||
bool is_indexed() const { return info_.indexed_; }
|
||||
bool is_instanced() const { return info_.instanced_; }
|
||||
|
||||
if (count == 0) return;
|
||||
if (instance_count == 0) return;
|
||||
std::size_t vertex_count() const { return info_.vertex_count_; }
|
||||
std::size_t index_count() const { return info_.index_count_; }
|
||||
std::size_t instance_count() const { return info_.instance_count_; }
|
||||
|
||||
gl::BindVertexArray(array_);
|
||||
gl::DrawArraysInstanced(primitive_type_, first, count, instance_count);
|
||||
}
|
||||
std::size_t count() const; // total vertex count = number of vertex shader executions
|
||||
|
||||
GLsizei count() const
|
||||
{
|
||||
return count_;
|
||||
}
|
||||
GLenum primitive_type() const { return info_.primitive_type_; }
|
||||
GLenum index_type() const { return info_.index_type_; }
|
||||
|
||||
GLsizei instance_count() const
|
||||
{
|
||||
return instance_count_;
|
||||
}
|
||||
// Drawing commands
|
||||
|
||||
GLenum primitive_type() const
|
||||
{
|
||||
return primitive_type_;
|
||||
}
|
||||
void draw() const override;
|
||||
|
||||
void draw(std::size_t first, std::size_t count, std::size_t instance_count = 0) const;
|
||||
|
||||
private:
|
||||
GLuint array_;
|
||||
GLuint buffer_;
|
||||
GLuint instance_buffer_;
|
||||
array array_;
|
||||
buffer vertex_buffer_ = buffer::null();
|
||||
buffer index_buffer_ = buffer::null();
|
||||
buffer instance_buffer_ = buffer::null();
|
||||
|
||||
GLsizei count_ = 0;
|
||||
GLsizei instance_count_ = 0;
|
||||
struct mesh_info
|
||||
{
|
||||
bool indexed_ = false;
|
||||
bool instanced_ = false;
|
||||
|
||||
std::size_t vertex_count_ = 0;
|
||||
std::size_t index_count_ = 0;
|
||||
std::size_t instance_count_ = 0;
|
||||
|
||||
std::size_t stride_ = 0;
|
||||
std::size_t instance_stride_ = 0;
|
||||
|
||||
GLenum primitive_type_;
|
||||
|
||||
instanced_mesh(int);
|
||||
GLenum index_type_;
|
||||
};
|
||||
|
||||
struct instanced_indexed_mesh
|
||||
: drawable
|
||||
{
|
||||
static instanced_indexed_mesh null();
|
||||
|
||||
instanced_indexed_mesh();
|
||||
instanced_indexed_mesh(instanced_indexed_mesh &&);
|
||||
instanced_indexed_mesh(instanced_indexed_mesh const &) = delete;
|
||||
|
||||
instanced_indexed_mesh & operator = (instanced_indexed_mesh &&);
|
||||
instanced_indexed_mesh & operator = (instanced_indexed_mesh const &) = delete;
|
||||
|
||||
~instanced_indexed_mesh();
|
||||
mesh_info info_;
|
||||
};
|
||||
|
||||
template <typename ... Attribs>
|
||||
void setup()
|
||||
void mesh::setup()
|
||||
{
|
||||
gl::BindVertexArray(array_);
|
||||
array_.bind();
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, buffer_);
|
||||
stride_ = detail::instanced_mesh_vertex_setup<Attribs...>::setup();
|
||||
if (!vertex_buffer_) vertex_buffer_ = buffer{};
|
||||
vertex_buffer_.bind();
|
||||
info_.stride_ = detail::instanced_mesh_vertex_setup<Attribs...>::setup();
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, instance_buffer_);
|
||||
instance_stride_ = detail::instanced_mesh_instance_setup<Attribs...>::setup();
|
||||
if constexpr (detail::has_instanced_attribs<Attribs...>)
|
||||
{
|
||||
if (!instance_buffer_) instance_buffer_ = buffer{};
|
||||
instance_buffer_.bind();
|
||||
info_.instance_stride_ = detail::instanced_mesh_instance_setup<Attribs...>::setup();
|
||||
info_.instanced_ = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
info_.instance_stride_ = 0;
|
||||
info_.instanced_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, index_buffer_);
|
||||
template <typename Vertex>
|
||||
void mesh::load(Vertex const * vertices, std::size_t count, GLenum primitive_type, GLenum usage)
|
||||
{
|
||||
assert(info_.stride_ == sizeof(Vertex));
|
||||
|
||||
if (auto n = detail::get_primitive_type_vertex_count(primitive_type); n)
|
||||
assert((count % (*n)) == 0);
|
||||
|
||||
assert(vertex_buffer_);
|
||||
|
||||
vertex_buffer_.load(vertices, count, usage);
|
||||
info_.vertex_count_ = count;
|
||||
info_.index_count_ = 0;
|
||||
info_.indexed_ = false;
|
||||
info_.primitive_type_ = primitive_type;
|
||||
}
|
||||
|
||||
template <typename Vertex>
|
||||
void mesh::load(std::vector<Vertex> const & vertices, GLenum primitive_type, GLenum usage)
|
||||
{
|
||||
load(vertices.data(), vertices.size(), primitive_type, usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, std::size_t N>
|
||||
void mesh::load(geom::simplex<Vertex, N> const * simplices, std::size_t count, GLenum usage)
|
||||
{
|
||||
static_assert(sizeof(Vertex) * (N + 1) == sizeof(simplices[0]));
|
||||
load(reinterpret_cast<Vertex const *>(simplices), count * (N + 1), detail::get_primitive_type<N>(), usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, std::size_t N>
|
||||
void mesh::load(std::vector<geom::simplex<Vertex, N>> const & simplices, GLenum usage)
|
||||
{
|
||||
load(simplices.data(), simplices.size(), usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, typename Index>
|
||||
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)
|
||||
void mesh::load(Vertex const * vertices, std::size_t vertex_count, Index const * indices, std::size_t index_count, GLenum primitive_type, GLenum usage)
|
||||
{
|
||||
detail::check_vertex_size(sizeof(Vertex), stride_);
|
||||
assert(info_.stride_ == sizeof(Vertex));
|
||||
|
||||
switch (primitive_type)
|
||||
if (auto n = detail::get_primitive_type_vertex_count(primitive_type); n)
|
||||
assert((index_count % (*n)) == 0);
|
||||
|
||||
assert(vertex_buffer_);
|
||||
|
||||
if (!index_buffer_)
|
||||
{
|
||||
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;
|
||||
index_buffer_ = buffer{};
|
||||
array_.bind();
|
||||
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, index_buffer_.id());
|
||||
}
|
||||
|
||||
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;
|
||||
vertex_buffer_.load(vertices, vertex_count, usage);
|
||||
index_buffer_.load(indices, index_count, usage);
|
||||
info_.vertex_count_ = vertex_count;
|
||||
info_.index_count_ = index_count;
|
||||
info_.indexed_ = true;
|
||||
info_.primitive_type_ = primitive_type;
|
||||
info_.index_type_ = detail::gl_type_v<Index>;
|
||||
}
|
||||
|
||||
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)
|
||||
void mesh::load(std::vector<Vertex> const & vertices, std::vector<Index> const & indices, GLenum primitive_type, GLenum usage)
|
||||
{
|
||||
load(vertices.data(), vertices.size(), indices.data(), indices.size(), primitive_type, usage);
|
||||
}
|
||||
|
||||
template <typename Vertex, typename Index, std::size_t N>
|
||||
void load(Vertex const * vertices, std::size_t vertex_count, geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage = gl::STREAM_DRAW)
|
||||
void mesh::load(Vertex const * vertices, std::size_t vertex_count, geom::simplex<Index, N> const * simplices, std::size_t simplex_count, GLenum usage)
|
||||
{
|
||||
static_assert(sizeof(geom::simplex<Index, N>) == (N + 1) * sizeof(Index));
|
||||
|
||||
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(vertices, vertex_count, reinterpret_cast<Index const *>(simplices), simplex_count * (N + 1), primitive_type, usage);
|
||||
static_assert(sizeof(Index) * (N + 1) == sizeof(simplices[0]));
|
||||
load(vertices, vertex_count, reinterpret_cast<Index const *>(simplices), (N + 1) * simplex_count, detail::get_primitive_type<N>(), usage);
|
||||
}
|
||||
|
||||
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 mesh::load(std::vector<Vertex> const & vertices, std::vector<geom::simplex<Index, N>> const & simplices, GLenum usage)
|
||||
{
|
||||
load(vertices.data(), vertices.size(), simplices.data(), simplices.size(), usage);
|
||||
}
|
||||
|
||||
template <typename Instance>
|
||||
void load_instance(Instance const * instances, std::size_t count, GLenum usage = gl::STREAM_DRAW)
|
||||
void mesh::load_instance(Instance const * instances, std::size_t count, GLenum usage)
|
||||
{
|
||||
detail::check_instance_size(sizeof(Instance), instance_stride_);
|
||||
assert(info_.instance_stride_ == sizeof(Instance));
|
||||
|
||||
gl::BindBuffer(gl::ARRAY_BUFFER, instance_buffer_);
|
||||
gl::BufferData(gl::ARRAY_BUFFER, count * sizeof(Instance), instances, usage);
|
||||
instance_count_ = count;
|
||||
assert(instance_buffer_);
|
||||
instance_buffer_.load(instances, count, usage);
|
||||
info_.instance_count_ = count;
|
||||
}
|
||||
|
||||
template <typename Instance>
|
||||
void load_instance(std::vector<Instance> const & instances, GLenum usage = gl::STREAM_DRAW)
|
||||
void mesh::load_instance(std::vector<Instance> const & instances, GLenum usage)
|
||||
{
|
||||
load_instance(instances.data(), instances.size(), usage);
|
||||
}
|
||||
|
||||
void draw() const override
|
||||
{
|
||||
draw(0, count_, instance_count_);
|
||||
}
|
||||
|
||||
void draw(GLsizei first, GLsizei count, GLsizei instance_count) const
|
||||
{
|
||||
assert(first + count <= count_);
|
||||
assert(instance_count <= instance_count_);
|
||||
|
||||
if (count == 0) return;
|
||||
if (instance_count == 0) return;
|
||||
|
||||
gl::BindVertexArray(array_);
|
||||
gl::DrawElementsInstanced(primitive_type_, count, index_type_, reinterpret_cast<char const *>(0) + detail::index_size(index_type_) * first, instance_count);
|
||||
}
|
||||
|
||||
GLsizei index_count() const
|
||||
{
|
||||
return count_;
|
||||
}
|
||||
|
||||
GLsizei instance_count() const
|
||||
{
|
||||
return instance_count_;
|
||||
}
|
||||
|
||||
GLenum primitive_type() const
|
||||
{
|
||||
return primitive_type_;
|
||||
}
|
||||
|
||||
private:
|
||||
GLuint array_;
|
||||
GLuint buffer_;
|
||||
GLuint index_buffer_;
|
||||
GLuint instance_buffer_;
|
||||
|
||||
GLsizei count_ = 0;
|
||||
GLsizei instance_count_ = 0;
|
||||
GLenum index_type_ = 0;
|
||||
|
||||
std::size_t stride_ = 0;
|
||||
std::size_t instance_stride_ = 0;
|
||||
|
||||
GLenum primitive_type_;
|
||||
|
||||
instanced_indexed_mesh(int);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
static indexed_mesh create_fullscreen_quad()
|
||||
static mesh create_fullscreen_quad()
|
||||
{
|
||||
indexed_mesh m;
|
||||
mesh m;
|
||||
|
||||
std::vector<geom::point<float, 2>> vertices(4);
|
||||
std::vector<std::uint8_t> indices(6);
|
||||
|
|
@ -28,9 +28,9 @@ namespace psemek::gfx
|
|||
return m;
|
||||
}
|
||||
|
||||
indexed_mesh const & fullscreen_quad()
|
||||
mesh const & fullscreen_quad()
|
||||
{
|
||||
static indexed_mesh m = create_fullscreen_quad();
|
||||
static mesh m = create_fullscreen_quad();
|
||||
return m;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,309 +5,83 @@
|
|||
namespace psemek::gfx
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
void check_vertex_size(std::size_t vertex_size, std::size_t stride)
|
||||
{
|
||||
if (vertex_size != stride)
|
||||
throw std::runtime_error(util::to_string("Vertex size (", vertex_size, ") not equal to sum of attribute sizes (", stride, ")"));
|
||||
}
|
||||
|
||||
void check_instance_size(std::size_t instance_size, std::size_t stride)
|
||||
{
|
||||
if (instance_size != stride)
|
||||
throw std::runtime_error(util::to_string("Instance size (", instance_size, ") not equal to sum of instanced attribute sizes (", stride, ")"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mesh mesh::null()
|
||||
{
|
||||
return mesh(0);
|
||||
}
|
||||
|
||||
mesh::mesh()
|
||||
{
|
||||
gl::GenVertexArrays(1, &array_);
|
||||
gl::GenBuffers(1, &buffer_);
|
||||
}
|
||||
|
||||
mesh::mesh(mesh && other)
|
||||
: array_{std::move(other.array_)}
|
||||
, vertex_buffer_{std::move(other.vertex_buffer_)}
|
||||
, index_buffer_{std::move(other.index_buffer_)}
|
||||
, instance_buffer_{std::move(other.instance_buffer_)}
|
||||
, info_{other.info_}
|
||||
{
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
count_ = other.count_;
|
||||
stride_ = other.stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.stride_ = 0;
|
||||
other.info_ = mesh_info{};
|
||||
}
|
||||
|
||||
mesh & mesh::operator =(mesh && other)
|
||||
mesh & mesh::operator = (mesh && other)
|
||||
{
|
||||
if (this == &other) return *this;
|
||||
|
||||
if (array_)
|
||||
{
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
}
|
||||
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
count_ = other.count_;
|
||||
stride_ = other.stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.stride_ = 0;
|
||||
array_ = std::move(other.array_);
|
||||
vertex_buffer_ = std::move(other.vertex_buffer_);
|
||||
index_buffer_ = std::move(other.index_buffer_);
|
||||
instance_buffer_ = std::move(other.instance_buffer_);
|
||||
info_ = other.info_;
|
||||
other.info_ = mesh_info{};
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
mesh::~mesh()
|
||||
void mesh::draw() const
|
||||
{
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
draw(0, is_indexed() ? index_count() : vertex_count(), instance_count());
|
||||
}
|
||||
|
||||
mesh::mesh(int)
|
||||
void mesh::draw(std::size_t first, std::size_t count, std::size_t instance_count) const
|
||||
{
|
||||
array_ = 0;
|
||||
buffer_ = 0;
|
||||
if (is_indexed())
|
||||
{
|
||||
assert(first + count <= index_count());
|
||||
|
||||
if (is_instanced())
|
||||
{
|
||||
assert(instance_count <= this->instance_count());
|
||||
|
||||
if (count != 0 && instance_count != 0)
|
||||
{
|
||||
array_.bind();
|
||||
gl::DrawElementsInstanced(primitive_type(), count, index_type(), reinterpret_cast<char const *>(detail::index_size(index_type()) * first), instance_count);
|
||||
}
|
||||
|
||||
indexed_mesh indexed_mesh::null()
|
||||
{
|
||||
return indexed_mesh(0);
|
||||
}
|
||||
|
||||
indexed_mesh::indexed_mesh()
|
||||
else
|
||||
{
|
||||
gl::GenVertexArrays(1, &array_);
|
||||
gl::GenBuffers(1, &buffer_);
|
||||
gl::GenBuffers(1, &index_buffer_);
|
||||
if (count != 0)
|
||||
{
|
||||
array_.bind();
|
||||
gl::DrawElements(primitive_type(), count, index_type(), reinterpret_cast<char const *>(detail::index_size(index_type()) * first));
|
||||
}
|
||||
|
||||
indexed_mesh::indexed_mesh(indexed_mesh && other)
|
||||
{
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
index_buffer_ = other.index_buffer_;
|
||||
count_ = other.count_;
|
||||
index_type_ = other.index_type_;
|
||||
stride_ = other.stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.index_buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.index_type_ = 0;
|
||||
other.stride_ = 0;
|
||||
}
|
||||
|
||||
indexed_mesh & indexed_mesh::operator =(indexed_mesh && other)
|
||||
{
|
||||
if (this == &other) return *this;
|
||||
|
||||
if (array_)
|
||||
{
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
gl::DeleteBuffers(1, &index_buffer_);
|
||||
}
|
||||
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
index_buffer_ = other.index_buffer_;
|
||||
count_ = other.count_;
|
||||
index_type_ = other.index_type_;
|
||||
stride_ = other.stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.index_buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.index_type_ = 0;
|
||||
other.stride_ = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
indexed_mesh::~indexed_mesh()
|
||||
else
|
||||
{
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
gl::DeleteBuffers(1, &index_buffer_);
|
||||
}
|
||||
assert(first + count <= vertex_count());
|
||||
|
||||
indexed_mesh::indexed_mesh(int)
|
||||
if (is_instanced())
|
||||
{
|
||||
array_ = 0;
|
||||
buffer_ = 0;
|
||||
index_buffer_ = 0;
|
||||
}
|
||||
assert(instance_count <= this->instance_count());
|
||||
|
||||
instanced_mesh instanced_mesh::null()
|
||||
if (count != 0 && instance_count != 0)
|
||||
{
|
||||
return instanced_mesh(0);
|
||||
array_.bind();
|
||||
gl::DrawArraysInstanced(primitive_type(), first, count, instance_count);
|
||||
}
|
||||
|
||||
instanced_mesh::instanced_mesh()
|
||||
{
|
||||
gl::GenVertexArrays(1, &array_);
|
||||
gl::GenBuffers(1, &buffer_);
|
||||
gl::GenBuffers(1, &instance_buffer_);
|
||||
}
|
||||
|
||||
instanced_mesh::instanced_mesh(instanced_mesh && other)
|
||||
else
|
||||
{
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
instance_buffer_ = other.instance_buffer_;
|
||||
count_ = other.count_;
|
||||
instance_count_ = other.instance_count_;
|
||||
stride_ = other.stride_;
|
||||
instance_stride_ = other.instance_stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.instance_buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.instance_count_ = 0;
|
||||
other.stride_ = 0;
|
||||
other.instance_stride_ = 0;
|
||||
if (count != 0)
|
||||
{
|
||||
array_.bind();
|
||||
gl::DrawArrays(primitive_type(), first, count);
|
||||
}
|
||||
|
||||
instanced_mesh & instanced_mesh::operator = (instanced_mesh && other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
gl::DeleteBuffers(1, &instance_buffer_);
|
||||
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
instance_buffer_ = other.instance_buffer_;
|
||||
count_ = other.count_;
|
||||
instance_count_ = other.instance_count_;
|
||||
stride_ = other.stride_;
|
||||
instance_stride_ = other.instance_stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.instance_buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.instance_count_ = 0;
|
||||
other.stride_ = 0;
|
||||
other.instance_stride_ = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
instanced_mesh::~instanced_mesh()
|
||||
{
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
gl::DeleteBuffers(1, &instance_buffer_);
|
||||
}
|
||||
|
||||
instanced_mesh::instanced_mesh(int)
|
||||
{
|
||||
array_ = 0;
|
||||
buffer_ = 0;
|
||||
instance_buffer_ = 0;
|
||||
}
|
||||
|
||||
instanced_indexed_mesh instanced_indexed_mesh::null()
|
||||
{
|
||||
return instanced_indexed_mesh(0);
|
||||
}
|
||||
|
||||
instanced_indexed_mesh::instanced_indexed_mesh()
|
||||
{
|
||||
gl::GenVertexArrays(1, &array_);
|
||||
gl::GenBuffers(1, &buffer_);
|
||||
gl::GenBuffers(1, &index_buffer_);
|
||||
gl::GenBuffers(1, &instance_buffer_);
|
||||
}
|
||||
|
||||
instanced_indexed_mesh::instanced_indexed_mesh(instanced_indexed_mesh && other)
|
||||
{
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
instance_buffer_ = other.instance_buffer_;
|
||||
count_ = other.count_;
|
||||
instance_count_ = other.instance_count_;
|
||||
stride_ = other.stride_;
|
||||
instance_stride_ = other.instance_stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.instance_buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.instance_count_ = 0;
|
||||
other.stride_ = 0;
|
||||
other.instance_stride_ = 0;
|
||||
}
|
||||
|
||||
instanced_indexed_mesh & instanced_indexed_mesh::operator = (instanced_indexed_mesh && other)
|
||||
{
|
||||
if (this == &other)
|
||||
return *this;
|
||||
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
gl::DeleteBuffers(1, &index_buffer_);
|
||||
gl::DeleteBuffers(1, &instance_buffer_);
|
||||
|
||||
array_ = other.array_;
|
||||
buffer_ = other.buffer_;
|
||||
instance_buffer_ = other.instance_buffer_;
|
||||
count_ = other.count_;
|
||||
instance_count_ = other.instance_count_;
|
||||
stride_ = other.stride_;
|
||||
instance_stride_ = other.instance_stride_;
|
||||
primitive_type_ = other.primitive_type_;
|
||||
|
||||
other.array_ = 0;
|
||||
other.buffer_ = 0;
|
||||
other.instance_buffer_ = 0;
|
||||
other.count_ = 0;
|
||||
other.instance_count_ = 0;
|
||||
other.stride_ = 0;
|
||||
other.instance_stride_ = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
instanced_indexed_mesh::~instanced_indexed_mesh()
|
||||
{
|
||||
gl::DeleteVertexArrays(1, &array_);
|
||||
gl::DeleteBuffers(1, &buffer_);
|
||||
gl::DeleteBuffers(1, &index_buffer_);
|
||||
gl::DeleteBuffers(1, &instance_buffer_);
|
||||
}
|
||||
|
||||
instanced_indexed_mesh::instanced_indexed_mesh(int)
|
||||
{
|
||||
array_ = 0;
|
||||
buffer_ = 0;
|
||||
index_buffer_ = 0;
|
||||
instance_buffer_ = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,8 +94,8 @@ namespace psemek::gfx
|
|||
|
||||
gfx::program program{vertex_source, fragment_source};
|
||||
gfx::program text_program{text_vertex_source, text_fragment_source};
|
||||
gfx::indexed_mesh mesh;
|
||||
gfx::indexed_mesh text_mesh;
|
||||
gfx::mesh mesh;
|
||||
gfx::mesh text_mesh;
|
||||
|
||||
std::vector<vertex> vertices;
|
||||
std::vector<std::uint32_t> indices;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue