namespace Msp {
namespace GL {
+Sampler::Sampler():
+ owner(0)
+{
+ init();
+
+ Require _req(ARB_sampler_objects);
+ if(ARB_direct_state_access)
+ glCreateSamplers(1, &id);
+ else
+ glGenSamplers(1, &id);
+}
+
Sampler::Sampler(const Texture &tex):
id(0),
owner(&tex)
void Sampler::update_parameter(int mask) const
{
- if(!owner->get_id() || (!ARB_direct_state_access && TexUnit::current().get_texture()!=owner))
+ if(owner)
{
- TexUnit *unit = TexUnit::find_unit(owner);
- if(!unit)
+ if(!owner->get_id())
{
dirty_params |= mask;
return;
}
- unit->bind();
+ if(!ARB_direct_state_access && TexUnit::current().get_texture()!=owner)
+ {
+ TexUnit *unit = TexUnit::find_unit(owner);
+ if(!unit)
+ {
+ dirty_params |= mask;
+ return;
+ }
+
+ unit->bind();
+ }
}
if(mask&MIN_FILTER)
void Sampler::set_parameter_i(unsigned param, int value) const
{
- if(ARB_direct_state_access)
+ if(id)
+ glSamplerParameteri(id, param, value);
+ else if(ARB_direct_state_access)
glTextureParameteri(owner->get_id(), param, value);
else
glTexParameteri(owner->get_target(), param, value);
void Sampler::set_parameter_f(unsigned param, float value) const
{
- if(ARB_direct_state_access)
+ if(id)
+ glSamplerParameterf(id, param, value);
+ else if(ARB_direct_state_access)
glTextureParameterf(owner->get_id(), param, value);
else
glTexParameterf(owner->get_target(), param, value);
void Sampler::bind_to(unsigned i) const
{
TexUnit &unit = TexUnit::get_unit(i);
- if(owner!=unit.get_texture())
+ if(owner && owner!=unit.get_texture())
throw invalid_operation("Sampler::bind_to");
- if(dirty_params)
+ const Sampler *cur = unit.get_sampler();
+ if(unit.set_sampler(this))
{
- update_parameter(dirty_params);
- dirty_params = 0;
+ if(!owner || (cur && cur->id))
+ glBindSampler(i, id);
+
+ if(dirty_params)
+ {
+ update_parameter(dirty_params);
+ dirty_params = 0;
+ }
}
}
+const Sampler *Sampler::current(unsigned i)
+{
+ return TexUnit::get_unit(i).get_sampler();
+}
+
+void Sampler::unbind_from(unsigned i)
+{
+ TexUnit &unit = TexUnit::get_unit(i);
+ const Sampler *cur = unit.get_sampler();
+ if(unit.set_sampler(0) && cur->id)
+ glBindSampler(i, 0);
+}
+
void Sampler::unload()
{
- // TODO check which params actually need refreshing
- if(!owner->get_id())
- dirty_params = -1;
+ if(owner && !owner->get_id())
+ {
+ if(min_filter!=NEAREST_MIPMAP_LINEAR)
+ dirty_params |= MIN_FILTER;
+ if(mag_filter!=LINEAR)
+ dirty_params |= MAG_FILTER;
+ if(max_anisotropy!=1.0f)
+ dirty_params |= MAX_ANISOTROPY;
+ if(wrap_s!=REPEAT)
+ dirty_params |= WRAP_S;
+ if(wrap_t!=REPEAT)
+ dirty_params |= WRAP_T;
+ if(wrap_r!=REPEAT)
+ dirty_params |= WRAP_R;
+ if(compare || cmp_func!=LEQUAL)
+ dirty_params |= COMPARE;
+ }
}