From 96cfb8224fe73afd04289a5d1c7780170f479e25 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 30 Sep 2021 17:15:22 +0300 Subject: [PATCH] Always use instanced rendering in InstanceArray All the required extensions are present in OpenGL 3.3, so there's little reason to keep the fallback code. --- source/render/instancearray.cpp | 104 +++++++++++--------------------- source/render/instancearray.h | 6 +- 2 files changed, 39 insertions(+), 71 deletions(-) diff --git a/source/render/instancearray.cpp b/source/render/instancearray.cpp index be3f17d4..37d7ccb6 100644 --- a/source/render/instancearray.cpp +++ b/source/render/instancearray.cpp @@ -1,9 +1,5 @@ #include #include -#include -#include -#include -#include #include "buffer.h" #include "camera.h" #include "instancearray.h" @@ -13,7 +9,6 @@ #include "program.h" #include "renderer.h" #include "technique.h" -#include "vertexsetup.h" using namespace std; @@ -22,9 +17,7 @@ namespace GL { InstanceArray::InstanceArray(const Object &o): object(o), - instance_data(0), instance_buffer(0), - vtx_setup(0), matrix_location(-1), matrix_offset(0) { @@ -42,54 +35,43 @@ InstanceArray::InstanceArray(const Object &o): throw invalid_argument("InstanceArray::InstanceArray"); } - if(ARB_vertex_array_object && ARB_instanced_arrays && ARB_draw_instanced) - { - instance_data = new VertexArray((RAW_ATTRIB4,matrix_location, RAW_ATTRIB4,matrix_location+1, RAW_ATTRIB4,matrix_location+2)); - const VertexFormat &fmt = instance_data->get_format(); - matrix_offset = fmt.offset((RAW_ATTRIB4,matrix_location)); + instance_data.set_format((RAW_ATTRIB4,matrix_location, RAW_ATTRIB4,matrix_location+1, RAW_ATTRIB4,matrix_location+2)); + const VertexFormat &fmt = instance_data.get_format(); + matrix_offset = fmt.offset((RAW_ATTRIB4,matrix_location)); - instance_buffer = new Buffer; - instance_data->use_buffer(instance_buffer); + instance_buffer = new Buffer; + instance_data.use_buffer(instance_buffer); - const Mesh *mesh = object.get_mesh(); + const Mesh *mesh = object.get_mesh(); - vtx_setup = new VertexSetup; - vtx_setup->set_format_instanced(mesh->get_vertices().get_format(), fmt); - vtx_setup->set_vertex_array(mesh->get_vertices()); - vtx_setup->set_index_buffer(*mesh->get_index_buffer(), mesh->get_batches().front().get_index_type()); - vtx_setup->set_instance_array(*instance_data); - } - else - static Require req(ARB_vertex_shader); + vtx_setup.set_format_instanced(mesh->get_vertices().get_format(), fmt); + vtx_setup.set_vertex_array(mesh->get_vertices()); + vtx_setup.set_index_buffer(*mesh->get_index_buffer(), mesh->get_batches().front().get_index_type()); + vtx_setup.set_instance_array(instance_data); } InstanceArray::~InstanceArray() { for(ObjectInstance *i: instances) delete i; - delete vtx_setup; - delete instance_data; delete instance_buffer; } void InstanceArray::append(ObjectInstance *inst) { instances.push_back(inst); - if(instance_data) + if(instance_data.size()size()get_size()>0 && instance_buffer->get_size()append(); - unsigned req_size = instance_data->get_required_buffer_size(); - if(instance_buffer->get_size()>0 && instance_buffer->get_size()use_buffer(instance_buffer); - } + delete instance_buffer; + instance_buffer = new Buffer; + instance_data.use_buffer(instance_buffer); } - update_instance_matrix(instances.size()-1); } + update_instance_matrix(instances.size()-1); } void InstanceArray::remove(ObjectInstance &inst) @@ -105,12 +87,9 @@ void InstanceArray::remove(ObjectInstance &inst) void InstanceArray::update_instance_matrix(unsigned index) { - if(!instance_data) - return; - const Matrix &m = *instances[index]->get_matrix(); - float *d = reinterpret_cast(instance_data->modify(instances.size()-1)+matrix_offset); + float *d = reinterpret_cast(instance_data.modify(instances.size()-1)+matrix_offset); for(unsigned i=0; i<12; ++i) d[i] = m(i/4, i%4); } @@ -120,35 +99,22 @@ void InstanceArray::render(Renderer &renderer, Tag tag) const if(instances.empty()) return; - if(instance_data) - { - const Technique *tech = object.get_technique(); - if(!tech) - throw logic_error("no technique"); - const RenderPass *pass = tech->find_pass(tag); - if(!pass) - return; - - const Mesh *mesh = object.get_mesh(); - mesh->get_vertices().refresh(); - if(instance_buffer->get_size()==0) - instance_buffer->storage(instance_data->get_required_buffer_size()); - instance_data->refresh(); - - Renderer::Push push(renderer); - pass->apply(renderer); - mesh->draw_instanced(renderer, *vtx_setup, instances.size()); - } - else - { - for(ObjectInstance *i: instances) - { - const Matrix &m = *i->get_matrix(); - for(unsigned j=0; j<3; ++j) - glVertexAttrib4f(matrix_location+j, m(j, 0), m(j, 1), m(j, 2), m(j, 3)); - i->render(renderer, tag); - } - } + const Technique *tech = object.get_technique(); + if(!tech) + throw logic_error("no technique"); + const RenderPass *pass = tech->find_pass(tag); + if(!pass) + return; + + const Mesh *mesh = object.get_mesh(); + mesh->get_vertices().refresh(); + if(instance_buffer->get_size()==0) + instance_buffer->storage(instance_data.get_required_buffer_size()); + instance_data.refresh(); + + Renderer::Push push(renderer); + pass->apply(renderer); + mesh->draw_instanced(renderer, vtx_setup, instances.size()); } } // namespace GL diff --git a/source/render/instancearray.h b/source/render/instancearray.h index 6a598b58..4d7d3475 100644 --- a/source/render/instancearray.h +++ b/source/render/instancearray.h @@ -4,6 +4,8 @@ #include #include "programdata.h" #include "renderable.h" +#include "vertexarray.h" +#include "vertexsetup.h" namespace Msp { namespace GL { @@ -39,9 +41,9 @@ public: private: const Object &object; std::vector instances; - VertexArray *instance_data; + VertexArray instance_data; Buffer *instance_buffer; - VertexSetup *vtx_setup; + VertexSetup vtx_setup; int matrix_location; unsigned matrix_offset; -- 2.45.2