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"
15 const int Texture::swizzle_orders[] =
17 GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA,
18 GL_RED, GL_RED, GL_RED, GL_ONE,
19 GL_RED, GL_RED, GL_RED, GL_GREEN,
20 GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA
23 Texture *Texture::scratch_binding = 0;
25 Texture::Texture(GLenum t, ResourceManager *m):
28 format(NO_PIXELFORMAT),
31 use_srgb_format(false),
32 auto_gen_mipmap(false)
39 static bool alignment_init = false;
42 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
43 alignment_init = true;
49 if(this==scratch_binding)
52 glDeleteTextures(1, &id);
55 void Texture::generate_id()
58 throw invalid_operation("Texture::generate_id");
59 if(ARB_direct_state_access)
60 glCreateTextures(target, 1, &id);
62 glGenTextures(1, &id);
65 if(!debug_name.empty() && KHR_debug)
66 glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
70 void Texture::set_format(PixelFormat fmt)
72 PixelComponents comp = get_components(fmt);
73 PixelComponents st_comp = comp;
74 FormatSwizzle swiz = NO_SWIZZLE;
79 swiz = R_TO_LUMINANCE;
83 swiz = RG_TO_LUMINANCE_ALPHA;
96 PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
97 require_pixelformat(st_fmt);
99 static Require _req(ARB_texture_swizzle);
102 storage_fmt = st_fmt;
106 void Texture::apply_swizzle()
108 if(swizzle==NO_SWIZZLE)
111 if(get_backend_api()==OPENGL_ES)
113 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
114 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
115 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
116 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
120 if(ARB_direct_state_access)
121 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
123 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
127 void Texture::set_parameter_i(unsigned param, int value) const
129 if(ARB_direct_state_access)
130 glTextureParameteri(id, param, value);
132 glTexParameteri(target, param, value);
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);
145 glGenerateMipmap(target);
149 void Texture::load_image(const string &fn, unsigned lv)
157 void Texture::set_debug_name(const string &name)
162 glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
168 void Texture::bind_scratch()
171 glActiveTexture(GL_TEXTURE0);
172 if(scratch_binding!=this)
174 if(scratch_binding && scratch_binding->target!=target)
175 glBindTexture(scratch_binding->target, 0);
176 glBindTexture(target, id);
177 scratch_binding = this;
181 void Texture::unbind_scratch()
185 glBindTexture(scratch_binding->target, 0);
191 Texture::Loader::Loader(Texture &t):
192 DataFile::CollectionObjectLoader<Texture>(t, 0)
197 Texture::Loader::Loader(Texture &t, Collection &c):
198 DataFile::CollectionObjectLoader<Texture>(t, &c)
203 void Texture::Loader::init()
207 add("external_image", &Loader::external_image);
208 add("external_image_srgb", &Loader::external_image_srgb);
209 add("generate_mipmap", &Loader::generate_mipmap);
210 add("image_data", &Loader::image_data);
211 add("mipmap_levels", &Loader::mipmap_levels);
214 void Texture::Loader::finish()
216 if(obj.auto_gen_mipmap)
217 obj.generate_mipmap();
220 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
222 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
224 throw IO::file_not_found(fn);
228 void Texture::Loader::external_image(const string &fn)
230 obj.use_srgb_format = false;
231 external_image_common(fn);
234 void Texture::Loader::external_image_srgb(const string &fn)
236 obj.use_srgb_format = true;
237 external_image_common(fn);
240 void Texture::Loader::external_image_common(const string &fn)
243 obj.manager->set_resource_location(obj, get_collection(), fn);
247 load_external_image(img, fn);
248 obj.image(img, levels);
252 void Texture::Loader::generate_mipmap(bool gm)
254 obj.auto_gen_mipmap = gm;
257 void Texture::Loader::image_data(const string &data)
267 IO::Memory mem(data.data(), data.size());
270 obj.image(img, levels);
273 void Texture::Loader::mipmap_levels(unsigned l)