]> git.tdb.fi Git - libs/gl.git/commitdiff
Always use instanced rendering in InstanceArray
authorMikko Rasa <tdb@tdb.fi>
Thu, 30 Sep 2021 14:15:22 +0000 (17:15 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 30 Sep 2021 21:07:06 +0000 (00:07 +0300)
All the required extensions are present in OpenGL 3.3, so there's little
reason to keep the fallback code.

source/render/instancearray.cpp
source/render/instancearray.h

index be3f17d4bc24cd6e2cd3d612321448a7302caf02..37d7ccb68e3815f8f24b31351d904f4f41175490 100644 (file)
@@ -1,9 +1,5 @@
 #include <msp/core/algorithm.h>
 #include <msp/core/maputils.h>
-#include <msp/gl/extensions/arb_draw_instanced.h>
-#include <msp/gl/extensions/arb_instanced_arrays.h>
-#include <msp/gl/extensions/arb_vertex_array_object.h>
-#include <msp/gl/extensions/arb_vertex_shader.h>
 #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()<instances.size())
        {
-               if(instance_data->size()<instances.size())
+               instance_data.append();
+               unsigned req_size = instance_data.get_required_buffer_size();
+               if(instance_buffer->get_size()>0 && instance_buffer->get_size()<req_size)
                {
-                       instance_data->append();
-                       unsigned req_size = instance_data->get_required_buffer_size();
-                       if(instance_buffer->get_size()>0 && instance_buffer->get_size()<req_size)
-                       {
-                               delete instance_buffer;
-                               instance_buffer = new Buffer;
-                               instance_data->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<float *>(instance_data->modify(instances.size()-1)+matrix_offset);
+       float *d = reinterpret_cast<float *>(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
index 6a598b5854f3183e290896eb052708f32c0f98a6..4d7d3475bbaa500d405ef05b6e3868402f9a2921 100644 (file)
@@ -4,6 +4,8 @@
 #include <vector>
 #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<ObjectInstance *> instances;
-       VertexArray *instance_data;
+       VertexArray instance_data;
        Buffer *instance_buffer;
-       VertexSetup *vtx_setup;
+       VertexSetup vtx_setup;
        int matrix_location;
        unsigned matrix_offset;