pixwerx/src/visual/src/vertex_array.cpp

141 lines
2.1 KiB
C++

#include "pw/visual/vertex_array.hpp"
#include "pw/core/mesh.hpp"
#include "pw/core/size.hpp"
#include "glad/glad.h"
#include <algorithm>
namespace pw {
struct vertex_array::impl {
GLuint _vao = 0;
std::vector<GLuint> _vbos;
GLint _mesh_elements = {0};
impl()
{
}
~impl()
{
release();
}
bool ready() const
{
return GL_TRUE == glIsVertexArray(_vao);
}
void create(const mesh& m)
{
// not sure ...
if (ready()) {
release();
}
glGenVertexArrays(1,&_vao);
glBindVertexArray(_vao);
size_t arrays_needed = 0;
// should bail out here
if (!m.vertices().empty()) arrays_needed++;
if (!m.indices().empty()) arrays_needed++;
_mesh_elements = m.indices().size();
// TODO: implement the other arrays
_vbos.resize(arrays_needed);
glGenBuffers(_vbos.size(), _vbos.data());
// vertices
glBindBuffer(GL_ARRAY_BUFFER, _vbos[0]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(m.vertices().front()) * m.vertices().size(),
m.vertices().data(),
GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vbos[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(m.indices().front()) * m.indices().size(), m.indices().data(),
GL_STATIC_DRAW);
// stop binding
glBindVertexArray(0);
}
void release()
{
glDeleteVertexArrays(1,&_vao);
for (auto vbo : _vbos)
glDeleteBuffers(1,&vbo);
_vbos.clear();
}
void draw()
{
glBindVertexArray(_vao);
glDrawElements(GL_TRIANGLES, _mesh_elements, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
}
// GLint get_mode(vertex_array::)
};
//
//
//
vertex_array::vertex_array()
: _impl(std::make_unique<vertex_array::impl>())
{
}
vertex_array::vertex_array(const mesh &m)
{
vertex_array();
_impl->create(m);
}
vertex_array::~vertex_array()
{
}
bool vertex_array::ready() const
{
return _impl->ready();
}
void vertex_array::create(const mesh &m)
{
_impl->create(m);
}
void vertex_array::release()
{
_impl->release();
}
void vertex_array::draw()
{
_impl->draw();
}
}