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,
22 GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA
25 Texture::Texture(GLenum t, ResourceManager *m):
30 auto_gen_mipmap(false),
31 default_sampler(*this)
35 else if(ARB_direct_state_access)
36 glCreateTextures(target, 1, &id);
38 glGenTextures(1, &id);
43 while(TexUnit *unit = TexUnit::find_unit(this))
44 unbind_from(unit->get_index());
47 glDeleteTextures(1, &id);
50 void Texture::set_internal_format(PixelFormat fmt)
52 PixelComponents comp = get_components(fmt);
53 FormatSwizzle swiz = NO_SWIZZLE;
58 swiz = R_TO_LUMINANCE;
62 swiz = RG_TO_LUMINANCE_ALPHA;
75 fmt = make_pixelformat(comp, get_component_type(fmt));
76 require_pixelformat(fmt);
78 static Require _req(ARB_texture_swizzle);
83 PixelComponents Texture::get_upload_components(PixelComponents comp) const
85 if(comp==LUMINANCE || comp==LUMINANCE_ALPHA || comp==BGR || comp==BGRA)
86 return get_components(ifmt);
91 void Texture::apply_swizzle()
93 if(swizzle==NO_SWIZZLE)
96 if(get_gl_api()==OPENGL_ES2)
98 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
99 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
100 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
101 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
105 if(ARB_direct_state_access)
106 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
108 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
112 void Texture::set_parameter_i(GLenum param, int value) const
114 if(ARB_direct_state_access)
115 glTextureParameteri(id, param, value);
117 glTexParameteri(target, param, value);
120 void Texture::set_min_filter(TextureFilter f)
122 default_sampler.set_min_filter(f);
125 void Texture::set_mag_filter(TextureFilter f)
127 default_sampler.set_mag_filter(f);
130 void Texture::set_filter(TextureFilter f)
132 default_sampler.set_filter(f);
135 void Texture::set_max_anisotropy(float a)
137 default_sampler.set_max_anisotropy(a);
140 void Texture::set_wrap(TextureWrap w)
142 default_sampler.set_wrap(w);
145 void Texture::set_wrap_s(TextureWrap w)
147 default_sampler.set_wrap_s(w);
150 void Texture::set_wrap_t(TextureWrap w)
152 default_sampler.set_wrap_t(w);
155 void Texture::set_wrap_r(TextureWrap w)
157 default_sampler.set_wrap_r(w);
160 bool Texture::can_generate_mipmap()
162 return EXT_framebuffer_object;
165 void Texture::generate_mipmap()
167 // glGenerateMipmap is defined here
168 static Require _req(EXT_framebuffer_object);
170 if(ARB_direct_state_access)
171 glGenerateTextureMipmap(id);
174 BindRestore _bind(this);
175 glGenerateMipmap(target);
179 void Texture::set_auto_generate_mipmap(bool gm)
182 static Require _req(EXT_framebuffer_object);
184 auto_gen_mipmap = gm;
187 void Texture::set_compare_enabled(bool c)
190 default_sampler.set_compare(default_sampler.get_compare_function());
192 default_sampler.disable_compare();
195 void Texture::set_compare_func(Predicate f)
197 default_sampler.set_compare(f);
200 void Texture::load_image(const string &fn, bool srgb)
202 load_image(fn, 0, srgb);
205 void Texture::load_image(const string &fn, unsigned lv, bool srgb)
210 image(img, lv, srgb);
213 void Texture::image(const Graphics::Image &img, bool srgb)
218 void Texture::bind_to(unsigned i) const
223 manager->resource_used(*this);
231 TexUnit &unit = TexUnit::get_unit(i);
232 if(unit.set_texture(this))
235 manager->resource_used(*this);
237 if(ARB_direct_state_access)
238 glBindTextureUnit(i, id);
242 glBindTexture(target, id);
245 default_sampler.bind_to(i);
249 const Texture *Texture::current(unsigned i)
251 return TexUnit::get_unit(i).get_texture();
254 void Texture::unbind_from(unsigned i)
256 TexUnit &unit = TexUnit::get_unit(i);
257 const Texture *cur = unit.get_texture();
258 if(unit.set_texture(0))
260 if(ARB_direct_state_access)
261 glBindTextureUnit(i, 0);
265 glBindTexture(cur->target, 0);
271 Texture::Loader::Loader(Texture &t):
272 DataFile::CollectionObjectLoader<Texture>(t, 0)
277 Texture::Loader::Loader(Texture &t, Collection &c):
278 DataFile::CollectionObjectLoader<Texture>(t, &c)
283 void Texture::Loader::init()
286 if(Resources *res = dynamic_cast<Resources *>(coll))
287 srgb = res->get_srgb_conversion();
291 add("external_image", &Loader::external_image);
292 add("filter", &Loader::filter);
293 add("generate_mipmap", &Loader::generate_mipmap);
294 add("image_data", &Loader::image_data);
295 add("mag_filter", &Loader::mag_filter);
296 add("max_anisotropy", &Loader::max_anisotropy);
297 add("min_filter", &Loader::min_filter);
298 add("mipmap_levels", &Loader::mipmap_levels);
299 add("sampler", &Loader::sampler);
300 add("wrap", &Loader::wrap);
301 add("wrap_r", &Loader::wrap_r);
302 add("wrap_s", &Loader::wrap_s);
303 add("wrap_t", &Loader::wrap_t);
306 unsigned Texture::Loader::get_levels() const
308 return (is_mipmapped(obj.default_sampler.get_min_filter()) ? levels : 1);
311 #pragma GCC diagnostic push
312 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
313 void Texture::Loader::external_image(const string &fn)
316 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
318 throw IO::file_not_found(fn);
321 obj.image(img, get_levels(), srgb);
324 void Texture::Loader::filter(TextureFilter f)
329 void Texture::Loader::generate_mipmap(bool gm)
331 obj.set_auto_generate_mipmap(gm);
334 void Texture::Loader::image_data(const string &data)
337 IO::Memory mem(data.data(), data.size());
340 obj.image(img, get_levels(), srgb);
343 void Texture::Loader::mag_filter(TextureFilter f)
345 obj.set_mag_filter(f);
348 void Texture::Loader::max_anisotropy(float a)
350 obj.set_max_anisotropy(a);
353 void Texture::Loader::min_filter(TextureFilter f)
355 obj.set_min_filter(f);
358 void Texture::Loader::mipmap_levels(unsigned l)
363 void Texture::Loader::sampler()
365 load_sub(obj.default_sampler);
368 void Texture::Loader::wrap(TextureWrap w)
373 void Texture::Loader::wrap_r(TextureWrap w)
378 void Texture::Loader::wrap_s(TextureWrap w)
383 void Texture::Loader::wrap_t(TextureWrap w)
387 #pragma GCC diagnostic pop