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::scratch_binding = 0;
26 Texture::Texture(GLenum t, ResourceManager *m):
32 use_srgb_format(false),
33 auto_gen_mipmap(false)
40 static bool alignment_init = false;
43 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
44 alignment_init = true;
50 if(this==scratch_binding)
53 glDeleteTextures(1, &id);
56 void Texture::generate_id()
59 throw invalid_operation("Texture::generate_id");
60 if(ARB_direct_state_access)
61 glCreateTextures(target, 1, &id);
63 glGenTextures(1, &id);
66 if(!debug_name.empty() && KHR_debug)
67 glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
71 void Texture::set_format(PixelFormat fmt)
73 PixelComponents comp = get_components(fmt);
74 PixelComponents st_comp = comp;
75 FormatSwizzle swiz = NO_SWIZZLE;
80 swiz = R_TO_LUMINANCE;
84 swiz = RG_TO_LUMINANCE_ALPHA;
97 PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
98 require_pixelformat(st_fmt);
100 static Require _req(ARB_texture_swizzle);
103 storage_fmt = st_fmt;
107 void Texture::apply_swizzle()
109 if(swizzle==NO_SWIZZLE)
112 if(get_gl_api()==OPENGL_ES2)
114 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
115 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
116 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
117 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
121 if(ARB_direct_state_access)
122 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
124 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
128 void Texture::set_parameter_i(GLenum param, int value) const
130 if(ARB_direct_state_access)
131 glTextureParameteri(id, param, value);
133 glTexParameteri(target, param, value);
136 void Texture::generate_mipmap()
138 // glGenerateMipmap is defined here
139 static Require _req(EXT_framebuffer_object);
141 if(ARB_direct_state_access)
142 glGenerateTextureMipmap(id);
146 glGenerateMipmap(target);
150 void Texture::load_image(const string &fn, bool)
155 void Texture::load_image(const string &fn, unsigned lv)
163 void Texture::image(const Graphics::Image &img, bool)
168 void Texture::set_debug_name(const string &name)
173 glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
179 void Texture::bind_scratch()
182 glActiveTexture(GL_TEXTURE0);
183 if(scratch_binding!=this)
185 if(scratch_binding && scratch_binding->target!=target)
186 glBindTexture(scratch_binding->target, 0);
187 glBindTexture(target, id);
188 scratch_binding = this;
192 void Texture::unbind_scratch()
196 glBindTexture(scratch_binding->target, 0);
202 Texture::Loader::Loader(Texture &t):
203 DataFile::CollectionObjectLoader<Texture>(t, 0)
208 Texture::Loader::Loader(Texture &t, Collection &c):
209 DataFile::CollectionObjectLoader<Texture>(t, &c)
214 void Texture::Loader::init()
218 add("external_image", &Loader::external_image);
219 add("external_image_srgb", &Loader::external_image_srgb);
220 add("generate_mipmap", &Loader::generate_mipmap);
221 add("image_data", &Loader::image_data);
222 add("mipmap_levels", &Loader::mipmap_levels);
225 void Texture::Loader::finish()
227 if(obj.auto_gen_mipmap)
228 obj.generate_mipmap();
231 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
233 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
235 throw IO::file_not_found(fn);
239 void Texture::Loader::external_image(const string &fn)
241 obj.use_srgb_format = false;
242 external_image_common(fn);
245 void Texture::Loader::external_image_srgb(const string &fn)
247 obj.use_srgb_format = true;
248 external_image_common(fn);
251 void Texture::Loader::external_image_common(const string &fn)
254 obj.manager->set_resource_location(obj, get_collection(), fn);
258 load_external_image(img, fn);
259 obj.image(img, levels);
263 void Texture::Loader::generate_mipmap(bool gm)
265 obj.auto_gen_mipmap = gm;
268 void Texture::Loader::image_data(const string &data)
278 IO::Memory mem(data.data(), data.size());
281 obj.image(img, levels);
284 void Texture::Loader::mipmap_levels(unsigned l)