1
0
Fork 0
Univerxel/src/client/render/gl/buffer/ShortIndexed.cpp

131 lines
5.1 KiB
C++

#include "ShortIndexed.hpp"
#include "vboindexer.hpp"
#include "../../../../core/utils/logger.hpp"
using namespace buffer;
ShortIndexed::Data::Data(const std::vector<PackedVertexData> &vs, const std::vector<GLushort> &indices): indices(indices), vertices(vs) { }
ShortIndexed::Data::Data(std::ifstream& in) {
{
size_t i_size;
in.read(reinterpret_cast<char *>(&i_size), sizeof(i_size));
indices.resize(i_size);
in.read(reinterpret_cast<char *>(indices.data()), sizeof(GLushort) * i_size);
}
size_t v_size;
in.read(reinterpret_cast<char *>(&v_size), sizeof(v_size));
vertices.resize(v_size, PackedVertexData(0, 0, 0, 0, 0, 0, 0, 0));
in.read(reinterpret_cast<char *>(vertices.data()), sizeof(buffer::PackedVertexData) * v_size);
}
void ShortIndexed::Data::serialize(std::ofstream& out) {
{
size_t i_size = indices.size();
out.write(reinterpret_cast<char *>(&i_size), sizeof(i_size));
out.write(reinterpret_cast<char *>(indices.data()), sizeof(GLushort) * i_size);
}
size_t v_size = vertices.size();
out.write(reinterpret_cast<char *>(&v_size), sizeof(v_size));
out.write(reinterpret_cast<char *>(vertices.data()), sizeof(buffer::PackedVertexData) * v_size);
}
void ShortIndexed::Data::index(const std::vector<PackedVertexData>& vs) {
indexVBO(vs, indices, vertices);
}
ShortIndexed::ShortIndexed(GLenum shape, const std::vector<PackedVertexData> &vertices): Abstract(shape) {
setData(ShortIndexed::Data(vertices));
}
ShortIndexed::ShortIndexed(GLenum shape, const std::vector<PackedVertexData> &vertices, const std::vector<GLushort>& indices): Abstract(shape) {
setData(ShortIndexed::Data(vertices, indices));
}
ShortIndexed::ShortIndexed(GLenum shape, const ShortIndexed::Data &data): Abstract(shape) {
setData(data);
}
ShortIndexed::~ShortIndexed() {
glDeleteBuffers(1, &IndexBufferID);
}
void ShortIndexed::enableVertexAttrib() {
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID);
glVertexAttribPointer(
0, // attribute
3, // size
GL_HALF_FLOAT, // type
GL_FALSE, // normalized?
sizeof(PackedVertexData), // stride
reinterpret_cast<void *>(offsetof(PackedVertexData, PosMat[0])) // array buffer offset
);
}
void ShortIndexed::enableAllAttribs() {
enableVertexAttrib();
glEnableVertexAttribArray(1);
glVertexAttribIPointer(
1, // attribute
1, // size
GL_UNSIGNED_SHORT, // type
sizeof(PackedVertexData), // stride
reinterpret_cast<void *>(offsetof(PackedVertexData, PosMat[3])) // array buffer offset
);
glEnableVertexAttribArray(2);
glVertexAttribPointer(
2, // attribute
3, // size
GL_HALF_FLOAT, // type
GL_FALSE, // normalized?
sizeof(PackedVertexData), // stride
reinterpret_cast<void *>(offsetof(PackedVertexData, Nrm)) // array buffer offset
);
}
void ShortIndexed::disableAllAttribs() {
glDisableVertexAttribArray(2);
glDisableVertexAttribArray(1);
disableVertexAttrib();
}
void ShortIndexed::enableIndex() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexBufferID);
}
uint ShortIndexed::draw(buffer::params params) {
if(IndexSize == 0)
return 0;
if(params.vertexOnly) {
enableVertexAttrib();
} else {
enableAllAttribs();
}
enableIndex();
if (params.instances == 1) {
glDrawElements(Shape, IndexSize, GL_UNSIGNED_SHORT, (void *)0);
} else {
glDrawElementsInstanced(Shape, IndexSize, GL_UNSIGNED_SHORT, (void *)0, params.instances);
}
if(params.vertexOnly) {
disableVertexAttrib();
} else {
disableAllAttribs();
}
return IndexSize * params.instances;
}
void ShortIndexed::setData(const ShortIndexed::Data& data) {
glGenBuffers(1, &IndexBufferID);
IndexSize = data.indices.size();
if(IndexSize != data.indices.size()) {
LOG_E("ShortBuffer overflow: " << data.indices.size());
}
setIndicies(IndexSize * sizeof(GLushort), data.indices.data());
setVertices(data.vertices.size() * sizeof(PackedVertexData), data.vertices.data());
}
void ShortIndexed::setIndicies(const unsigned long size, const void *data) {
glBindBuffer(GL_ARRAY_BUFFER, IndexBufferID);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
}