1 #include <msp/gl/extensions/arb_direct_state_access.h>
2 #include <msp/gl/extensions/arb_texture_swizzle.h>
3 #include <msp/gl/extensions/ext_framebuffer_object.h>
4 #include <msp/io/memory.h>
7 #include "resourcemanager.h"
17 int Texture::swizzle_orders[] =
19 GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA,
20 GL_RED, GL_RED, GL_RED, GL_ONE,
21 GL_RED, GL_RED, GL_RED, GL_GREEN
24 Texture::Texture(GLenum t, ResourceManager *m):
28 auto_gen_mipmap(false),
30 default_sampler(*this)
34 else if(ARB_direct_state_access)
35 glCreateTextures(target, 1, &id);
37 glGenTextures(1, &id);
42 while(TexUnit *unit = TexUnit::find_unit(this))
43 unbind_from(unit->get_index());
46 glDeleteTextures(1, &id);
49 DataType Texture::get_alloc_type(PixelFormat fmt)
51 return (get_base_pixelformat(fmt)==DEPTH_COMPONENT ? UNSIGNED_SHORT : UNSIGNED_BYTE);
54 void Texture::set_internal_format(PixelFormat fmt)
56 FormatSwizzle swiz = NO_SWIZZLE;
57 if(ARB_texture_rg && ARB_texture_swizzle)
62 swiz = R_TO_LUMINANCE;
64 else if(fmt==LUMINANCE_ALPHA)
67 swiz = RG_TO_LUMINANCE_ALPHA;
71 if(!get_component_size(fmt) && OES_required_internalformat)
72 fmt = get_default_sized_pixelformat(fmt);
74 require_pixelformat(fmt);
78 update_parameter(FORMAT_SWIZZLE);
81 PixelFormat Texture::get_upload_format(PixelFormat fmt) const
83 if(fmt==LUMINANCE || fmt==LUMINANCE_ALPHA)
84 return get_base_pixelformat(ifmt);
89 void Texture::update_parameter(int mask) const
97 if(!ARB_direct_state_access && TexUnit::current().get_texture()!=this)
99 TexUnit *unit = TexUnit::find_unit(this);
102 dirty_params |= mask;
109 if(mask&FORMAT_SWIZZLE)
111 if(get_gl_api()==OPENGL_ES2)
113 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
114 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
115 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
116 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
120 if(ARB_direct_state_access)
121 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
123 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
128 void Texture::set_parameter_i(GLenum param, int value) const
130 if(ARB_direct_state_access)
131 glTextureParameteri(id, param, value);
133 glTexParameteri(target, param, value);
136 void Texture::set_parameter_f(GLenum param, float value) const
138 if(ARB_direct_state_access)
139 glTextureParameterf(id, param, value);
141 glTexParameterf(target, param, value);
144 void Texture::set_min_filter(TextureFilter f)
146 default_sampler.set_min_filter(f);
149 void Texture::set_mag_filter(TextureFilter f)
151 default_sampler.set_mag_filter(f);
154 void Texture::set_filter(TextureFilter f)
156 default_sampler.set_filter(f);
159 void Texture::set_max_anisotropy(float a)
161 default_sampler.set_max_anisotropy(a);
164 void Texture::set_wrap(TextureWrap w)
166 default_sampler.set_wrap(w);
169 void Texture::set_wrap_s(TextureWrap w)
171 default_sampler.set_wrap_s(w);
174 void Texture::set_wrap_t(TextureWrap w)
176 default_sampler.set_wrap_t(w);
179 void Texture::set_wrap_r(TextureWrap w)
181 default_sampler.set_wrap_r(w);
184 bool Texture::can_generate_mipmap()
186 return EXT_framebuffer_object;
189 void Texture::generate_mipmap()
191 // glGenerateMipmap is defined here
192 static Require _req(EXT_framebuffer_object);
194 if(ARB_direct_state_access)
195 glGenerateTextureMipmap(id);
198 BindRestore _bind(this);
199 glGenerateMipmap(target);
203 void Texture::set_auto_generate_mipmap(bool gm)
206 static Require _req(EXT_framebuffer_object);
208 auto_gen_mipmap = gm;
211 void Texture::set_compare_enabled(bool c)
214 default_sampler.set_compare(default_sampler.get_compare_function());
216 default_sampler.disable_compare();
219 void Texture::set_compare_func(Predicate f)
221 default_sampler.set_compare(f);
224 void Texture::load_image(const string &fn, bool srgb)
226 load_image(fn, 0, srgb);
229 void Texture::load_image(const string &fn, unsigned lv, bool srgb)
234 image(img, lv, srgb);
237 void Texture::image(const Graphics::Image &img, bool srgb)
242 void Texture::bind_to(unsigned i) const
247 manager->resource_used(*this);
255 TexUnit &unit = TexUnit::get_unit(i);
256 if(unit.set_texture(this))
259 manager->resource_used(*this);
261 if(ARB_direct_state_access)
262 glBindTextureUnit(i, id);
266 glBindTexture(target, id);
271 update_parameter(dirty_params);
275 default_sampler.bind_to(i);
279 const Texture *Texture::current(unsigned i)
281 return TexUnit::get_unit(i).get_texture();
284 void Texture::unbind_from(unsigned i)
286 TexUnit &unit = TexUnit::get_unit(i);
287 const Texture *cur = unit.get_texture();
288 if(unit.set_texture(0))
290 if(ARB_direct_state_access)
291 glBindTextureUnit(i, 0);
295 glBindTexture(cur->target, 0);
301 Texture::Loader::Loader(Texture &t):
302 DataFile::CollectionObjectLoader<Texture>(t, 0)
307 Texture::Loader::Loader(Texture &t, Collection &c):
308 DataFile::CollectionObjectLoader<Texture>(t, &c)
313 void Texture::Loader::init()
316 if(Resources *res = dynamic_cast<Resources *>(coll))
317 srgb = res->get_srgb_conversion();
321 add("external_image", &Loader::external_image);
322 add("filter", &Loader::filter);
323 add("generate_mipmap", &Loader::generate_mipmap);
324 add("image_data", &Loader::image_data);
325 add("mag_filter", &Loader::mag_filter);
326 add("max_anisotropy", &Loader::max_anisotropy);
327 add("min_filter", &Loader::min_filter);
328 add("mipmap_levels", &Loader::mipmap_levels);
329 add("sampler", &Loader::sampler);
330 add("wrap", &Loader::wrap);
331 add("wrap_r", &Loader::wrap_r);
332 add("wrap_s", &Loader::wrap_s);
333 add("wrap_t", &Loader::wrap_t);
336 unsigned Texture::Loader::get_levels() const
338 return (is_mipmapped(obj.default_sampler.get_min_filter()) ? levels : 1);
341 #pragma GCC diagnostic push
342 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
343 void Texture::Loader::external_image(const string &fn)
346 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
348 throw IO::file_not_found(fn);
351 obj.image(img, get_levels(), srgb);
354 void Texture::Loader::filter(TextureFilter f)
359 void Texture::Loader::generate_mipmap(bool gm)
361 obj.set_auto_generate_mipmap(gm);
364 void Texture::Loader::image_data(const string &data)
367 IO::Memory mem(data.data(), data.size());
370 obj.image(img, get_levels(), srgb);
373 void Texture::Loader::mag_filter(TextureFilter f)
375 obj.set_mag_filter(f);
378 void Texture::Loader::max_anisotropy(float a)
380 obj.set_max_anisotropy(a);
383 void Texture::Loader::min_filter(TextureFilter f)
385 obj.set_min_filter(f);
388 void Texture::Loader::mipmap_levels(unsigned l)
393 void Texture::Loader::sampler()
395 load_sub(obj.default_sampler);
398 void Texture::Loader::wrap(TextureWrap w)
403 void Texture::Loader::wrap_r(TextureWrap w)
408 void Texture::Loader::wrap_s(TextureWrap w)
413 void Texture::Loader::wrap_t(TextureWrap w)
417 #pragma GCC diagnostic pop