X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fpixelformat.cpp;h=547a6a6970b4d69566b1a5552ca93a6a39c3fb47;hb=a40fc85277dba5c34402a0e703d038efd30cc57b;hp=cd3bb2aa78e30709293dd8dfb13f4d42cd4c481d;hpb=f1b12c992db974c679d85ae6ec22cd318199d0d5;p=libs%2Fgl.git diff --git a/source/pixelformat.cpp b/source/pixelformat.cpp index cd3bb2aa..547a6a69 100644 --- a/source/pixelformat.cpp +++ b/source/pixelformat.cpp @@ -14,6 +14,10 @@ void operator>>(const LexicalConverter &conv, PixelFormat &fmt) fmt = STENCIL_INDEX; else if(conv.get()=="DEPTH_COMPONENT") fmt = DEPTH_COMPONENT; + else if(conv.get()=="RED") + fmt = RED; + else if(conv.get()=="RG") + fmt = RG; else if(conv.get()=="RGB") fmt = RGB; else if(conv.get()=="RGBA") @@ -30,10 +34,6 @@ void operator>>(const LexicalConverter &conv, PixelFormat &fmt) fmt = LUMINANCE; else if(conv.get()=="LUMINANCE_ALPHA") fmt = LUMINANCE_ALPHA; - else if(conv.get()=="SLUMINANCE") - fmt = SLUMINANCE; - else if(conv.get()=="SLUMINANCE_ALPHA") - fmt = SLUMINANCE_ALPHA; else throw lexical_error(format("conversion of '%s' to PixelFormat", conv.get())); } @@ -54,46 +54,129 @@ PixelFormat pixelformat_from_graphics(Graphics::PixelFormat pf) } } -PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat pf) +PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat pf, bool srgb) { + PixelFormat result; switch(pf) { case Graphics::RGBX: case Graphics::BGR: - case Graphics::BGRX: return RGB; - case Graphics::BGRA: return RGBA; - default: return pixelformat_from_graphics(pf); + case Graphics::BGRX: result = RGB; break; + case Graphics::BGRA: result = RGBA; break; + default: result = pixelformat_from_graphics(pf); } + + if(srgb) + return get_srgb_pixelformat(result); + else + return result; } PixelFormat get_base_pixelformat(PixelFormat pf) +{ + PixelFormat unsized = get_unsized_pixelformat(pf); + switch(unsized) + { + case SRGB: return RGB; + case SRGB_ALPHA: return RGBA; + default: return unsized; + } +} + +PixelFormat get_unsized_pixelformat(PixelFormat pf) { switch(pf) { + case R8: + case R16F: + case R32F: return RED; + case RG8: + case RG16F: + case RG32F: return RG; case RGB8: case RGB16F: - case RGB32F: - case SRGB: - case SRGB8: return RGB; + case RGB32F: return RGB; + case SRGB8: return SRGB; case RGBA8: case RGBA16F: - case RGBA32F: - case SRGB_ALPHA: - case SRGB8_ALPHA8: return RGBA; - case LUMINANCE8: - case LUMINANCE16F: - case LUMINANCE32F: - case SLUMINANCE: - case SLUMINANCE8: return LUMINANCE; - case LUMINANCE_ALPHA8: - case LUMINANCE_ALPHA16F: - case LUMINANCE_ALPHA32F: - case SLUMINANCE_ALPHA: - case SLUMINANCE8_ALPHA8: return LUMINANCE_ALPHA; + case RGBA32F: return RGBA; + case SRGB8_ALPHA8: return SRGB_ALPHA; + case LUMINANCE8: return LUMINANCE; + case LUMINANCE8_ALPHA8: return LUMINANCE_ALPHA; + case DEPTH_COMPONENT16: + case DEPTH_COMPONENT24: + case DEPTH_COMPONENT32: + case DEPTH_COMPONENT32F: return DEPTH_COMPONENT; default: return pf; } } +PixelFormat get_sized_pixelformat(PixelFormat pf, unsigned size) +{ + if(!size || size>4) + throw invalid_argument("get_sized_pixelformat"); + + pf = get_unsized_pixelformat(pf); + + switch(size) + { + case 1: + switch(pf) + { + case RED: return R8; + case RG: return RG8; + case RGB: return RGB8; + case RGBA: return RGBA8; + case SRGB: return SRGB8; + case SRGB_ALPHA: return SRGB8_ALPHA8; + case LUMINANCE: return LUMINANCE8; + case LUMINANCE_ALPHA: return LUMINANCE8_ALPHA8; + default: throw invalid_argument("get_sized_pixelformat"); + } + case 2: + switch(pf) + { + case RED: return R16F; + case RG: return RG16F; + case RGB: return RGB16F; + case RGBA: return RGBA16F; + case DEPTH_COMPONENT: return DEPTH_COMPONENT16; + default: throw invalid_argument("get_sized_pixelformat"); + } + case 3: + if(pf==DEPTH_COMPONENT) + return DEPTH_COMPONENT24; + else + throw invalid_argument("get_sized_pixelformat"); + case 4: + switch(pf) + { + case RED: return R32F; + case RG: return RG32F; + case RGB: return RGB32F; + case RGBA: return RGBA32F; + case DEPTH_COMPONENT: return ARB_depth_buffer_float ? DEPTH_COMPONENT32F : DEPTH_COMPONENT32; + default: throw invalid_argument("get_sized_pixelformat"); + } + default: + throw invalid_argument("get_sized_pixelformat"); + } +} + +PixelFormat get_default_sized_pixelformat(PixelFormat pf) +{ + pf = get_unsized_pixelformat(pf); + unsigned size = 1; + if(pf==DEPTH_COMPONENT) + { + if(get_gl_api()==OPENGL_ES2 && !ARB_depth_buffer_float) + size = 2; + else + size = 4; + } + return get_sized_pixelformat(pf, size); +} + PixelFormat get_srgb_pixelformat(PixelFormat pf) { switch(pf) @@ -102,10 +185,6 @@ PixelFormat get_srgb_pixelformat(PixelFormat pf) case RGBA: return SRGB_ALPHA; case RGB8: return SRGB8; case RGBA8: return SRGB8_ALPHA8; - case LUMINANCE: return SLUMINANCE; - case LUMINANCE8: return SLUMINANCE8; - case LUMINANCE_ALPHA: return SLUMINANCE_ALPHA; - case LUMINANCE_ALPHA8: return SLUMINANCE8_ALPHA8; default: return pf; } } @@ -116,11 +195,11 @@ unsigned get_component_count(PixelFormat pf) { case STENCIL_INDEX: case DEPTH_COMPONENT: + case RED: case LUMINANCE: - case SLUMINANCE: return 1; + case RG: case LUMINANCE_ALPHA: - case SLUMINANCE_ALPHA: return 2; case RGB: case BGR: @@ -137,54 +216,97 @@ unsigned get_component_size(PixelFormat pf) { switch(pf) { + case R8: + case RG8: + case RGB8: + case RGBA8: + case SRGB8: + case SRGB8_ALPHA8: + case LUMINANCE8: + case LUMINANCE8_ALPHA8: + return 1; + case R16F: + case RG16F: case RGB16F: case RGBA16F: - case LUMINANCE16F: - case LUMINANCE_ALPHA16F: + case DEPTH_COMPONENT16: return 2; + case DEPTH_COMPONENT24: + return 3; + case R32F: + case RG32F: case RGB32F: case RGBA32F: - case LUMINANCE32F: - case LUMINANCE_ALPHA32F: + case DEPTH_COMPONENT32: + case DEPTH_COMPONENT32F: return 4; default: - return 1; + return 0; } } unsigned get_pixel_size(PixelFormat pf) { - return get_component_count(pf)*get_component_size(pf); + return get_component_count(pf)*max(get_component_size(pf), 1U); } void require_pixelformat(PixelFormat pf) { + /* TODO These checks are only accurate for textures. On OpenGL ES some + formats are allowed for render buffers earlier than textures. In particular + it's possible to create a 16-bit depth renderbuffer on OpenGL ES 2.0 but + depth textures are only available with 3.0 or the OES_depth_texture + extension.*/ switch(pf) { + case RGB8: + case RGBA8: + { static Require _req(OES_required_internalformat); } + break; + case RED: + case R8: + case RG: + case RG8: + { static Require _req(ARB_texture_rg); } + break; + case R16F: + case R32F: + case RG16F: + case RG32F: + { static Require _req(ARB_texture_rg); } + { static Require _req(ARB_texture_float); } + break; case RGB16F: case RGB32F: case RGBA16F: case RGBA32F: - case LUMINANCE16F: - case LUMINANCE32F: - case LUMINANCE_ALPHA16F: - case LUMINANCE_ALPHA32F: { static Require _req(ARB_texture_float); } break; case SRGB: case SRGB8: case SRGB_ALPHA: case SRGB8_ALPHA8: - case SLUMINANCE: - case SLUMINANCE8: - case SLUMINANCE_ALPHA: - case SLUMINANCE8_ALPHA8: { static Require _req(EXT_texture_sRGB); } break; case BGR: case BGRA: { static Require _req(EXT_bgra); } break; + case DEPTH_COMPONENT: + { static Require _req(ARB_depth_texture); } + break; + case DEPTH_COMPONENT16: + case DEPTH_COMPONENT24: + case DEPTH_COMPONENT32: + { static Require _req(ARB_depth_texture); } + { static Require _req(OES_required_internalformat); } + break; + case DEPTH_COMPONENT32F: + { static Require _req(ARB_depth_buffer_float); } + break; + case STENCIL_INDEX: + { static Require _req(OES_texture_stencil8); } + break; default: break; }