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)
39 static bool alignment_init = false;
42 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
43 alignment_init = true;
50 glDeleteTextures(1, &id);
53 void Texture::generate_id()
56 throw invalid_operation("Texture::generate_id");
57 if(ARB_direct_state_access)
58 glCreateTextures(target, 1, &id);
60 glGenTextures(1, &id);
63 if(!debug_name.empty() && KHR_debug)
64 glObjectLabel(GL_TEXTURE, id, debug_name.size(), debug_name.c_str());
68 void Texture::set_format(PixelFormat fmt)
70 PixelComponents comp = get_components(fmt);
71 PixelComponents st_comp = comp;
72 FormatSwizzle swiz = NO_SWIZZLE;
77 swiz = R_TO_LUMINANCE;
81 swiz = RG_TO_LUMINANCE_ALPHA;
94 PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
95 require_pixelformat(st_fmt);
97 static Require _req(ARB_texture_swizzle);
100 storage_fmt = st_fmt;
104 void Texture::apply_swizzle()
106 if(swizzle==NO_SWIZZLE)
109 if(get_gl_api()==OPENGL_ES2)
111 set_parameter_i(GL_TEXTURE_SWIZZLE_R, swizzle_orders[swizzle*4]);
112 set_parameter_i(GL_TEXTURE_SWIZZLE_G, swizzle_orders[swizzle*4+1]);
113 set_parameter_i(GL_TEXTURE_SWIZZLE_B, swizzle_orders[swizzle*4+2]);
114 set_parameter_i(GL_TEXTURE_SWIZZLE_A, swizzle_orders[swizzle*4+3]);
118 if(ARB_direct_state_access)
119 glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
121 glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
125 void Texture::set_parameter_i(GLenum param, int value) const
127 if(ARB_direct_state_access)
128 glTextureParameteri(id, param, value);
130 glTexParameteri(target, param, value);
133 bool Texture::can_generate_mipmap()
135 return EXT_framebuffer_object;
138 void Texture::generate_mipmap()
140 // glGenerateMipmap is defined here
141 static Require _req(EXT_framebuffer_object);
143 if(!ARB_direct_state_access)
145 glActiveTexture(GL_TEXTURE0);
146 glBindTexture(target, id);
149 if(!ARB_direct_state_access)
150 glBindTexture(target, 0);
153 void Texture::generate_mipmap_()
155 if(ARB_direct_state_access)
156 glGenerateTextureMipmap(id);
158 glGenerateMipmap(target);
161 void Texture::set_auto_generate_mipmap(bool gm)
164 static Require _req(EXT_framebuffer_object);
166 auto_gen_mipmap = gm;
169 void Texture::load_image(const string &fn, bool)
174 void Texture::load_image(const string &fn, unsigned lv)
182 void Texture::image(const Graphics::Image &img, bool)
187 void Texture::set_debug_name(const string &name)
192 glObjectLabel(GL_TEXTURE, id, name.size(), name.c_str());
199 Texture::Loader::Loader(Texture &t):
200 DataFile::CollectionObjectLoader<Texture>(t, 0)
205 Texture::Loader::Loader(Texture &t, Collection &c):
206 DataFile::CollectionObjectLoader<Texture>(t, &c)
211 void Texture::Loader::init()
215 add("external_image", &Loader::external_image);
216 add("external_image_srgb", &Loader::external_image_srgb);
217 add("generate_mipmap", &Loader::generate_mipmap);
218 add("image_data", &Loader::image_data);
219 add("mipmap_levels", &Loader::mipmap_levels);
222 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
224 RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
226 throw IO::file_not_found(fn);
230 void Texture::Loader::external_image(const string &fn)
232 obj.use_srgb_format = false;
233 external_image_common(fn);
236 void Texture::Loader::external_image_srgb(const string &fn)
238 obj.use_srgb_format = true;
239 external_image_common(fn);
242 void Texture::Loader::external_image_common(const string &fn)
245 obj.manager->set_resource_location(obj, get_collection(), fn);
249 load_external_image(img, fn);
250 obj.image(img, levels);
254 void Texture::Loader::generate_mipmap(bool gm)
256 obj.set_auto_generate_mipmap(gm);
259 void Texture::Loader::image_data(const string &data)
269 IO::Memory mem(data.data(), data.size());
272 obj.image(img, levels);
275 void Texture::Loader::mipmap_levels(unsigned l)