1
0
Fork 0
Univerxel/src/client/render/gl/api/Models.cpp

159 lines
5.7 KiB
C++

#include "Models.hpp"
using namespace render::gl;
Shape::Shape(const std::vector<glm::vec3>& pos) {
size = pos.size();
glGenBuffers(1, &bufferId);
glBindBuffer(GL_ARRAY_BUFFER, bufferId);
glBufferData(GL_ARRAY_BUFFER, pos.size() * sizeof(glm::vec3), pos.data(), GL_STATIC_DRAW);
}
Shape::~Shape() {
glDeleteBuffers(1, &bufferId);
}
size_t Shape::draw() {
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, bufferId);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
glDrawArrays(GL_TRIANGLES, 0, size);
glDisableVertexAttribArray(0);
return size;
}
Indicator::Indicator(const std::vector<glm::vec3>& pos, const std::vector<glm::vec4>& col) {
assert(pos.size() == col.size());
size = pos.size();
glGenBuffers(1, &vertexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glBufferData(GL_ARRAY_BUFFER, pos.size() * sizeof(glm::vec3), pos.data(), GL_STATIC_DRAW);
glGenBuffers(1, &colorBufferId);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferId);
glBufferData(GL_ARRAY_BUFFER, col.size() * sizeof(glm::vec4), col.data(), GL_STATIC_DRAW);
}
Indicator::~Indicator() {
glDeleteBuffers(1, &colorBufferId);
glDeleteBuffers(1, &vertexBufferId);
}
void Indicator::enableAttribs() {
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferId);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void *)0);
}
void Indicator::disableAttribs() {
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
size_t Indicator::draw() {
enableAttribs();
glDrawArrays(GL_LINES, 0, size);
disableAttribs();
return size;
}
size_t Indicator::drawInstanced(size_t count) {
enableAttribs();
glDrawArraysInstanced(GL_LINES, 0, size, count);
disableAttribs();
return size * count;
}
void enableAttribs() {
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_HALF_FLOAT, GL_FALSE, sizeof(render::PackedVertexData),
reinterpret_cast<void *>(offsetof(render::PackedVertexData, PosMat[0])));
glEnableVertexAttribArray(1);
glVertexAttribIPointer(1, 1, GL_UNSIGNED_SHORT, sizeof(render::PackedVertexData),
reinterpret_cast<void *>(offsetof(render::PackedVertexData, PosMat[3])));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_HALF_FLOAT, GL_FALSE, sizeof(render::PackedVertexData),
reinterpret_cast<void *>(offsetof(render::PackedVertexData, Nrm)));
}
void disableAttribs() {
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
Model::Model(const Data& data) {
indexSize = data.indices.size();
glGenBuffers(1, &vertexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glBufferData(GL_ARRAY_BUFFER, data.vertices.size() * sizeof(render::PackedVertexData), data.vertices.data(), GL_STATIC_DRAW);
glGenBuffers(1, &indexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, indexBufferId);
glBufferData(GL_ARRAY_BUFFER, data.indices.size() * sizeof(glm::u16), data.indices.data(), GL_STATIC_DRAW);
}
Model::~Model() {
glDeleteBuffers(1, &vertexBufferId);
glDeleteBuffers(1, &indexBufferId);
}
size_t Model::draw() {
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
enableAttribs();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
glDrawElements(GL_TRIANGLES, indexSize, GL_UNSIGNED_SHORT, (void *)0);
disableAttribs();
return indexSize;
}
size_t Model::drawInstanced(size_t count) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
enableAttribs();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
glDrawElementsInstanced(GL_TRIANGLES, indexSize, GL_UNSIGNED_SHORT, (void *)0, count);
disableAttribs();
return indexSize * count;
}
LodModel::LodModel(const LodData& data) {
indexSize = data.first.indices.size();
offsets = data.second;
glGenBuffers(1, &vertexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glBufferData(GL_ARRAY_BUFFER, data.first.vertices.size() * sizeof(render::PackedVertexData), data.first.vertices.data(), GL_STATIC_DRAW);
glGenBuffers(1, &indexBufferId);
glBindBuffer(GL_ARRAY_BUFFER, indexBufferId);
glBufferData(GL_ARRAY_BUFFER, data.first.indices.size() * sizeof(glm::u16), data.first.indices.data(), GL_STATIC_DRAW);
}
LodModel::~LodModel() {
glDeleteBuffers(1, &vertexBufferId);
glDeleteBuffers(1, &indexBufferId);
}
size_t LodModel::draw() {
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
enableAttribs();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
const auto start = getOffset(level);
const auto end = getOffset(level+1);
const auto count = end - start;
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (void *)(start*sizeof(glm::u16)));
disableAttribs();
return count;
}
size_t LodModel::drawInstanced(size_t i) {
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
enableAttribs();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
const auto start = getOffset(level);
const auto end = getOffset(level+1);
const auto count = end - start;
glDrawElementsInstanced(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, (void *)(start*sizeof(glm::u16)), i);
disableAttribs();
return i * count;
}
std::unique_ptr<render::Model> createModel(const Model::Data& data) {
return std::make_unique<Model>(data);
}
void Model::MakeDefault() {
createFunc = createModel;
}
std::unique_ptr<render::LodModel> createLodModel(const LodModel::LodData& data) {
return std::make_unique<LodModel>(data);
}
void LodModel::MakeDefault() {
createFunc = createLodModel;
}