From b856ccc893a102536048e8d67a6577a31ebdf166 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 25 May 2020 18:17:28 +0300 Subject: [PATCH] Change Texturing to store index-texture pairs Modern GPUs have a large number of texture binding points so storing texture pointers for all of them is inefficient. --- source/texturing.cpp | 90 ++++++++++++++++++++++++++++++-------------- source/texturing.h | 16 ++++---- 2 files changed, 71 insertions(+), 35 deletions(-) diff --git a/source/texturing.cpp b/source/texturing.cpp index dff3757f..d8d178b3 100644 --- a/source/texturing.cpp +++ b/source/texturing.cpp @@ -23,36 +23,46 @@ void Texturing::detach(unsigned attch) set_attachment(attch, 0); } -void Texturing::set_attachment(unsigned attch, const Texture *tex) +void Texturing::set_attachment(unsigned unit, const Texture *tex) { - if(attch>=TexUnit::get_n_units()) + if(unit>=TexUnit::get_n_units()) throw out_of_range("Texturing::set_attachment"); - if(attachments.size()<=attch) - attachments.resize(attch+1); - - attachments[attch] = tex; - - if(current()==this) - bind_attachment(attch); -} - -const Texture *Texturing::get_attached_texture(unsigned i) const -{ - return i::iterator i; + for(i=attachments.begin(); (i!=attachments.end() && i->unit<=unit); ++i) + if(i->unit==unit) + { + i->texture = tex; + if(current()==this) + tex->bind_to(unit); + return; + } -void Texturing::bind_attachment(unsigned i) const -{ - if(const Texture *tex = attachments[i]) - tex->bind_to(i); + attachments.insert(i, Attachment(unit, tex)); + if(current()==this) + tex->bind_to(unit); + } else - Texture::unbind_from(i); + { + for(vector::iterator i=attachments.begin(); (i!=attachments.end() && i->unit<=unit); ++i) + if(i->unit==unit) + { + attachments.erase(i); + if(current()==this) + Texture::unbind_from(unit); + return; + } + } } -void Texturing::unbind_attachment(unsigned i) +const Texture *Texturing::get_attached_texture(unsigned unit) const { - Texture::unbind_from(i); + for(vector::const_iterator i=attachments.begin(); (i!=attachments.end() && i->unit<=unit); ++i) + if(i->unit==unit) + return i->texture; + return 0; } void Texturing::bind() const @@ -60,12 +70,30 @@ void Texturing::bind() const const Texturing *old = current(); if(set_current(this)) { - for(unsigned i=0; iattachments.size(); ++i) - unbind_attachment(i); + vector::const_iterator i = attachments.begin(); + vector::const_iterator j = old->attachments.begin(); + while(i!=attachments.end() || j!=old->attachments.end()) + { + if(i!=attachments.end() && (j==old->attachments.end() || i->unit<=j->unit)) + { + i->texture->bind_to(i->unit); + if(j!=old->attachments.end() && j->unit==i->unit) + ++j; + ++i; + } + else + { + Texture::unbind_from(j->unit); + ++j; + } + } + } + else + { + for(vector::const_iterator i=attachments.begin(); i!=attachments.end(); ++i) + i->texture->bind_to(i->unit); } } } @@ -75,10 +103,16 @@ void Texturing::unbind() const Texturing *old = current(); if(set_current(0)) { - for(unsigned i=old->attachments.size(); i--;) - unbind_attachment(i); + for(vector::const_iterator i=old->attachments.begin(); i!=old->attachments.end(); ++i) + Texture::unbind_from(i->unit); } } + +Texturing::Attachment::Attachment(unsigned u, const Texture *t): + unit(u), + texture(t) +{ } + } // namespace GL } // namespace Msp; diff --git a/source/texturing.h b/source/texturing.h index 0b3a9751..79647f1d 100644 --- a/source/texturing.h +++ b/source/texturing.h @@ -12,7 +12,15 @@ class Texture; class Texturing: public Bindable { private: - std::vector attachments; + struct Attachment + { + unsigned unit; + const Texture *texture; + + Attachment(unsigned, const Texture *); + }; + + std::vector attachments; public: ~Texturing(); @@ -24,12 +32,6 @@ private: public: const Texture *get_attached_texture(unsigned) const; -private: - void bind_attachment(unsigned) const; - - static void unbind_attachment(unsigned); - -public: void bind() const; static void unbind(); -- 2.43.0