]> git.tdb.fi Git - libs/gl.git/blob - source/core/texture.cpp
Simplify Program by removing transient data
[libs/gl.git] / source / core / texture.cpp
1 #include <msp/datafile/rawdata.h>
2 #include <msp/io/memory.h>
3 #include "error.h"
4 #include "resourcemanager.h"
5 #include "texture.h"
6 #include "texture1d.h"
7 #include "texture2d.h"
8 #include "texture2darray.h"
9 #include "texture3d.h"
10 #include "texturecube.h"
11
12 using namespace std;
13
14 namespace Msp {
15 namespace GL {
16
17 Texture::Texture(unsigned t):
18         TextureBackend(t)
19 { }
20
21 void Texture::set_format(PixelFormat fmt)
22 {
23         PixelComponents comp = get_components(fmt);
24         ComponentSwizzle swiz = get_required_swizzle(comp);
25         PixelComponents st_comp = unswizzle_components(comp, swiz);
26
27         PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt), is_srgb(fmt));
28         require_pixelformat(st_fmt);
29         if(swiz!=NO_SWIZZLE)
30                 require_swizzle();
31
32         format = fmt;
33         storage_fmt = st_fmt;
34         swizzle = swiz;
35 }
36
37 unsigned Texture::count_levels(unsigned size)
38 {
39         unsigned n = 0;
40         for(; size; size>>=1, ++n) ;
41         return n;
42 }
43
44 void Texture::stage_pixels(void *staging, const void *data, size_t count)
45 {
46         if(swizzle==RGBA_TO_RGB)
47         {
48                 const uint32_t *src = static_cast<const uint32_t *>(data);
49                 uint32_t *dst = static_cast<uint32_t *>(staging);
50                 size_t i = 0;
51                 for(; i+3<count; i+=4)
52                 {
53                         dst[0] = src[0]|0xFF000000;
54                         dst[1] = (src[0]>>24)|(src[1]<<8)|0xFF000000;
55                         dst[2] = (src[1]>>16)|(src[2]<<16)|0xFF000000;
56                         dst[3] = (src[2]>>8)|0xFF000000;
57                         src += 3;
58                         dst += 4;
59                 }
60
61                 if(i<count)
62                 {
63                         const uint8_t *src_bytes = reinterpret_cast<const uint8_t *>(src);
64                         for(; i<count; ++i)
65                         {
66                                 *dst++ = src_bytes[0]|(src_bytes[1]<<8)|(src_bytes[2]<<16)|0xFF000000;
67                                 src_bytes += 3;
68                         }
69                 }
70         }
71         else
72         {
73                 const char *src = static_cast<const char *>(data);
74                 size_t data_size = count*get_pixel_size(storage_fmt);
75                 copy(src, src+data_size, static_cast<char *>(staging));
76         }
77 }
78
79 void Texture::load_image(const string &fn, unsigned lv)
80 {
81         Graphics::Image img;
82         img.load_file(fn);
83
84         image(img, lv);
85 }
86
87 Texture::GenericLoader::TypeRegistry &Texture::get_texture_registry()
88 {
89         static GenericLoader::TypeRegistry registry;
90         static bool initialized = false;
91         if(!initialized)
92         {
93                 initialized = true;
94                 registry.register_type<Texture1D>("1d");
95                 registry.register_type<Texture2D>("2d");
96                 registry.register_type<Texture3D>("3d");
97                 registry.register_type<Texture2DArray>("2d_array");
98                 registry.register_type<TextureCube>("cube");
99         }
100         return registry;
101 }
102
103
104 Texture::Loader::Loader(Texture &t, Collection *c):
105         CollectionObjectLoader<Texture>(t, c),
106         levels(0)
107 {
108         add("external_data", &Loader::external_data);
109         add("external_image", &Loader::external_image, false);
110         add("external_image_srgb", &Loader::external_image, true);
111         add("generate_mipmap", &Loader::generate_mipmap);
112         add("image_data", &Loader::image_data);
113         add("mipmap_levels", &Loader::mipmap_levels);
114         add("raw_data", &Loader::raw_data);
115 }
116
117 void Texture::Loader::finish()
118 {
119         if(obj.auto_gen_mipmap)
120                 obj.generate_mipmap();
121 }
122
123 void Texture::Loader::load_external_image(Graphics::Image &img, const string &fn)
124 {
125         RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
126         if(!io)
127                 throw IO::file_not_found(fn);
128         img.load_io(*io);
129 }
130
131 void Texture::Loader::external_data(const string &fn)
132 {
133         if(obj.manager)
134                 obj.manager->set_resource_location(obj, get_collection(), fn);
135         else
136         {
137                 DataFile::RawData rd;
138                 rd.open_file(get_collection(), fn);
139                 rd.load();
140                 obj.image(0, rd.get_data());
141         }
142 }
143
144 void Texture::Loader::external_image(bool srgb, const string &fn)
145 {
146         obj.use_srgb_format = srgb;
147         if(obj.manager)
148                 obj.manager->set_resource_location(obj, get_collection(), fn);
149         else
150         {
151                 Graphics::Image img;
152                 load_external_image(img, fn);
153                 obj.image(img, levels);
154         }
155 }
156
157 void Texture::Loader::generate_mipmap(bool gm)
158 {
159         obj.auto_gen_mipmap = gm;
160 }
161
162 void Texture::Loader::image_data(const string &data)
163 {
164         if(obj.manager)
165                 obj.set_manager(0);
166
167         Graphics::Image img;
168         IO::Memory mem(data.data(), data.size());
169         img.load_io(mem);
170
171         obj.image(img, levels);
172 }
173
174 void Texture::Loader::mipmap_levels(unsigned l)
175 {
176         levels = l;
177 }
178
179 void Texture::Loader::raw_data(const string &data)
180 {
181         if(obj.manager)
182                 obj.set_manager(0);
183
184         obj.image(0, data.data());
185 }
186
187 } // namespace GL
188 } // namespace Msp