]> git.tdb.fi Git - libs/gl.git/blob - source/pixelformat.cpp
d866bcf8094b9f9d677ccea8c00bf36db8842cd7
[libs/gl.git] / source / pixelformat.cpp
1 #include <msp/gl/extensions/arb_texture_float.h>
2 #include <msp/gl/extensions/ext_bgra.h>
3 #include <msp/strings/format.h>
4 #include "pixelformat.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GL {
10
11 void operator>>(const LexicalConverter &conv, PixelFormat &fmt)
12 {
13         if(conv.get()=="STENCIL_INDEX")
14                 fmt = STENCIL_INDEX;
15         else if(conv.get()=="DEPTH_COMPONENT")
16                 fmt = DEPTH_COMPONENT;
17         else if(conv.get()=="RED")
18                 fmt = RED;
19         else if(conv.get()=="RG")
20                 fmt = RG;
21         else if(conv.get()=="RGB")
22                 fmt = RGB;
23         else if(conv.get()=="RGBA")
24                 fmt = RGBA;
25         else if(conv.get()=="BGR")
26                 fmt = BGR;
27         else if(conv.get()=="BGRA")
28                 fmt = BGRA;
29         else if(conv.get()=="SRGB")
30                 fmt = SRGB;
31         else if(conv.get()=="SRGB_ALPHA")
32                 fmt = SRGB_ALPHA;
33         else if(conv.get()=="LUMINANCE")
34                 fmt = LUMINANCE;
35         else if(conv.get()=="LUMINANCE_ALPHA")
36                 fmt = LUMINANCE_ALPHA;
37         else if(conv.get()=="SLUMINANCE")
38                 fmt = SLUMINANCE;
39         else if(conv.get()=="SLUMINANCE_ALPHA")
40                 fmt = SLUMINANCE_ALPHA;
41         else
42                 throw lexical_error(format("conversion of '%s' to PixelFormat", conv.get()));
43 }
44
45 PixelFormat pixelformat_from_graphics(Graphics::PixelFormat pf)
46 {
47         switch(pf)
48         {
49         case Graphics::LUMINANCE: return LUMINANCE;
50         case Graphics::LUMINANCE_ALPHA: return LUMINANCE_ALPHA;
51         case Graphics::RGB: return RGB;
52         case Graphics::RGBX:
53         case Graphics::RGBA: return RGBA;
54         case Graphics::BGR: return BGR;
55         case Graphics::BGRX:
56         case Graphics::BGRA: return BGRA;
57         default: throw invalid_argument("pixelformat_from_graphics");
58         }
59 }
60
61 PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat pf, bool srgb)
62 {
63         PixelFormat result;
64         switch(pf)
65         {
66         case Graphics::RGBX:
67         case Graphics::BGR:
68         case Graphics::BGRX: result = RGB; break;
69         case Graphics::BGRA: result = RGBA; break;
70         default: result = pixelformat_from_graphics(pf);
71         }
72
73         if(srgb)
74                 return get_srgb_pixelformat(result);
75         else
76                 return result;
77 }
78
79 PixelFormat get_base_pixelformat(PixelFormat pf)
80 {
81         PixelFormat unsized = get_unsized_pixelformat(pf);
82         switch(unsized)
83         {
84         case SRGB: return RGB;
85         case SRGB_ALPHA: return RGBA;
86         case SLUMINANCE: return LUMINANCE;
87         case SLUMINANCE_ALPHA: return LUMINANCE_ALPHA;
88         default: return unsized;
89         }
90 }
91
92 PixelFormat get_unsized_pixelformat(PixelFormat pf)
93 {
94         switch(pf)
95         {
96         case R8:
97         case R16F:
98         case R32F: return RED;
99         case RG8:
100         case RG16F:
101         case RG32F: return RG;
102         case RGB8:
103         case RGB16F:
104         case RGB32F: return RGB;
105         case SRGB8: return SRGB;
106         case RGBA8:
107         case RGBA16F:
108         case RGBA32F: return RGBA;
109         case SRGB8_ALPHA8: return SRGB_ALPHA;
110         case LUMINANCE8: return LUMINANCE;
111         case SLUMINANCE8: return SLUMINANCE;
112         case LUMINANCE_ALPHA8: return LUMINANCE_ALPHA;
113         case SLUMINANCE8_ALPHA8: return SLUMINANCE_ALPHA;
114         case DEPTH_COMPONENT16:
115         case DEPTH_COMPONENT24:
116         case DEPTH_COMPONENT32: return DEPTH_COMPONENT;
117         default: return pf;
118         }
119 }
120
121 PixelFormat get_sized_pixelformat(PixelFormat pf, unsigned size)
122 {
123         if(!size || size>4)
124                 throw invalid_argument("get_sized_pixelformat");
125
126         switch(pf)
127         {
128         case SRGB:
129         case SRGB_ALPHA: break;
130         case SRGB8: pf = SRGB; break;
131         case SRGB8_ALPHA8: pf = SRGB_ALPHA; break;
132         default: pf = get_base_pixelformat(pf);
133         }
134
135         switch(size)
136         {
137         case 1:
138                 switch(pf)
139                 {
140                 case RED: return R8;
141                 case RG: return RG8;
142                 case RGB: return RGB8;
143                 case RGBA: return RGBA8;
144                 case SRGB: return SRGB8;
145                 case SRGB_ALPHA: return SRGB8_ALPHA8;
146                 case LUMINANCE: return LUMINANCE8;
147                 case SLUMINANCE: return SLUMINANCE8;
148                 case LUMINANCE_ALPHA: return LUMINANCE8_ALPHA8;
149                 case SLUMINANCE_ALPHA: return SLUMINANCE8_ALPHA8;
150                 default: throw invalid_argument("get_sized_pixelformat");
151                 }
152         case 2:
153                 switch(pf)
154                 {
155                 case RED: return R16F;
156                 case RG: return RG16F;
157                 case RGB: return RGB16F;
158                 case RGBA: return RGBA16F;
159                 case DEPTH_COMPONENT: return DEPTH_COMPONENT16;
160                 default: throw invalid_argument("get_sized_pixelformat");
161                 }
162         case 3:
163                 if(pf==DEPTH_COMPONENT)
164                         return DEPTH_COMPONENT24;
165                 else
166                         throw invalid_argument("get_sized_pixelformat");
167         case 4:
168                 switch(pf)
169                 {
170                 case RED: return R32F;
171                 case RG: return RG32F;
172                 case RGB: return RGB32F;
173                 case RGBA: return RGBA32F;
174                 case DEPTH_COMPONENT: return DEPTH_COMPONENT32;
175                 default: throw invalid_argument("get_sized_pixelformat");
176                 }
177         default:
178                 throw invalid_argument("get_sized_pixelformat");
179         }
180 }
181
182 PixelFormat get_srgb_pixelformat(PixelFormat pf)
183 {
184         switch(pf)
185         {
186         case RGB: return SRGB;
187         case RGBA: return SRGB_ALPHA;
188         case RGB8: return SRGB8;
189         case RGBA8: return SRGB8_ALPHA8;
190         case LUMINANCE: return SLUMINANCE;
191         case LUMINANCE8: return SLUMINANCE8;
192         case LUMINANCE_ALPHA: return SLUMINANCE_ALPHA;
193         case LUMINANCE_ALPHA8: return SLUMINANCE8_ALPHA8;
194         default: return pf;
195         }
196 }
197
198 unsigned get_component_count(PixelFormat pf)
199 {
200         switch(get_base_pixelformat(pf))
201         {
202         case STENCIL_INDEX:
203         case DEPTH_COMPONENT:
204         case RED:
205         case LUMINANCE:
206         case SLUMINANCE:
207                 return 1;
208         case RG:
209         case LUMINANCE_ALPHA:
210         case SLUMINANCE_ALPHA:
211                 return 2;
212         case RGB:
213         case BGR:
214                 return 3;
215         case RGBA:
216         case BGRA:
217                 return 4;
218         default:
219                 throw invalid_argument("get_component_count");
220         }
221 }
222
223 unsigned get_component_size(PixelFormat pf)
224 {
225         switch(pf)
226         {
227         case R8:
228         case RG8:
229         case RGB8:
230         case RGBA8:
231         case SRGB8:
232         case SRGB8_ALPHA8:
233         case LUMINANCE8:
234         case LUMINANCE8_ALPHA8:
235         case SLUMINANCE8:
236         case SLUMINANCE8_ALPHA8:
237                 return 1;
238         case R16F:
239         case RG16F:
240         case RGB16F:
241         case RGBA16F:
242         case DEPTH_COMPONENT16:
243                 return 2;
244         case DEPTH_COMPONENT24:
245                 return 3;
246         case R32F:
247         case RG32F:
248         case RGB32F:
249         case RGBA32F:
250         case DEPTH_COMPONENT32:
251                 return 4;
252         default:
253                 return 0;
254         }
255 }
256
257 unsigned get_pixel_size(PixelFormat pf)
258 {
259         return get_component_count(pf)*max(get_component_size(pf), 1U);
260 }
261
262 void require_pixelformat(PixelFormat pf)
263 {
264         switch(pf)
265         {
266         case RED:
267         case R8:
268         case RG:
269         case RG8:
270                 { static Require _req(ARB_texture_rg); }
271                 break;
272         case R16F:
273         case R32F:
274         case RG16F:
275         case RG32F:
276                 { static Require _req(ARB_texture_rg); }
277                 { static Require _req(ARB_texture_float); }
278                 break;
279         case RGB16F:
280         case RGB32F:
281         case RGBA16F:
282         case RGBA32F:
283                 { static Require _req(ARB_texture_float); }
284                 break;
285         case SRGB:
286         case SRGB8:
287         case SRGB_ALPHA:
288         case SRGB8_ALPHA8:
289         case SLUMINANCE:
290         case SLUMINANCE8:
291         case SLUMINANCE_ALPHA:
292         case SLUMINANCE8_ALPHA8:
293                 { static Require _req(EXT_texture_sRGB); }
294                 break;
295         case BGR:
296         case BGRA:
297                 { static Require _req(EXT_bgra); }
298                 break;
299         case DEPTH_COMPONENT:
300         case DEPTH_COMPONENT16:
301         case DEPTH_COMPONENT24:
302         case DEPTH_COMPONENT32:
303                 { static Require _req(ARB_depth_texture); }
304                 break;
305         default:
306                 break;
307         }
308 }
309
310 } // namespace GL
311 } // namespace Msp