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