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):
29 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)
57 if(ARB_texture_rg && ARB_texture_swizzle)
62 swizzle = R_TO_LUMINANCE;
64 else if(fmt==LUMINANCE_ALPHA)
67 swizzle = 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 PixelFormat Texture::get_upload_format(PixelFormat fmt) const
80 if(fmt==LUMINANCE || fmt==LUMINANCE_ALPHA)
81 return get_base_pixelformat(ifmt);
86 void Texture::apply_swizzle()
88 if(swizzle==NO_SWIZZLE)
91 if(get_gl_api()==OPENGL_ES2)
93 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
94 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
95 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
96 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
100 if(ARB_direct_state_access)
101 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
103 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
107 void Texture::set_parameter_i(GLenum param, int value) const
109 if(ARB_direct_state_access)
110 glTextureParameteri(id, param, value);
112 glTexParameteri(target, param, value);
115 void Texture::set_min_filter(TextureFilter f)
117 default_sampler.set_min_filter(f);
120 void Texture::set_mag_filter(TextureFilter f)
122 default_sampler.set_mag_filter(f);
125 void Texture::set_filter(TextureFilter f)
127 default_sampler.set_filter(f);
130 void Texture::set_max_anisotropy(float a)
132 default_sampler.set_max_anisotropy(a);
135 void Texture::set_wrap(TextureWrap w)
137 default_sampler.set_wrap(w);
140 void Texture::set_wrap_s(TextureWrap w)
142 default_sampler.set_wrap_s(w);
145 void Texture::set_wrap_t(TextureWrap w)
147 default_sampler.set_wrap_t(w);
150 void Texture::set_wrap_r(TextureWrap w)
152 default_sampler.set_wrap_r(w);
155 bool Texture::can_generate_mipmap()
157 return EXT_framebuffer_object;
160 void Texture::generate_mipmap()
162 // glGenerateMipmap is defined here
163 static Require _req(EXT_framebuffer_object);
165 if(ARB_direct_state_access)
166 glGenerateTextureMipmap(id);
169 BindRestore _bind(this);
170 glGenerateMipmap(target);
174 void Texture::set_auto_generate_mipmap(bool gm)
177 static Require _req(EXT_framebuffer_object);
179 auto_gen_mipmap = gm;
182 void Texture::set_compare_enabled(bool c)
185 default_sampler.set_compare(default_sampler.get_compare_function());
187 default_sampler.disable_compare();
190 void Texture::set_compare_func(Predicate f)
192 default_sampler.set_compare(f);
195 void Texture::load_image(const string &fn, bool srgb)
197 load_image(fn, 0, srgb);
200 void Texture::load_image(const string &fn, unsigned lv, bool srgb)
205 image(img, lv, srgb);
208 void Texture::image(const Graphics::Image &img, bool srgb)
213 void Texture::bind_to(unsigned i) const
218 manager->resource_used(*this);
226 TexUnit &unit = TexUnit::get_unit(i);
227 if(unit.set_texture(this))
230 manager->resource_used(*this);
232 if(ARB_direct_state_access)
233 glBindTextureUnit(i, id);
237 glBindTexture(target, id);
240 default_sampler.bind_to(i);
244 const Texture *Texture::current(unsigned i)
246 return TexUnit::get_unit(i).get_texture();
249 void Texture::unbind_from(unsigned i)
251 TexUnit &unit = TexUnit::get_unit(i);
252 const Texture *cur = unit.get_texture();
253 if(unit.set_texture(0))
255 if(ARB_direct_state_access)
256 glBindTextureUnit(i, 0);
260 glBindTexture(cur->target, 0);
266 Texture::Loader::Loader(Texture &t):
267 DataFile::CollectionObjectLoader<Texture>(t, 0)
272 Texture::Loader::Loader(Texture &t, Collection &c):
273 DataFile::CollectionObjectLoader<Texture>(t, &c)
278 void Texture::Loader::init()
281 if(Resources *res = dynamic_cast<Resources *>(coll))
282 srgb = res->get_srgb_conversion();
286 add("external_image", &Loader::external_image);
287 add("filter", &Loader::filter);
288 add("generate_mipmap", &Loader::generate_mipmap);
289 add("image_data", &Loader::image_data);
290 add("mag_filter", &Loader::mag_filter);
291 add("max_anisotropy", &Loader::max_anisotropy);
292 add("min_filter", &Loader::min_filter);
293 add("mipmap_levels", &Loader::mipmap_levels);
294 add("sampler", &Loader::sampler);
295 add("wrap", &Loader::wrap);
296 add("wrap_r", &Loader::wrap_r);
297 add("wrap_s", &Loader::wrap_s);
298 add("wrap_t", &Loader::wrap_t);
301 unsigned Texture::Loader::get_levels() const
303 return (is_mipmapped(obj.default_sampler.get_min_filter()) ? levels : 1);
306 #pragma GCC diagnostic push
307 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
308 void Texture::Loader::external_image(const string &fn)
311 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
313 throw IO::file_not_found(fn);
316 obj.image(img, get_levels(), srgb);
319 void Texture::Loader::filter(TextureFilter f)
324 void Texture::Loader::generate_mipmap(bool gm)
326 obj.set_auto_generate_mipmap(gm);
329 void Texture::Loader::image_data(const string &data)
332 IO::Memory mem(data.data(), data.size());
335 obj.image(img, get_levels(), srgb);
338 void Texture::Loader::mag_filter(TextureFilter f)
340 obj.set_mag_filter(f);
343 void Texture::Loader::max_anisotropy(float a)
345 obj.set_max_anisotropy(a);
348 void Texture::Loader::min_filter(TextureFilter f)
350 obj.set_min_filter(f);
353 void Texture::Loader::mipmap_levels(unsigned l)
358 void Texture::Loader::sampler()
360 load_sub(obj.default_sampler);
363 void Texture::Loader::wrap(TextureWrap w)
368 void Texture::Loader::wrap_r(TextureWrap w)
373 void Texture::Loader::wrap_s(TextureWrap w)
378 void Texture::Loader::wrap_t(TextureWrap w)
382 #pragma GCC diagnostic pop