]> git.tdb.fi Git - libs/gl.git/blob - source/core/texture.cpp
Load textures in a type-generic way
[libs/gl.git] / source / core / texture.cpp
1 #include <msp/io/memory.h>
2 #include "error.h"
3 #include "resourcemanager.h"
4 #include "texture.h"
5 #include "texture1d.h"
6 #include "texture2d.h"
7 #include "texture2darray.h"
8 #include "texture3d.h"
9 #include "texturecube.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace GL {
15
16 Texture::Texture(unsigned t):
17         TextureBackend(t),
18         format(NO_PIXELFORMAT),
19         storage_fmt(format),
20         swizzle(NO_SWIZZLE),
21         use_srgb_format(false),
22         auto_gen_mipmap(false)
23 { }
24
25 void Texture::set_format(PixelFormat fmt)
26 {
27         PixelComponents comp = get_components(fmt);
28         PixelComponents st_comp = comp;
29         FormatSwizzle swiz = NO_SWIZZLE;
30         switch(comp)
31         {
32         case LUMINANCE:
33                 st_comp = RED;
34                 swiz = R_TO_LUMINANCE;
35                 break;
36         case LUMINANCE_ALPHA:
37                 st_comp = RG;
38                 swiz = RG_TO_LUMINANCE_ALPHA;
39                 break;
40         case BGR:
41                 st_comp = RGB;
42                 swiz = RGB_TO_BGR;
43                 break;
44         case BGRA:
45                 st_comp = RGBA;
46                 swiz = RGB_TO_BGR;
47                 break;
48         default:;
49         }
50
51         PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
52         require_pixelformat(st_fmt);
53         if(swiz!=NO_SWIZZLE)
54                 require_swizzle();
55
56         format = fmt;
57         storage_fmt = st_fmt;
58         swizzle = swiz;
59 }
60
61 void Texture::load_image(const string &fn, unsigned lv)
62 {
63         Graphics::Image img;
64         img.load_file(fn);
65
66         image(img, lv);
67 }
68
69 Texture::GenericLoader::TypeRegistry &Texture::get_texture_registry()
70 {
71         static GenericLoader::TypeRegistry registry;
72         static bool initialized = false;
73         if(!initialized)
74         {
75                 initialized = true;
76                 registry.register_type<Texture1D>("1d");
77                 registry.register_type<Texture2D>("2d");
78                 registry.register_type<Texture3D>("3d");
79                 registry.register_type<Texture2DArray>("2d_array");
80                 registry.register_type<TextureCube>("cube");
81         }
82         return registry;
83 }
84
85
86 Texture::Loader::Loader(Texture &t, Collection *c):
87         CollectionObjectLoader<Texture>(t, c),
88         levels(0)
89 {
90         add("external_image", &Loader::external_image);
91         add("external_image_srgb", &Loader::external_image_srgb);
92         add("generate_mipmap", &Loader::generate_mipmap);
93         add("image_data", &Loader::image_data);
94         add("mipmap_levels", &Loader::mipmap_levels);
95 }
96
97 void Texture::Loader::finish()
98 {
99         if(obj.auto_gen_mipmap)
100                 obj.generate_mipmap();
101 }
102
103 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
104 {
105         RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
106         if(!io)
107                 throw IO::file_not_found(fn);
108         img.load_io(*io);
109 }
110
111 void Texture::Loader::external_image(const string &fn)
112 {
113         obj.use_srgb_format = false;
114         external_image_common(fn);
115 }
116
117 void Texture::Loader::external_image_srgb(const string &fn)
118 {
119         obj.use_srgb_format = true;
120         external_image_common(fn);
121 }
122
123 void Texture::Loader::external_image_common(const string &fn)
124 {
125         if(obj.manager)
126                 obj.manager->set_resource_location(obj, get_collection(), fn);
127         else
128         {
129                 Graphics::Image img;
130                 load_external_image(img, fn);
131                 obj.image(img, levels);
132         }
133 }
134
135 void Texture::Loader::generate_mipmap(bool gm)
136 {
137         obj.auto_gen_mipmap = gm;
138 }
139
140 void Texture::Loader::image_data(const string &data)
141 {
142         if(obj.manager)
143                 obj.set_manager(0);
144
145         Graphics::Image img;
146         IO::Memory mem(data.data(), data.size());
147         img.load_io(mem);
148
149         obj.image(img, levels);
150 }
151
152 void Texture::Loader::mipmap_levels(unsigned l)
153 {
154         levels = l;
155 }
156
157 } // namespace GL
158 } // namespace Msp