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