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/gl/extensions/khr_debug.h>
5 #include <msp/io/memory.h>
8 #include "resourcemanager.h"
18 int Texture::swizzle_orders[] =
20 GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA,
21 GL_RED, GL_RED, GL_RED, GL_ONE,
22 GL_RED, GL_RED, GL_RED, GL_GREEN,
23 GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA
26 Texture::Texture(GLenum t, ResourceManager *m):
32 use_srgb_format(false),
33 auto_gen_mipmap(false)
43 while(TexUnit *unit = TexUnit::find_unit(this))
44 unbind_from(unit->get_index());
47 glDeleteTextures(1, &id);
50 void Texture::generate_id()
53 throw invalid_operation("Texture::generate_id");
54 if(ARB_direct_state_access)
55 glCreateTextures(target, 1, &id);
57 glGenTextures(1, &id);
60 if(!debug_name.empty() && KHR_debug)
61 glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
65 void Texture::set_format(PixelFormat fmt)
67 PixelComponents comp = get_components(fmt);
68 PixelComponents st_comp = comp;
69 FormatSwizzle swiz = NO_SWIZZLE;
74 swiz = R_TO_LUMINANCE;
78 swiz = RG_TO_LUMINANCE_ALPHA;
91 PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
92 require_pixelformat(st_fmt);
94 static Require _req(ARB_texture_swizzle);
101 void Texture::apply_swizzle()
103 if(swizzle==NO_SWIZZLE)
106 if(get_gl_api()==OPENGL_ES2)
108 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
109 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
110 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
111 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
115 if(ARB_direct_state_access)
116 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
118 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
122 void Texture::set_parameter_i(GLenum param, int value) const
124 if(ARB_direct_state_access)
125 glTextureParameteri(id, param, value);
127 glTexParameteri(target, param, value);
130 bool Texture::can_generate_mipmap()
132 return EXT_framebuffer_object;
135 void Texture::generate_mipmap()
137 // glGenerateMipmap is defined here
138 static Require _req(EXT_framebuffer_object);
140 if(ARB_direct_state_access)
141 glGenerateTextureMipmap(id);
144 BindRestore _bind(this);
145 glGenerateMipmap(target);
149 void Texture::set_auto_generate_mipmap(bool gm)
152 static Require _req(EXT_framebuffer_object);
154 auto_gen_mipmap = gm;
157 void Texture::load_image(const string &fn, bool)
162 void Texture::load_image(const string &fn, unsigned lv)
170 void Texture::image(const Graphics::Image &img, bool)
175 void Texture::bind_to(unsigned i) const
180 manager->resource_used(*this);
188 TexUnit &unit = TexUnit::get_unit(i);
189 if(unit.set_texture(this))
192 manager->resource_used(*this);
194 if(ARB_direct_state_access)
195 glBindTextureUnit(i, id);
199 glBindTexture(target, id);
204 const Texture *Texture::current(unsigned i)
206 return TexUnit::get_unit(i).get_texture();
209 void Texture::unbind_from(unsigned i)
211 TexUnit &unit = TexUnit::get_unit(i);
212 const Texture *cur = unit.get_texture();
213 if(unit.set_texture(0))
215 if(ARB_direct_state_access)
216 glBindTextureUnit(i, 0);
220 glBindTexture(cur->target, 0);
225 void Texture::set_debug_name(const string &name)
230 glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
237 Texture::Loader::Loader(Texture &t):
238 DataFile::CollectionObjectLoader<Texture>(t, 0)
243 Texture::Loader::Loader(Texture &t, Collection &c):
244 DataFile::CollectionObjectLoader<Texture>(t, &c)
249 void Texture::Loader::init()
253 add("external_image", &Loader::external_image);
254 add("external_image_srgb", &Loader::external_image_srgb);
255 add("generate_mipmap", &Loader::generate_mipmap);
256 add("image_data", &Loader::image_data);
257 add("mipmap_levels", &Loader::mipmap_levels);
260 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
262 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
264 throw IO::file_not_found(fn);
268 void Texture::Loader::external_image(const string &fn)
270 obj.use_srgb_format = false;
271 external_image_common(fn);
274 void Texture::Loader::external_image_srgb(const string &fn)
276 obj.use_srgb_format = true;
277 external_image_common(fn);
280 void Texture::Loader::external_image_common(const string &fn)
283 obj.manager->set_resource_location(obj, get_collection(), fn);
287 load_external_image(img, fn);
288 obj.image(img, levels);
292 void Texture::Loader::generate_mipmap(bool gm)
294 obj.set_auto_generate_mipmap(gm);
297 void Texture::Loader::image_data(const string &data)
307 IO::Memory mem(data.data(), data.size());
310 obj.image(img, levels);
313 void Texture::Loader::mipmap_levels(unsigned l)