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>
7 #include "resourcemanager.h"
16 int Texture::swizzle_orders[] =
18 GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA,
19 GL_RED, GL_RED, GL_RED, GL_ONE,
20 GL_RED, GL_RED, GL_RED, GL_GREEN,
21 GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA
24 Texture::Texture(GLenum t, ResourceManager *m):
30 use_srgb_format(false),
31 auto_gen_mipmap(false)
38 static bool alignment_init = false;
41 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
42 alignment_init = true;
49 glDeleteTextures(1, &id);
52 void Texture::generate_id()
55 throw invalid_operation("Texture::generate_id");
56 if(ARB_direct_state_access)
57 glCreateTextures(target, 1, &id);
59 glGenTextures(1, &id);
62 if(!debug_name.empty() && KHR_debug)
63 glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
67 void Texture::set_format(PixelFormat fmt)
69 PixelComponents comp = get_components(fmt);
70 PixelComponents st_comp = comp;
71 FormatSwizzle swiz = NO_SWIZZLE;
76 swiz = R_TO_LUMINANCE;
80 swiz = RG_TO_LUMINANCE_ALPHA;
93 PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
94 require_pixelformat(st_fmt);
96 static Require _req(ARB_texture_swizzle);
103 void Texture::apply_swizzle()
105 if(swizzle==NO_SWIZZLE)
108 if(get_gl_api()==OPENGL_ES2)
110 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
111 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
112 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
113 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
117 if(ARB_direct_state_access)
118 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
120 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
124 void Texture::set_parameter_i(GLenum param, int value) const
126 if(ARB_direct_state_access)
127 glTextureParameteri(id, param, value);
129 glTexParameteri(target, param, value);
132 bool Texture::can_generate_mipmap()
134 return EXT_framebuffer_object;
137 void Texture::generate_mipmap()
139 // glGenerateMipmap is defined here
140 static Require _req(EXT_framebuffer_object);
142 if(!ARB_direct_state_access)
144 glActiveTexture(GL_TEXTURE0);
145 glBindTexture(target, id);
148 if(!ARB_direct_state_access)
149 glBindTexture(target, 0);
152 void Texture::generate_mipmap_()
154 if(ARB_direct_state_access)
155 glGenerateTextureMipmap(id);
157 glGenerateMipmap(target);
160 void Texture::set_auto_generate_mipmap(bool gm)
163 static Require _req(EXT_framebuffer_object);
165 auto_gen_mipmap = gm;
168 void Texture::load_image(const string &fn, bool)
173 void Texture::load_image(const string &fn, unsigned lv)
181 void Texture::image(const Graphics::Image &img, bool)
186 void Texture::set_debug_name(const string &name)
191 glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
198 Texture::Loader::Loader(Texture &t):
199 DataFile::CollectionObjectLoader<Texture>(t, 0)
204 Texture::Loader::Loader(Texture &t, Collection &c):
205 DataFile::CollectionObjectLoader<Texture>(t, &c)
210 void Texture::Loader::init()
214 add("external_image", &Loader::external_image);
215 add("external_image_srgb", &Loader::external_image_srgb);
216 add("generate_mipmap", &Loader::generate_mipmap);
217 add("image_data", &Loader::image_data);
218 add("mipmap_levels", &Loader::mipmap_levels);
221 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
223 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
225 throw IO::file_not_found(fn);
229 void Texture::Loader::external_image(const string &fn)
231 obj.use_srgb_format = false;
232 external_image_common(fn);
235 void Texture::Loader::external_image_srgb(const string &fn)
237 obj.use_srgb_format = true;
238 external_image_common(fn);
241 void Texture::Loader::external_image_common(const string &fn)
244 obj.manager->set_resource_location(obj, get_collection(), fn);
248 load_external_image(img, fn);
249 obj.image(img, levels);
253 void Texture::Loader::generate_mipmap(bool gm)
255 obj.set_auto_generate_mipmap(gm);
258 void Texture::Loader::image_data(const string &data)
268 IO::Memory mem(data.data(), data.size());
271 obj.image(img, levels);
274 void Texture::Loader::mipmap_levels(unsigned l)