]> git.tdb.fi Git - libs/gl.git/commitdiff
Change Texturing to store index-texture pairs
authorMikko Rasa <tdb@tdb.fi>
Mon, 25 May 2020 15:17:28 +0000 (18:17 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 25 May 2020 15:17:28 +0000 (18:17 +0300)
Modern GPUs have a large number of texture binding points so storing
texture pointers for all of them is inefficient.

source/texturing.cpp
source/texturing.h

index dff3757fdb6d9b8985234e87241153d94b41a80b..d8d178b385c05e54da6d588df0e4866e6da1a460 100644 (file)
@@ -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<attachments.size() ? attachments[i] : 0;
-}
+       if(tex)
+       {
+               vector<Attachment>::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<Attachment>::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<Attachment>::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; i<attachments.size(); ++i)
-                       bind_attachment(i);
                if(old)
                {
-                       for(unsigned i=attachments.size(); i<old->attachments.size(); ++i)
-                               unbind_attachment(i);
+                       vector<Attachment>::const_iterator i = attachments.begin();
+                       vector<Attachment>::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<Attachment>::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<Attachment>::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;
index 0b3a9751b5f98ebe17f6e55a48fe3d4a998b92c1..79647f1d95a5b0467a106ddac206066f28267111 100644 (file)
@@ -12,7 +12,15 @@ class Texture;
 class Texturing: public Bindable<Texturing>
 {
 private:
-       std::vector<const Texture *> attachments;
+       struct Attachment
+       {
+               unsigned unit;
+               const Texture *texture;
+
+               Attachment(unsigned, const Texture *);
+       };
+
+       std::vector<Attachment> 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();