From 9ea45d05951ead69fee978000cda90f9cf5f0c81 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Tue, 26 Jan 2021 01:17:52 +0200 Subject: [PATCH] Better way of refreshing VertexSetup It can now disable attribute arrays which are no longer used. --- source/mesh.cpp | 4 ++-- source/vertexformat.cpp | 7 ++++++ source/vertexformat.h | 2 ++ source/vertexsetup.cpp | 53 +++++++++++++++++++++++++++++++++++------ source/vertexsetup.h | 10 +++++++- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/source/mesh.cpp b/source/mesh.cpp index 51468f2f..ae08fd83 100644 --- a/source/mesh.cpp +++ b/source/mesh.cpp @@ -230,7 +230,7 @@ void Mesh::Loader::vertices(const vector &c) if(allow_gl_calls) { obj.check_buffers(VERTEX_BUFFER); - obj.vtx_setup.set_vertex_array(obj.vertices); + obj.vtx_setup.refresh(); } } @@ -285,7 +285,7 @@ bool Mesh::AsyncLoader::process() else if(phase==1) { mesh.resize_buffers(); - mesh.vtx_setup.set_vertex_array(vertices); + mesh.vtx_setup.refresh(); vertex_updater = mesh.vertices.refresh_async(); if(!mesh.batches.empty()) index_updater = mesh.batches.front().refresh_async(); diff --git a/source/vertexformat.cpp b/source/vertexformat.cpp index 037305f8..6c2e2933 100644 --- a/source/vertexformat.cpp +++ b/source/vertexformat.cpp @@ -43,6 +43,13 @@ VertexFormat VertexFormat::operator,(unsigned i) const return r; } +bool VertexFormat::operator==(const VertexFormat &other) const +{ + if(count!=other.count) + return false; + return equal(components, components+count, other.components); +} + unsigned VertexFormat::stride() const { unsigned s = 0; diff --git a/source/vertexformat.h b/source/vertexformat.h index bcb5b925..35612922 100644 --- a/source/vertexformat.h +++ b/source/vertexformat.h @@ -44,6 +44,8 @@ public: VertexFormat operator,(VertexComponent c) const; VertexFormat operator,(unsigned i) const; + bool operator==(const VertexFormat &) const; + bool operator!=(const VertexFormat &other) const { return !(*this==other); } bool empty() const { return !count; } const unsigned char *begin() const { return components; } diff --git a/source/vertexsetup.cpp b/source/vertexsetup.cpp index 19edfb39..d50406a1 100644 --- a/source/vertexsetup.cpp +++ b/source/vertexsetup.cpp @@ -42,7 +42,8 @@ void VertexSetup::set_vertex_array(const VertexArray &a) throw invalid_argument("VertexSetup::set_vertex_array"); vertex_array = &a; - update(VERTEX_ARRAY); + update(get_update_mask(VERTEX_ARRAY, vertex_format, *vertex_array)); + vertex_format = vertex_array->get_format(); } void VertexSetup::set_instance_array(const VertexArray *a) @@ -56,7 +57,8 @@ void VertexSetup::set_instance_array(const VertexArray *a) } inst_array = a; - update(INSTANCE_ARRAY); + update(get_update_mask(INSTANCE_ARRAY, inst_format, *inst_array)); + inst_format = inst_array->get_format(); } void VertexSetup::set_index_buffer(const Buffer &ibuf) @@ -65,6 +67,34 @@ void VertexSetup::set_index_buffer(const Buffer &ibuf) update(INDEX_BUFFER); } +void VertexSetup::refresh() +{ + if(vertex_array && vertex_array->get_format()!=vertex_format) + set_vertex_array(*vertex_array); + + if(inst_array && inst_array->get_format()!=inst_format) + set_instance_array(inst_array); +} + +unsigned VertexSetup::get_attribs(const VertexFormat &fmt) +{ + unsigned mask = 0; + for(const unsigned char *c=fmt.begin(); c!=fmt.end(); ++c) + { + unsigned t = get_component_type(*c); + if(t>=get_component_type(ATTRIB1)) + t -= get_component_type(ATTRIB1); + mask |= 1<>ATTRIB_SHIFT; am; ++i, am>>=1) + if(am&1) + { + if(direct) + glDisableVertexArrayAttrib(id, i); + else + glDisableVertexAttribArray(i); + } + } + if(mask&VERTEX_ARRAY) update_vertex_array(*vertex_array, 0, 0, direct); - if(mask&INSTANCE_ARRAY) - { - if(inst_array) - update_vertex_array(*inst_array, 1, 1, direct); - } + if((mask&INSTANCE_ARRAY) && inst_array) + update_vertex_array(*inst_array, 1, 1, direct); if(mask&INDEX_BUFFER) { diff --git a/source/vertexsetup.h b/source/vertexsetup.h index 9e7409ac..bae4c5f3 100644 --- a/source/vertexsetup.h +++ b/source/vertexsetup.h @@ -2,6 +2,7 @@ #define MSP_GL_VERTEXSETUP_H_ #include "bindable.h" +#include "vertexformat.h" namespace Msp { namespace GL { @@ -19,13 +20,17 @@ private: { VERTEX_ARRAY = 1, INSTANCE_ARRAY = 2, - INDEX_BUFFER = 4 + INDEX_BUFFER = 4, + UNUSED_ATTRIBS = 8, + ATTRIB_SHIFT = 4 }; unsigned id; mutable unsigned dirty; const VertexArray *vertex_array; + VertexFormat vertex_format; const VertexArray *inst_array; + VertexFormat inst_format; const Buffer *index_buffer; public: @@ -35,11 +40,14 @@ public: void set_vertex_array(const VertexArray &); void set_instance_array(const VertexArray *); void set_index_buffer(const Buffer &); + void refresh(); const VertexArray *get_vertex_array() const { return vertex_array; } const VertexArray *get_instance_array() const { return inst_array; } const Buffer *get_index_buffer() const { return index_buffer; } private: + static unsigned get_attribs(const VertexFormat &); + static unsigned get_update_mask(unsigned, const VertexFormat &, const VertexArray &); void update(unsigned) const; void update_vertex_array(const VertexArray &, unsigned, unsigned, bool) const; -- 2.43.0