]> git.tdb.fi Git - libs/gl.git/blob - source/core/pixelformat.cpp
11eb40812ea631ff2421b88d55e39812d9ea09d5
[libs/gl.git] / source / core / pixelformat.cpp
1 #include <msp/gl/extensions/arb_depth_buffer_float.h>
2 #include <msp/gl/extensions/arb_depth_texture.h>
3 #include <msp/gl/extensions/arb_texture_float.h>
4 #include <msp/gl/extensions/arb_texture_rg.h>
5 #include <msp/gl/extensions/ext_texture_srgb.h>
6 #include <msp/gl/extensions/oes_required_internalformat.h>
7 #include <msp/gl/extensions/oes_texture_stencil8.h>
8 #include <msp/strings/format.h>
9 #include "pixelformat.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace GL {
15
16 void operator>>(const LexicalConverter &conv, PixelComponents &comp)
17 {
18         if(conv.get()=="STENCIL_INDEX")
19                 comp = STENCIL_INDEX;
20         else if(conv.get()=="DEPTH_COMPONENT")
21                 comp = DEPTH_COMPONENT;
22         else if(conv.get()=="RED")
23                 comp = RED;
24         else if(conv.get()=="RG")
25                 comp = RG;
26         else if(conv.get()=="RGB")
27                 comp = RGB;
28         else if(conv.get()=="RGBA")
29                 comp = RGBA;
30         else if(conv.get()=="BGR")
31                 comp = BGR;
32         else if(conv.get()=="BGRA")
33                 comp = BGRA;
34         else if(conv.get()=="LUMINANCE")
35                 comp = LUMINANCE;
36         else if(conv.get()=="LUMINANCE_ALPHA")
37                 comp = LUMINANCE_ALPHA;
38         else
39                 throw lexical_error(format("conversion of '%s' to PixelComponents", conv.get()));
40 }
41
42 void operator>>(const LexicalConverter &conv, PixelFormat &fmt)
43 {
44         if(conv.get()=="R8")
45                 fmt = R8;
46         else if(conv.get()=="R16F")
47                 fmt = R16F;
48         else if(conv.get()=="R32F")
49                 fmt = R32F;
50         else if(conv.get()=="RG8")
51                 fmt = RG8;
52         else if(conv.get()=="RG16F")
53                 fmt = RG16F;
54         else if(conv.get()=="RG32F")
55                 fmt = RG32F;
56         else if(conv.get()=="RGB8")
57                 fmt = RGB8;
58         else if(conv.get()=="RGB16F")
59                 fmt = RGB16F;
60         else if(conv.get()=="RGB32F")
61                 fmt = RGB32F;
62         else if(conv.get()=="RGBA8")
63                 fmt = RGBA8;
64         else if(conv.get()=="RGBA16F")
65                 fmt = RGBA16F;
66         else if(conv.get()=="RGBA32F")
67                 fmt = RGBA32F;
68         else if(conv.get()=="SRGB8")
69                 fmt = SRGB8;
70         else if(conv.get()=="SRGB8_ALPHA8")
71                 fmt = SRGB8_ALPHA8;
72         else if(conv.get()=="BGR8")
73                 fmt = BGR8;
74         else if(conv.get()=="BGRA8")
75                 fmt = BGRA8;
76         else if(conv.get()=="LUMINANCE8")
77                 fmt = LUMINANCE8;
78         else if(conv.get()=="LUMINANCE8_ALPHA8")
79                 fmt = LUMINANCE8_ALPHA8;
80         else if(conv.get()=="DEPTH_COMPONENT16")
81                 fmt = DEPTH_COMPONENT16;
82         else if(conv.get()=="DEPTH_COMPONENT24")
83                 fmt = DEPTH_COMPONENT24;
84         else if(conv.get()=="DEPTH_COMPONENT32")
85                 fmt = DEPTH_COMPONENT32;
86         else if(conv.get()=="DEPTH_COMPONENT32F")
87                 fmt = DEPTH_COMPONENT32F;
88         else
89                 throw lexical_error(format("conversion of '%s' to PixelFormat", conv.get()));
90 }
91
92 PixelComponents components_from_graphics(Graphics::PixelFormat pf)
93 {
94         switch(pf)
95         {
96         case Graphics::LUMINANCE: return LUMINANCE;
97         case Graphics::LUMINANCE_ALPHA: return LUMINANCE_ALPHA;
98         case Graphics::RGB: return RGB;
99         case Graphics::RGBX:
100         case Graphics::RGBA: return RGBA;
101         case Graphics::BGR: return BGR;
102         case Graphics::BGRX:
103         case Graphics::BGRA: return BGRA;
104         default: throw invalid_argument("pixelformat_from_graphics");
105         }
106 }
107
108 PixelFormat pixelformat_from_image(const Graphics::Image &image, bool srgb)
109 {
110         PixelComponents comp = components_from_graphics(image.get_format());
111         return make_pixelformat(comp, UNSIGNED_BYTE, srgb);
112 }
113
114 PixelFormat make_pixelformat(PixelComponents comp, DataType type, bool srgb)
115 {
116         bool normalized = !is_float(type);
117         return static_cast<PixelFormat>(comp | get_type_size(type)<<8 | (type&0x300)<<4 | normalized*0x4000 | srgb*0x8000);
118 }
119
120 void require_pixelformat(PixelFormat pf)
121 {
122         /* TODO These checks are only accurate for textures.  On OpenGL ES some
123         formats are allowed for render buffers earlier than textures.  In particular
124         it's possible to create a 16-bit depth renderbuffer on OpenGL ES 2.0 but
125         depth textures are only available with 3.0 or the OES_depth_texture
126         extension.*/
127         switch(pf)
128         {
129         case RGB8:
130         case RGBA8:
131                 { static Require _req(OES_required_internalformat); }
132                 break;
133         case R8:
134         case RG8:
135                 { static Require _req(ARB_texture_rg); }
136                 break;
137         case R16F:
138         case R32F:
139         case RG16F:
140         case RG32F:
141                 { static Require _req(ARB_texture_rg); }
142                 { static Require _req(ARB_texture_float); }
143                 break;
144         case RGB16F:
145         case RGB32F:
146         case RGBA16F:
147         case RGBA32F:
148                 { static Require _req(ARB_texture_float); }
149                 break;
150         case SRGB8:
151         case SRGB8_ALPHA8:
152                 { static Require _req(EXT_texture_sRGB); }
153                 break;
154         case DEPTH_COMPONENT16:
155         case DEPTH_COMPONENT24:
156         case DEPTH_COMPONENT32:
157                 { static Require _req(ARB_depth_texture); }
158                 { static Require _req(OES_required_internalformat); }
159                 break;
160         case DEPTH_COMPONENT32F:
161                 { static Require _req(ARB_depth_buffer_float); }
162                 break;
163         case STENCIL_INDEX8:
164                 { static Require _req(OES_texture_stencil8); }
165                 break;
166         default:
167                 throw invalid_argument("require_pixelformat");
168         }
169 }
170
171 unsigned get_gl_components(PixelComponents comp)
172 {
173         switch(comp)
174         {
175         case RED: return GL_RED;
176         case RG: return GL_RG;
177         case RGB: return GL_RGB;
178         case RGBA: return GL_RGBA;
179         case DEPTH_COMPONENT: return GL_DEPTH_COMPONENT;
180         case STENCIL_INDEX: return GL_STENCIL_INDEX;
181         default: throw invalid_argument("get_gl_components");
182         }
183 }
184
185 unsigned get_gl_pixelformat(PixelFormat pf)
186 {
187         switch(pf)
188         {
189         case R8: return GL_R8;
190         case R16F: return GL_R16F;
191         case R32F: return GL_R32F;
192         case RG8: return GL_RG8;
193         case RG16F: return GL_RG16F;
194         case RG32F: return GL_RG32F;
195         case RGB8: return GL_RGB8;
196         case RGB16F: return GL_RGB16F;
197         case RGB32F: return GL_RGB32F;
198         case RGBA8: return GL_RGBA8;
199         case RGBA16F: return GL_RGBA16F;
200         case RGBA32F: return GL_RGBA32F;
201         case SRGB8: return GL_SRGB8;
202         case SRGB8_ALPHA8: return GL_SRGB8_ALPHA8;
203         case DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16;
204         case DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24;
205         case DEPTH_COMPONENT32: return GL_DEPTH_COMPONENT32;
206         case DEPTH_COMPONENT32F: return GL_DEPTH_COMPONENT32F;
207         case STENCIL_INDEX8: return GL_STENCIL_INDEX8;
208         default: throw invalid_argument("get_gl_pixelformat");
209         }
210 }
211
212 } // namespace GL
213 } // namespace Msp