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"
11 void operator>>(const LexicalConverter &conv, PixelComponents &comp)
13 if(conv.get()=="STENCIL_INDEX")
15 else if(conv.get()=="DEPTH_COMPONENT")
16 comp = DEPTH_COMPONENT;
17 else if(conv.get()=="RED")
19 else if(conv.get()=="RG")
21 else if(conv.get()=="RGB")
23 else if(conv.get()=="RGBA")
25 else if(conv.get()=="BGR")
27 else if(conv.get()=="BGRA")
29 else if(conv.get()=="LUMINANCE")
31 else if(conv.get()=="LUMINANCE_ALPHA")
32 comp = LUMINANCE_ALPHA;
34 throw lexical_error(format("conversion of '%s' to PixelComponents", conv.get()));
37 void operator>>(const LexicalConverter &conv, PixelFormat &fmt)
41 else if(conv.get()=="R16F")
43 else if(conv.get()=="R32F")
45 else if(conv.get()=="RG8")
47 else if(conv.get()=="RG16F")
49 else if(conv.get()=="RG32F")
51 else if(conv.get()=="RGB8")
53 else if(conv.get()=="RGB16F")
55 else if(conv.get()=="RGB32F")
57 else if(conv.get()=="RGBA8")
59 else if(conv.get()=="RGBA16F")
61 else if(conv.get()=="RGBA32F")
63 else if(conv.get()=="SRGB8")
65 else if(conv.get()=="SRGB8_ALPHA8")
67 else if(conv.get()=="BGR8")
69 else if(conv.get()=="BGRA8")
71 else if(conv.get()=="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;
85 if(conv.get()=="SRGB")
87 else if(conv.get()=="SRGB_ALPHA")
93 fmt = make_pixelformat(comp, (comp==DEPTH_COMPONENT ? FLOAT : UNSIGNED_BYTE));
95 IO::print(IO::cerr, "Warning: deprecated conversion of '%s' to PixelFormat\n", conv.get());
99 PixelComponents components_from_graphics(Graphics::PixelFormat pf)
103 case Graphics::LUMINANCE: return LUMINANCE;
104 case Graphics::LUMINANCE_ALPHA: return LUMINANCE_ALPHA;
105 case Graphics::RGB: return RGB;
107 case Graphics::RGBA: return RGBA;
108 case Graphics::BGR: return BGR;
110 case Graphics::BGRA: return BGRA;
111 default: throw invalid_argument("pixelformat_from_graphics");
115 PixelFormat pixelformat_from_image(const Graphics::Image &image)
117 PixelComponents comp = components_from_graphics(image.get_format());
118 return make_pixelformat(comp, UNSIGNED_BYTE);
121 PixelFormat make_pixelformat(PixelComponents comp, DataType type, bool srgb)
123 bool normalized = !is_float(type);
124 return static_cast<PixelFormat>(comp | get_type_size(type)<<8 | (type&0x300)<<4 | normalized*0x4000 | srgb*0x8000);
127 void require_pixelformat(PixelFormat pf)
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
138 { static Require _req(OES_required_internalformat); }
142 { static Require _req(ARB_texture_rg); }
148 { static Require _req(ARB_texture_rg); }
149 { static Require _req(ARB_texture_float); }
155 { static Require _req(ARB_texture_float); }
159 { static Require _req(EXT_texture_sRGB); }
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); }
167 case DEPTH_COMPONENT32F:
168 { static Require _req(ARB_depth_buffer_float); }
171 { static Require _req(OES_texture_stencil8); }
174 throw invalid_argument("require_pixelformat");
178 GLenum get_gl_components(PixelComponents comp)
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");
192 GLenum get_gl_pixelformat(PixelFormat pf)
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");