141 lines
2.1 KiB
C++
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();
|
|
}
|
|
|
|
|
|
}
|