X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fpixelformat.cpp;h=87191c3423122aefde6b7e38110daae5d28cb4d0;hp=6655c6b22c3b3205e06be0bbe338e643209d2da9;hb=bec07999d95b76f4b47cffcc564d0cd0afc0435e;hpb=ee1da735a016a4df724fb18e60dec6a6f9bf3d6e diff --git a/source/pixelformat.cpp b/source/pixelformat.cpp index 6655c6b2..87191c34 100644 --- a/source/pixelformat.cpp +++ b/source/pixelformat.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include "pixelformat.h" @@ -8,41 +8,88 @@ using namespace std; namespace Msp { namespace GL { -void operator>>(const LexicalConverter &conv, PixelFormat &fmt) +void operator>>(const LexicalConverter &conv, PixelComponents &comp) { if(conv.get()=="STENCIL_INDEX") - fmt = STENCIL_INDEX; + comp = STENCIL_INDEX; else if(conv.get()=="DEPTH_COMPONENT") - fmt = DEPTH_COMPONENT; + comp = DEPTH_COMPONENT; else if(conv.get()=="RED") - fmt = RED; + comp = RED; else if(conv.get()=="RG") - fmt = RG; + comp = RG; else if(conv.get()=="RGB") - fmt = RGB; + comp = RGB; else if(conv.get()=="RGBA") - fmt = RGBA; + comp = RGBA; else if(conv.get()=="BGR") - fmt = BGR; + comp = BGR; else if(conv.get()=="BGRA") - fmt = BGRA; - else if(conv.get()=="SRGB") - fmt = SRGB; - else if(conv.get()=="SRGB_ALPHA") - fmt = SRGB_ALPHA; + comp = BGRA; else if(conv.get()=="LUMINANCE") - fmt = LUMINANCE; + comp = 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; + comp = LUMINANCE_ALPHA; else throw lexical_error(format("conversion of '%s' to PixelFormat", conv.get())); } -PixelFormat pixelformat_from_graphics(Graphics::PixelFormat pf) +void operator>>(const LexicalConverter &conv, PixelFormat &fmt) +{ + if(conv.get()=="R8") + fmt = R8; + else if(conv.get()=="R16F") + fmt = R16F; + else if(conv.get()=="R32F") + fmt = R32F; + else if(conv.get()=="RG8") + fmt = RG8; + else if(conv.get()=="RG16F") + fmt = RG16F; + else if(conv.get()=="RG32F") + fmt = RG32F; + else if(conv.get()=="RGB8") + fmt = RGB8; + else if(conv.get()=="RGB16F") + fmt = RGB16F; + else if(conv.get()=="RGB32F") + fmt = RGB32F; + else if(conv.get()=="RGBA8") + fmt = RGBA8; + else if(conv.get()=="RGBA16F") + fmt = RGBA16F; + else if(conv.get()=="RGBA32F") + fmt = RGBA32F; + else if(conv.get()=="SRGB8") + fmt = SRGB8; + else if(conv.get()=="SRGB8_ALPHA8") + fmt = SRGB8_ALPHA8; + else if(conv.get()=="BGR8") + fmt = BGR8; + else if(conv.get()=="BGRA8") + fmt = BGRA8; + else if(conv.get()=="LUMINANCE8") + fmt = LUMINANCE8; + else if(conv.get()=="LUMINANCE8_ALPHA8") + fmt = LUMINANCE8_ALPHA8; + else if(conv.get()=="DEPTH_COMPONENT16") + fmt = DEPTH_COMPONENT16; + else if(conv.get()=="DEPTH_COMPONENT24") + fmt = DEPTH_COMPONENT24; + else if(conv.get()=="DEPTH_COMPONENT32") + fmt = DEPTH_COMPONENT32; + else if(conv.get()=="DEPTH_COMPONENT32F") + fmt = DEPTH_COMPONENT32F; + else + { + PixelComponents comp; + conv >> comp; + fmt = make_pixelformat(comp, (comp==DEPTH_COMPONENT ? FLOAT : UNSIGNED_BYTE)); + IO::print(IO::cerr, "Warning: deprecated conversion of '%s' to PixelFormat\n", conv.get()); + } +} + +PixelComponents pixelformat_from_graphics(Graphics::PixelFormat pf) { switch(pf) { @@ -58,38 +105,113 @@ PixelFormat pixelformat_from_graphics(Graphics::PixelFormat pf) } } -PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat pf, bool srgb) +PixelComponents storage_pixelformat_from_graphics(Graphics::PixelFormat pf) { - PixelFormat result; +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" switch(pf) { case Graphics::RGBX: case Graphics::BGR: - case Graphics::BGRX: result = RGB; break; - case Graphics::BGRA: result = RGBA; break; - default: result = pixelformat_from_graphics(pf); + case Graphics::BGRX: return RGB; + case Graphics::BGRA: return RGBA; + default: return pixelformat_from_graphics(pf); } +#pragma GCC diagnostic pop +} - if(srgb) - return get_srgb_pixelformat(result); - else - return result; +PixelFormat pixelformat_from_image(const Graphics::Image &image) +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + PixelComponents comp = pixelformat_from_graphics(image.get_format()); +#pragma GCC diagnostic pop + return make_pixelformat(comp, UNSIGNED_BYTE); +} + +PixelFormat make_pixelformat(PixelComponents comp, DataType type, bool srgb) +{ + if(srgb && type!=UNSIGNED_BYTE && comp!=RGB && comp!=RGBA && comp!=BGR && comp!=BGRA) + throw invalid_argument("make_pixelformat"); + + switch(comp) + { + case RED: + switch(type) + { + case UNSIGNED_BYTE: return R8; + case HALF_FLOAT: return R16F; + case FLOAT: return R32F; + default: throw invalid_argument("make_pixelformat"); + } + case RG: + switch(type) + { + case UNSIGNED_BYTE: return RG8; + case HALF_FLOAT: return RG16F; + case FLOAT: return RG32F; + default: throw invalid_argument("make_pixelformat"); + } + case RGB: + switch(type) + { + case UNSIGNED_BYTE: return (srgb ? SRGB8 : RGB8); + case HALF_FLOAT: return RGB16F; + case FLOAT: return RGB32F; + default: throw invalid_argument("make_pixelformat"); + } + case RGBA: + switch(type) + { + case UNSIGNED_BYTE: return (srgb ? SRGB8_ALPHA8 : RGBA8); + case HALF_FLOAT: return RGBA16F; + case FLOAT: return RGBA32F; + default: throw invalid_argument("make_pixelformat"); + } + case BGR: + if(type!=UNSIGNED_BYTE) + throw invalid_argument("make_pixelformat"); + return (srgb ? BGR8 : SBGR8); + case BGRA: + if(type!=UNSIGNED_BYTE) + throw invalid_argument("make_pixelformat"); + return (srgb ? BGRA8 : SBGR8_ALPHA8); + case LUMINANCE: + if(type!=UNSIGNED_BYTE) + throw invalid_argument("make_pixelformat"); + return LUMINANCE8; + case LUMINANCE_ALPHA: + if(type!=UNSIGNED_BYTE) + throw invalid_argument("make_pixelformat"); + return LUMINANCE8; + case STENCIL_INDEX: + if(type!=UNSIGNED_BYTE) + throw invalid_argument("make_pixelformat"); + return STENCIL_INDEX8; + case DEPTH_COMPONENT: + switch(type) + { + case UNSIGNED_SHORT: return DEPTH_COMPONENT16; + case UNSIGNED_INT: return DEPTH_COMPONENT32; + case FLOAT: return DEPTH_COMPONENT32F; + default: throw invalid_argument("make_pixelformat"); + } + default: + throw invalid_argument("make_pixelformat"); + } } PixelFormat get_base_pixelformat(PixelFormat pf) { - PixelFormat unsized = get_unsized_pixelformat(pf); - switch(unsized) + switch(pf) { - case SRGB: return RGB; - case SRGB_ALPHA: return RGBA; - case SLUMINANCE: return LUMINANCE; - case SLUMINANCE_ALPHA: return LUMINANCE_ALPHA; - default: return unsized; + case SRGB8: return RGB8; + case SRGB8_ALPHA8: return RGBA8; + default: return pf; } } -PixelFormat get_unsized_pixelformat(PixelFormat pf) +PixelComponents get_components(PixelFormat pf) { switch(pf) { @@ -101,107 +223,61 @@ PixelFormat get_unsized_pixelformat(PixelFormat pf) case RG32F: return RG; case RGB8: case RGB16F: - case RGB32F: return RGB; - case SRGB8: return SRGB; + case RGB32F: + case SRGB8: return RGB; case RGBA8: case RGBA16F: - case RGBA32F: return RGBA; - case SRGB8_ALPHA8: return SRGB_ALPHA; + case RGBA32F: + case SRGB8_ALPHA8: return RGBA; + case BGR8: + case SBGR8: return BGR; + case BGRA8: + case SBGR8_ALPHA8: return BGRA; case LUMINANCE8: return LUMINANCE; - case SLUMINANCE8: return SLUMINANCE; - case LUMINANCE_ALPHA8: return LUMINANCE_ALPHA; - case SLUMINANCE8_ALPHA8: return SLUMINANCE_ALPHA; + case LUMINANCE8_ALPHA8: return LUMINANCE_ALPHA; + case STENCIL_INDEX8: return STENCIL_INDEX; case DEPTH_COMPONENT16: case DEPTH_COMPONENT24: case DEPTH_COMPONENT32: case DEPTH_COMPONENT32F: return DEPTH_COMPONENT; - default: return pf; + default: throw invalid_argument("get_components"); } } -PixelFormat get_sized_pixelformat(PixelFormat pf, unsigned size) +PixelFormat get_default_sized_pixelformat(PixelComponents comp) { - if(!size || size>4) - throw invalid_argument("get_sized_pixelformat"); - - pf = get_unsized_pixelformat(pf); - - switch(size) + DataType type = UNSIGNED_BYTE; + if(comp==DEPTH_COMPONENT) { - 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 SLUMINANCE: return SLUMINANCE8; - case LUMINANCE_ALPHA: return LUMINANCE8_ALPHA8; - case SLUMINANCE_ALPHA: return SLUMINANCE8_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; + if(get_gl_api()==OPENGL_ES2 && !ARB_depth_buffer_float) + type = UNSIGNED_SHORT; 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"); + type = FLOAT; } + return make_pixelformat(comp, type); } PixelFormat get_srgb_pixelformat(PixelFormat pf) { switch(pf) { - case RGB: return SRGB; - 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; } } -unsigned get_component_count(PixelFormat pf) +unsigned get_component_count(PixelComponents comp) { - switch(get_base_pixelformat(pf)) + switch(comp) { - case STENCIL_INDEX: - case DEPTH_COMPONENT: case RED: case LUMINANCE: - case SLUMINANCE: + case DEPTH_COMPONENT: + case STENCIL_INDEX: return 1; case RG: case LUMINANCE_ALPHA: - case SLUMINANCE_ALPHA: return 2; case RGB: case BGR: @@ -214,7 +290,7 @@ unsigned get_component_count(PixelFormat pf) } } -unsigned get_component_size(PixelFormat pf) +DataType get_component_type(PixelFormat pf) { switch(pf) { @@ -224,34 +300,38 @@ unsigned get_component_size(PixelFormat pf) case RGBA8: case SRGB8: case SRGB8_ALPHA8: + case BGR8: + case BGRA8: + case SBGR8: + case SBGR8_ALPHA8: case LUMINANCE8: case LUMINANCE8_ALPHA8: - case SLUMINANCE8: - case SLUMINANCE8_ALPHA8: - return 1; + return UNSIGNED_BYTE; case R16F: case RG16F: case RGB16F: case RGBA16F: + return HALF_FLOAT; case DEPTH_COMPONENT16: - return 2; - case DEPTH_COMPONENT24: - return 3; + return UNSIGNED_SHORT; case R32F: case RG32F: case RGB32F: case RGBA32F: case DEPTH_COMPONENT32: + return UNSIGNED_INT; case DEPTH_COMPONENT32F: - return 4; + return FLOAT; + case DEPTH_COMPONENT24: + // There's no DataType value with 24-bit size default: - return 0; + throw invalid_argument("get_component_type"); } } unsigned get_pixel_size(PixelFormat pf) { - return get_component_count(pf)*max(get_component_size(pf), 1U); + return get_component_count(pf)*get_type_size(get_component_type(pf)); } void require_pixelformat(PixelFormat pf) @@ -267,9 +347,7 @@ void require_pixelformat(PixelFormat pf) case RGBA8: { static Require _req(OES_required_internalformat); } break; - case RED: case R8: - case RG: case RG8: { static Require _req(ARB_texture_rg); } break; @@ -286,23 +364,10 @@ void require_pixelformat(PixelFormat pf) case RGBA32F: { 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: @@ -312,11 +377,11 @@ void require_pixelformat(PixelFormat pf) case DEPTH_COMPONENT32F: { static Require _req(ARB_depth_buffer_float); } break; - case STENCIL_INDEX: + case STENCIL_INDEX8: { static Require _req(OES_texture_stencil8); } break; default: - break; + throw invalid_argument("require_pixelformat"); } }