1 #include <msp/gl/extensions/arb_direct_state_access.h>
2 #include <msp/gl/extensions/arb_sampler_objects.h>
3 #include <msp/gl/extensions/arb_shadow.h>
4 #include <msp/gl/extensions/ext_texture_filter_anisotropic.h>
5 #include <msp/gl/extensions/ext_texture3d.h>
6 #include <msp/gl/extensions/khr_debug.h>
7 #include <msp/strings/format.h>
18 min_filter(NEAREST_MIPMAP_LINEAR),
24 border_color(Color(0.0f, 0.0f, 0.0f, 0.0f)),
29 Require _req(ARB_sampler_objects);
30 if(ARB_direct_state_access)
31 glCreateSamplers(1, &id);
33 glGenSamplers(1, &id);
36 void Sampler::update() const
38 if(dirty_params&MIN_FILTER)
39 glSamplerParameteri(id, GL_TEXTURE_MIN_FILTER, min_filter);
40 if(dirty_params&MAG_FILTER)
41 glSamplerParameteri(id, GL_TEXTURE_MAG_FILTER, mag_filter);
42 if(dirty_params&MAX_ANISOTROPY)
43 glSamplerParameterf(id, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy);
44 if(dirty_params&WRAP_S)
45 glSamplerParameteri(id, GL_TEXTURE_WRAP_S, wrap_s);
46 if(dirty_params&WRAP_T)
47 glSamplerParameteri(id, GL_TEXTURE_WRAP_T, wrap_t);
48 if(dirty_params&WRAP_R)
49 glSamplerParameteri(id, GL_TEXTURE_WRAP_R, wrap_r);
50 if(dirty_params&BORDER_COLOR)
51 glSamplerParameterfv(id, GL_TEXTURE_BORDER_COLOR, &border_color.r);
52 if(dirty_params&COMPARE)
54 glSamplerParameteri(id, GL_TEXTURE_COMPARE_MODE, (compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE));
56 glSamplerParameteri(id, GL_TEXTURE_COMPARE_FUNC, get_gl_predicate(cmp_func));
62 void Sampler::set_min_filter(TextureFilter f)
65 dirty_params |= MIN_FILTER;
68 void Sampler::set_mag_filter(TextureFilter f)
71 dirty_params |= MAG_FILTER;
74 void Sampler::set_filter(TextureFilter f)
77 set_mag_filter(f==NEAREST ? NEAREST : LINEAR);
80 void Sampler::set_max_anisotropy(float a)
83 throw invalid_argument("Sampler::set_max_anisotropy");
85 static Require _req(EXT_texture_filter_anisotropic);
87 if(EXT_texture_filter_anisotropic)
88 dirty_params |= MAX_ANISOTROPY;
91 void Sampler::set_wrap(TextureWrap w)
99 void Sampler::set_wrap_s(TextureWrap w)
102 dirty_params |= WRAP_S;
105 void Sampler::set_wrap_t(TextureWrap w)
108 dirty_params |= WRAP_T;
111 void Sampler::set_wrap_r(TextureWrap w)
113 static Require _req(EXT_texture3D);
115 dirty_params |= WRAP_R;
118 void Sampler::set_border_color(const Color &c)
121 dirty_params |= BORDER_COLOR;
124 void Sampler::disable_compare()
127 dirty_params |= COMPARE;
130 void Sampler::set_compare(Predicate f)
132 static Require _req(ARB_shadow);
135 dirty_params |= COMPARE;
138 void Sampler::set_debug_name(const string &name)
142 glObjectLabel(GL_SAMPLER, id, name.size(), name.c_str());
149 Sampler::Loader::Loader(Sampler &s):
150 DataFile::ObjectLoader<Sampler>(s)
152 add("border_color", &Loader::border_color);
153 add("compare", &Loader::compare);
154 add("filter", &Loader::filter);
155 add("mag_filter", &Loader::mag_filter);
156 add("max_anisotropy", &Loader::max_anisotropy);
157 add("min_filter", &Loader::min_filter);
158 add("wrap", &Loader::wrap);
159 add("wrap_r", &Loader::wrap_r);
160 add("wrap_s", &Loader::wrap_s);
161 add("wrap_t", &Loader::wrap_t);
164 void Sampler::Loader::border_color(float r, float g, float b, float a)
166 obj.set_border_color(Color(r, g, b, a));
169 void Sampler::Loader::compare(Predicate c)
174 void Sampler::Loader::filter(TextureFilter f)
179 void Sampler::Loader::mag_filter(TextureFilter f)
181 obj.set_mag_filter(f);
184 void Sampler::Loader::max_anisotropy(float a)
186 obj.set_max_anisotropy(a);
189 void Sampler::Loader::min_filter(TextureFilter f)
191 obj.set_min_filter(f);
194 void Sampler::Loader::wrap(TextureWrap w)
199 void Sampler::Loader::wrap_r(TextureWrap w)
204 void Sampler::Loader::wrap_s(TextureWrap w)
209 void Sampler::Loader::wrap_t(TextureWrap w)
215 bool is_mipmapped(TextureFilter filter)
217 return (filter==NEAREST_MIPMAP_NEAREST || filter==NEAREST_MIPMAP_LINEAR ||
218 filter==LINEAR_MIPMAP_NEAREST || filter==LINEAR_MIPMAP_LINEAR);
221 void operator>>(const LexicalConverter &c, TextureFilter &tf)
223 if(c.get()=="NEAREST")
225 else if(c.get()=="LINEAR")
227 else if(c.get()=="NEAREST_MIPMAP_NEAREST")
228 tf = NEAREST_MIPMAP_NEAREST;
229 else if(c.get()=="NEAREST_MIPMAP_LINEAR")
230 tf = NEAREST_MIPMAP_LINEAR;
231 else if(c.get()=="LINEAR_MIPMAP_NEAREST")
232 tf = LINEAR_MIPMAP_NEAREST;
233 else if(c.get()=="LINEAR_MIPMAP_LINEAR")
234 tf = LINEAR_MIPMAP_LINEAR;
236 throw lexical_error(format("conversion of '%s' to TextureFilter", c.get()));
239 void operator>>(const LexicalConverter &c, TextureWrap &tw)
241 if(c.get()=="REPEAT")
243 else if(c.get()=="CLAMP_TO_EDGE")
245 else if(c.get()=="CLAMP_TO_BORDER")
246 tw = CLAMP_TO_BORDER;
247 else if(c.get()=="MIRRORED_REPEAT")
248 tw = MIRRORED_REPEAT;
250 throw lexical_error(format("conversion of '%s' to TextureWrap", c.get()));