#include "EntityProgram.hpp" #include "../Renderer.hpp" using namespace pass; inline void createBuffer(GLuint *id, const GLfloat *data, size_t count) { glGenBuffers(1, id); glBindBuffer(GL_ARRAY_BUFFER, *id); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * count, data, GL_STREAM_DRAW); } EntityProgram::EntityProgram(const EntityProgram::options &opts) : VoxelProgram(opts, {"INSTANCED"}) { constexpr auto INIT_SIZE = 100; createBuffer(&ModelsBufferID, NULL, INIT_SIZE); ModelBufferSize = INIT_SIZE; } EntityProgram::~EntityProgram() { } buffer::params EntityProgram::setup(render::gl::Renderer *renderer, const std::vector& modelsMatrices) { setModels(&modelsMatrices[0][0][0], modelsMatrices.size()); auto params = VoxelProgram::setup(renderer); params.instances = modelsMatrices.size(); return params; } void EntityProgram::setModels(const GLfloat *matrices, size_t count) { if (count > ModelBufferSize) { glDeleteBuffers(1, &ModelsBufferID); // Replace buffer createBuffer(&ModelsBufferID, matrices, count); ModelBufferSize = count; } else { glBindBuffer(GL_ARRAY_BUFFER, ModelsBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::mat4) * count, matrices); } glEnableVertexAttribArray(LOCATION + 0); glVertexAttribPointer(LOCATION + 0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(glm::vec4), (void *)0); glVertexAttribDivisor(LOCATION + 0, 1); glEnableVertexAttribArray(LOCATION + 1); glVertexAttribPointer(LOCATION + 1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(glm::vec4), (void *)(1 * sizeof(glm::vec4))); glVertexAttribDivisor(LOCATION + 1, 1); glEnableVertexAttribArray(LOCATION + 2); glVertexAttribPointer(LOCATION + 2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(glm::vec4), (void *)(2 * sizeof(glm::vec4))); glVertexAttribDivisor(LOCATION + 2, 1); glEnableVertexAttribArray(LOCATION + 3); glVertexAttribPointer(LOCATION + 3, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(glm::vec4), (void *)(3 * sizeof(glm::vec4))); glVertexAttribDivisor(LOCATION + 3, 1); } void EntityProgram::disable() { glDisableVertexAttribArray(LOCATION + 0); glDisableVertexAttribArray(LOCATION + 1); glDisableVertexAttribArray(LOCATION + 2); glDisableVertexAttribArray(LOCATION + 3); }