1 #include <msp/core/hash.h>
11 Texturing::~Texturing()
17 int Texturing::find_free_unit(const string &name_hint) const
19 unsigned max_unit = TexUnit::get_n_units();
20 // Leave some space for effect textures
21 max_unit -= min(max_unit/4, 8U);
22 unsigned initial_unit = (name_hint.empty() ? 0 : hash32(name_hint)%max_unit);
23 unsigned unit = initial_unit;
24 while(get_attached_texture(unit) || get_attached_sampler(unit))
26 unit = (unit+1)%max_unit;
27 if(unit==initial_unit)
34 void Texturing::attach(unsigned attch, const Texture &tex, const Sampler *samp)
36 set_attachment(attch, &tex, samp);
39 void Texturing::attach(unsigned attch, const Sampler &samp)
41 set_attachment(attch, 0, &samp);
44 void Texturing::detach(unsigned attch)
46 set_attachment(attch, 0, 0);
49 void Texturing::set_attachment(unsigned unit, const Texture *tex, const Sampler *samp)
51 if(unit>=TexUnit::get_n_units())
52 throw out_of_range("Texturing::set_attachment");
56 vector<Attachment>::iterator i;
57 for(i=attachments.begin(); (i!=attachments.end() && i->unit<=unit); ++i)
67 attachments.insert(i, Attachment(unit, tex, samp));
73 for(vector<Attachment>::iterator i=attachments.begin(); (i!=attachments.end() && i->unit<=unit); ++i)
78 unbind_attachment(unit);
84 const Texture *Texturing::get_attached_texture(unsigned unit) const
86 for(vector<Attachment>::const_iterator i=attachments.begin(); (i!=attachments.end() && i->unit<=unit); ++i)
92 const Sampler *Texturing::get_attached_sampler(unsigned unit) const
94 for(vector<Attachment>::const_iterator i=attachments.begin(); (i!=attachments.end() && i->unit<=unit); ++i)
100 void Texturing::bind() const
102 const Texturing *old = current();
103 if(set_current(this))
107 vector<Attachment>::const_iterator i = attachments.begin();
108 vector<Attachment>::const_iterator j = old->attachments.begin();
109 while(i!=attachments.end() || j!=old->attachments.end())
111 if(i!=attachments.end() && (j==old->attachments.end() || i->unit<=j->unit))
114 if(j!=old->attachments.end() && j->unit==i->unit)
120 unbind_attachment(j->unit);
127 for(vector<Attachment>::const_iterator i=attachments.begin(); i!=attachments.end(); ++i)
133 void Texturing::bind_attachment(const Attachment &attch) const
136 attch.sampler->bind_to(attch.unit);
138 Sampler::unbind_from(attch.unit);
140 attch.texture->bind_to(attch.unit);
142 Texture::unbind_from(attch.unit);
145 void Texturing::unbind()
147 const Texturing *old = current();
150 for(vector<Attachment>::const_iterator i=old->attachments.begin(); i!=old->attachments.end(); ++i)
151 unbind_attachment(i->unit);
155 void Texturing::unbind_attachment(unsigned unit)
157 Texture::unbind_from(unit);
158 Sampler::unbind_from(unit);
162 Texturing::Attachment::Attachment(unsigned u, const Texture *t, const Sampler *s):