]> git.tdb.fi Git - libs/gl.git/blob - source/core/texture2d.cpp
01612d7325a8bf21c875e6e5a7de4f3de461657d
[libs/gl.git] / source / core / texture2d.cpp
1 #include "error.h"
2 #include "texture2d.h"
3
4 using namespace std;
5
6 namespace Msp {
7 namespace GL {
8
9 Texture2D::Texture2D():
10         width(0),
11         height(0)
12 { }
13
14 Texture2D::~Texture2D()
15 {
16         set_manager(0);
17 }
18
19 void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned lv)
20 {
21         if(width>0)
22         {
23                 if(fmt!=format || wd!=width || ht!=height || (lv && lv!=levels))
24                         throw incompatible_data("Texture2D::storage");
25                 return;
26         }
27         if(wd==0 || ht==0)
28                 throw invalid_argument("Texture2D::storage");
29
30         set_format(fmt);
31         width = wd;
32         height = ht;
33         levels = get_n_levels();
34         if(lv>0)
35                 levels = min(levels, lv);
36
37         allocate();
38 }
39
40 void Texture2D::image(unsigned level, const void *data)
41 {
42         LinAl::Vector<unsigned, 2> size = get_level_size(level);
43         return sub_image(level, 0, 0, size.x, size.y, data);
44 }
45
46 void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data)
47 {
48         if(width==0 || height==0)
49                 throw invalid_operation("Texture2D::sub_image");
50         if(level>=levels)
51                 throw out_of_range("Texture2D::sub_image");
52
53         Texture2DBackend::sub_image(level, x, y, wd, ht, data);
54 }
55
56 void Texture2D::image(const Graphics::Image &img, unsigned lv)
57 {
58         storage(pixelformat_from_image(img, use_srgb_format), img.get_width(), img.get_height(), lv);
59         image(0, img.get_pixels());
60 }
61
62 unsigned Texture2D::get_n_levels() const
63 {
64         unsigned n = 0;
65         for(unsigned s=max(width, height); s; s>>=1, ++n) ;
66         return n;
67 }
68
69 LinAl::Vector<unsigned, 2> Texture2D::get_level_size(unsigned level) const
70 {
71         unsigned w = width>>level;
72         unsigned h = height>>level;
73
74         if(!w && h)
75                 w = 1;
76         else if(!h && w)
77                 h = 1;
78
79         return LinAl::Vector<unsigned, 2>(w, h);
80 }
81
82 Resource::AsyncLoader *Texture2D::load(IO::Seekable &io, const Resources *)
83 {
84         return create_async_loader(io);
85 }
86
87 uint64_t Texture2D::get_data_size() const
88 {
89         return id ? width*height*get_pixel_size(format) : 0;
90 }
91
92
93 Texture2D::Loader::Loader(Texture2D &t):
94         DataFile::DerivedObjectLoader<Texture2D, Texture::Loader>(t)
95 {
96         init();
97 }
98
99 Texture2D::Loader::Loader(Texture2D &t, Collection &c):
100         DataFile::DerivedObjectLoader<Texture2D, Texture::Loader>(t, c)
101 {
102         init();
103 }
104
105 void Texture2D::Loader::init()
106 {
107         add("raw_data", &Loader::raw_data);
108         add("storage", &Loader::storage);
109         add("storage", &Loader::storage_levels);
110 }
111
112 void Texture2D::Loader::raw_data(const string &data)
113 {
114         if(obj.manager)
115                 obj.set_manager(0);
116         obj.image(0, data.data());
117 }
118
119 void Texture2D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h)
120 {
121         obj.storage(fmt, w, h);
122 }
123
124 void Texture2D::Loader::storage_levels(PixelFormat fmt, unsigned w, unsigned h, unsigned l)
125 {
126         obj.storage(fmt, w, h, l);
127 }
128
129 } // namespace GL
130 } // namespace Msp