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"
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):
31 use_srgb_format(false),
32 auto_gen_mipmap(false)
43 glDeleteTextures(1, &id);
46 void Texture::generate_id()
49 throw invalid_operation("Texture::generate_id");
50 if(ARB_direct_state_access)
51 glCreateTextures(target, 1, &id);
53 glGenTextures(1, &id);
56 if(!debug_name.empty() && KHR_debug)
57 glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
61 void Texture::set_format(PixelFormat fmt)
63 PixelComponents comp = get_components(fmt);
64 PixelComponents st_comp = comp;
65 FormatSwizzle swiz = NO_SWIZZLE;
70 swiz = R_TO_LUMINANCE;
74 swiz = RG_TO_LUMINANCE_ALPHA;
87 PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
88 require_pixelformat(st_fmt);
90 static Require _req(ARB_texture_swizzle);
97 void Texture::apply_swizzle()
99 if(swizzle==NO_SWIZZLE)
102 if(get_gl_api()==OPENGL_ES2)
104 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
105 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
106 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
107 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
111 if(ARB_direct_state_access)
112 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
114 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
118 void Texture::set_parameter_i(GLenum param, int value) const
120 if(ARB_direct_state_access)
121 glTextureParameteri(id, param, value);
123 glTexParameteri(target, param, value);
126 bool Texture::can_generate_mipmap()
128 return EXT_framebuffer_object;
131 void Texture::generate_mipmap()
133 // glGenerateMipmap is defined here
134 static Require _req(EXT_framebuffer_object);
136 if(!ARB_direct_state_access)
138 glActiveTexture(GL_TEXTURE0);
139 glBindTexture(target, id);
142 if(!ARB_direct_state_access)
143 glBindTexture(target, 0);
146 void Texture::generate_mipmap_()
148 if(ARB_direct_state_access)
149 glGenerateTextureMipmap(id);
151 glGenerateMipmap(target);
154 void Texture::set_auto_generate_mipmap(bool gm)
157 static Require _req(EXT_framebuffer_object);
159 auto_gen_mipmap = gm;
162 void Texture::load_image(const string &fn, bool)
167 void Texture::load_image(const string &fn, unsigned lv)
175 void Texture::image(const Graphics::Image &img, bool)
180 void Texture::set_debug_name(const string &name)
185 glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
192 Texture::Loader::Loader(Texture &t):
193 DataFile::CollectionObjectLoader<Texture>(t, 0)
198 Texture::Loader::Loader(Texture &t, Collection &c):
199 DataFile::CollectionObjectLoader<Texture>(t, &c)
204 void Texture::Loader::init()
208 add("external_image", &Loader::external_image);
209 add("external_image_srgb", &Loader::external_image_srgb);
210 add("generate_mipmap", &Loader::generate_mipmap);
211 add("image_data", &Loader::image_data);
212 add("mipmap_levels", &Loader::mipmap_levels);
215 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
217 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
219 throw IO::file_not_found(fn);
223 void Texture::Loader::external_image(const string &fn)
225 obj.use_srgb_format = false;
226 external_image_common(fn);
229 void Texture::Loader::external_image_srgb(const string &fn)
231 obj.use_srgb_format = true;
232 external_image_common(fn);
235 void Texture::Loader::external_image_common(const string &fn)
238 obj.manager->set_resource_location(obj, get_collection(), fn);
242 load_external_image(img, fn);
243 obj.image(img, levels);
247 void Texture::Loader::generate_mipmap(bool gm)
249 obj.set_auto_generate_mipmap(gm);
252 void Texture::Loader::image_data(const string &data)
262 IO::Memory mem(data.data(), data.size());
265 obj.image(img, levels);
268 void Texture::Loader::mipmap_levels(unsigned l)