]> git.tdb.fi Git - libs/gl.git/blob - source/pixelformat.cpp
Remove support for legacy OpenGL features
[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
38                 throw lexical_error(format("conversion of '%s' to PixelFormat", conv.get()));
39 }
40
41 PixelFormat pixelformat_from_graphics(Graphics::PixelFormat pf)
42 {
43         switch(pf)
44         {
45         case Graphics::LUMINANCE: return LUMINANCE;
46         case Graphics::LUMINANCE_ALPHA: return LUMINANCE_ALPHA;
47         case Graphics::RGB: return RGB;
48         case Graphics::RGBX:
49         case Graphics::RGBA: return RGBA;
50         case Graphics::BGR: return BGR;
51         case Graphics::BGRX:
52         case Graphics::BGRA: return BGRA;
53         default: throw invalid_argument("pixelformat_from_graphics");
54         }
55 }
56
57 PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat pf, bool srgb)
58 {
59         PixelFormat result;
60         switch(pf)
61         {
62         case Graphics::RGBX:
63         case Graphics::BGR:
64         case Graphics::BGRX: result = RGB; break;
65         case Graphics::BGRA: result = RGBA; break;
66         default: result = pixelformat_from_graphics(pf);
67         }
68
69         if(srgb)
70                 return get_srgb_pixelformat(result);
71         else
72                 return result;
73 }
74
75 PixelFormat get_base_pixelformat(PixelFormat pf)
76 {
77         PixelFormat unsized = get_unsized_pixelformat(pf);
78         switch(unsized)
79         {
80         case SRGB: return RGB;
81         case SRGB_ALPHA: return RGBA;
82         default: return unsized;
83         }
84 }
85
86 PixelFormat get_unsized_pixelformat(PixelFormat pf)
87 {
88         switch(pf)
89         {
90         case R8:
91         case R16F:
92         case R32F: return RED;
93         case RG8:
94         case RG16F:
95         case RG32F: return RG;
96         case RGB8:
97         case RGB16F:
98         case RGB32F: return RGB;
99         case SRGB8: return SRGB;
100         case RGBA8:
101         case RGBA16F:
102         case RGBA32F: return RGBA;
103         case SRGB8_ALPHA8: return SRGB_ALPHA;
104         case LUMINANCE8: return LUMINANCE;
105         case LUMINANCE8_ALPHA8: return LUMINANCE_ALPHA;
106         case DEPTH_COMPONENT16:
107         case DEPTH_COMPONENT24:
108         case DEPTH_COMPONENT32:
109         case DEPTH_COMPONENT32F: return DEPTH_COMPONENT;
110         default: return pf;
111         }
112 }
113
114 PixelFormat get_sized_pixelformat(PixelFormat pf, unsigned size)
115 {
116         if(!size || size>4)
117                 throw invalid_argument("get_sized_pixelformat");
118
119         pf = get_unsized_pixelformat(pf);
120
121         switch(size)
122         {
123         case 1:
124                 switch(pf)
125                 {
126                 case RED: return R8;
127                 case RG: return RG8;
128                 case RGB: return RGB8;
129                 case RGBA: return RGBA8;
130                 case SRGB: return SRGB8;
131                 case SRGB_ALPHA: return SRGB8_ALPHA8;
132                 case LUMINANCE: return LUMINANCE8;
133                 case LUMINANCE_ALPHA: return LUMINANCE8_ALPHA8;
134                 default: throw invalid_argument("get_sized_pixelformat");
135                 }
136         case 2:
137                 switch(pf)
138                 {
139                 case RED: return R16F;
140                 case RG: return RG16F;
141                 case RGB: return RGB16F;
142                 case RGBA: return RGBA16F;
143                 case DEPTH_COMPONENT: return DEPTH_COMPONENT16;
144                 default: throw invalid_argument("get_sized_pixelformat");
145                 }
146         case 3:
147                 if(pf==DEPTH_COMPONENT)
148                         return DEPTH_COMPONENT24;
149                 else
150                         throw invalid_argument("get_sized_pixelformat");
151         case 4:
152                 switch(pf)
153                 {
154                 case RED: return R32F;
155                 case RG: return RG32F;
156                 case RGB: return RGB32F;
157                 case RGBA: return RGBA32F;
158                 case DEPTH_COMPONENT: return ARB_depth_buffer_float ? DEPTH_COMPONENT32F : DEPTH_COMPONENT32;
159                 default: throw invalid_argument("get_sized_pixelformat");
160                 }
161         default:
162                 throw invalid_argument("get_sized_pixelformat");
163         }
164 }
165
166 PixelFormat get_default_sized_pixelformat(PixelFormat pf)
167 {
168         pf = get_unsized_pixelformat(pf);
169         unsigned size = 1;
170         if(pf==DEPTH_COMPONENT)
171         {
172                 if(get_gl_api()==OPENGL_ES2 && !ARB_depth_buffer_float)
173                         size = 2;
174                 else
175                         size = 4;
176         }
177         return get_sized_pixelformat(pf, size);
178 }
179
180 PixelFormat get_srgb_pixelformat(PixelFormat pf)
181 {
182         switch(pf)
183         {
184         case RGB: return SRGB;
185         case RGBA: return SRGB_ALPHA;
186         case RGB8: return SRGB8;
187         case RGBA8: return SRGB8_ALPHA8;
188         default: return pf;
189         }
190 }
191
192 unsigned get_component_count(PixelFormat pf)
193 {
194         switch(get_base_pixelformat(pf))
195         {
196         case STENCIL_INDEX:
197         case DEPTH_COMPONENT:
198         case RED:
199         case LUMINANCE:
200                 return 1;
201         case RG:
202         case LUMINANCE_ALPHA:
203                 return 2;
204         case RGB:
205         case BGR:
206                 return 3;
207         case RGBA:
208         case BGRA:
209                 return 4;
210         default:
211                 throw invalid_argument("get_component_count");
212         }
213 }
214
215 unsigned get_component_size(PixelFormat pf)
216 {
217         switch(pf)
218         {
219         case R8:
220         case RG8:
221         case RGB8:
222         case RGBA8:
223         case SRGB8:
224         case SRGB8_ALPHA8:
225         case LUMINANCE8:
226         case LUMINANCE8_ALPHA8:
227                 return 1;
228         case R16F:
229         case RG16F:
230         case RGB16F:
231         case RGBA16F:
232         case DEPTH_COMPONENT16:
233                 return 2;
234         case DEPTH_COMPONENT24:
235                 return 3;
236         case R32F:
237         case RG32F:
238         case RGB32F:
239         case RGBA32F:
240         case DEPTH_COMPONENT32:
241         case DEPTH_COMPONENT32F:
242                 return 4;
243         default:
244                 return 0;
245         }
246 }
247
248 unsigned get_pixel_size(PixelFormat pf)
249 {
250         return get_component_count(pf)*max(get_component_size(pf), 1U);
251 }
252
253 void require_pixelformat(PixelFormat pf)
254 {
255         /* TODO These checks are only accurate for textures.  On OpenGL ES some
256         formats are allowed for render buffers earlier than textures.  In particular
257         it's possible to create a 16-bit depth renderbuffer on OpenGL ES 2.0 but
258         depth textures are only available with 3.0 or the OES_depth_texture
259         extension.*/
260         switch(pf)
261         {
262         case RGB8:
263         case RGBA8:
264                 { static Require _req(OES_required_internalformat); }
265                 break;
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                 { static Require _req(EXT_texture_sRGB); }
290                 break;
291         case BGR:
292         case BGRA:
293                 { static Require _req(EXT_bgra); }
294                 break;
295         case DEPTH_COMPONENT:
296                 { static Require _req(ARB_depth_texture); }
297                 break;
298         case DEPTH_COMPONENT16:
299         case DEPTH_COMPONENT24:
300         case DEPTH_COMPONENT32:
301                 { static Require _req(ARB_depth_texture); }
302                 { static Require _req(OES_required_internalformat); }
303                 break;
304         case DEPTH_COMPONENT32F:
305                 { static Require _req(ARB_depth_buffer_float); }
306                 break;
307         case STENCIL_INDEX:
308                 { static Require _req(OES_texture_stencil8); }
309                 break;
310         default:
311                 break;
312         }
313 }
314
315 } // namespace GL
316 } // namespace Msp