From 33b6ca811172d402fc891eeed9cd2a5edc28d61d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 11 Sep 2021 17:23:56 +0300 Subject: [PATCH] Rework PixelComponents and PixelFormat to use custom values --- source/core/datatype.h | 1 + source/core/pixelformat.cpp | 271 ++++++----------------------------- source/core/pixelformat.h | 132 +++++++++-------- source/core/renderbuffer.cpp | 10 +- source/core/texture1d.cpp | 12 +- source/core/texture2d.cpp | 12 +- source/core/texture3d.cpp | 12 +- source/core/texturecube.cpp | 14 +- 8 files changed, 155 insertions(+), 309 deletions(-) diff --git a/source/core/datatype.h b/source/core/datatype.h index ccd288c9..d7414a26 100644 --- a/source/core/datatype.h +++ b/source/core/datatype.h @@ -91,6 +91,7 @@ enum DataType }; inline unsigned get_type_size(DataType t) { return t&0xFF; } +inline bool is_float(DataType t) { return t&0x200; } inline bool is_matrix(DataType t) { return t&0xC000; } inline bool is_vector(DataType t) { return !is_matrix(t) && (t&0x3000); } inline bool is_image(DataType t) { return t&0x70000; } diff --git a/source/core/pixelformat.cpp b/source/core/pixelformat.cpp index 9a28cdce..cfbf8112 100644 --- a/source/core/pixelformat.cpp +++ b/source/core/pixelformat.cpp @@ -96,7 +96,7 @@ void operator>>(const LexicalConverter &conv, PixelFormat &fmt) } } -PixelComponents pixelformat_from_graphics(Graphics::PixelFormat pf) +PixelComponents components_from_graphics(Graphics::PixelFormat pf) { switch(pf) { @@ -112,238 +112,16 @@ PixelComponents pixelformat_from_graphics(Graphics::PixelFormat pf) } } -PixelComponents storage_pixelformat_from_graphics(Graphics::PixelFormat pf) -{ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - switch(pf) - { - case Graphics::RGBX: - case Graphics::BGR: - case Graphics::BGRX: return RGB; - case Graphics::BGRA: return RGBA; - default: return pixelformat_from_graphics(pf); - } -#pragma GCC diagnostic pop -} - 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 + PixelComponents comp = components_from_graphics(image.get_format()); 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) -{ - switch(pf) - { - case SRGB8: return RGB8; - case SRGB8_ALPHA8: return RGBA8; - default: return pf; - } -} - -PixelComponents get_components(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 SRGB8: return RGB; - case RGBA8: - case RGBA16F: - 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 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: throw invalid_argument("get_components"); - } -} - -PixelFormat get_default_sized_pixelformat(PixelComponents comp) -{ - DataType type = UNSIGNED_BYTE; - if(comp==DEPTH_COMPONENT) - { - if(get_gl_api()==OPENGL_ES2 && !ARB_depth_buffer_float) - type = UNSIGNED_SHORT; - else - type = FLOAT; - } - return make_pixelformat(comp, type); -} - -PixelFormat get_srgb_pixelformat(PixelFormat pf) -{ - switch(pf) - { - case RGB8: return SRGB8; - case RGBA8: return SRGB8_ALPHA8; - default: return pf; - } -} - -unsigned get_component_count(PixelComponents comp) -{ - switch(comp) - { - case RED: - case LUMINANCE: - case DEPTH_COMPONENT: - case STENCIL_INDEX: - return 1; - case RG: - case LUMINANCE_ALPHA: - return 2; - case RGB: - case BGR: - return 3; - case RGBA: - case BGRA: - return 4; - default: - throw invalid_argument("get_component_count"); - } -} - -DataType get_component_type(PixelFormat pf) -{ - switch(pf) - { - case R8: - case RG8: - case RGB8: - case RGBA8: - case SRGB8: - case SRGB8_ALPHA8: - case BGR8: - case BGRA8: - case SBGR8: - case SBGR8_ALPHA8: - case LUMINANCE8: - case LUMINANCE8_ALPHA8: - return UNSIGNED_BYTE; - case R16F: - case RG16F: - case RGB16F: - case RGBA16F: - return HALF_FLOAT; - case DEPTH_COMPONENT16: - return UNSIGNED_SHORT; - case R32F: - case RG32F: - case RGB32F: - case RGBA32F: - case DEPTH_COMPONENT32: - return UNSIGNED_INT; - case DEPTH_COMPONENT32F: - return FLOAT; - case DEPTH_COMPONENT24: - // There's no DataType value with 24-bit size - default: - throw invalid_argument("get_component_type"); - } -} - -bool is_srgb(PixelFormat pf) -{ - return (pf==SRGB8 || pf==SRGB8_ALPHA8 || pf==SBGR8 || pf==SBGR8_ALPHA8); -} - -unsigned get_pixel_size(PixelFormat pf) -{ - return get_component_count(pf)*get_type_size(get_component_type(pf)); + bool normalized = !is_float(type); + return static_cast(comp | get_type_size(type)<<8 | (type&0x300)<<4 | normalized*0x4000 | srgb*0x8000); } void require_pixelformat(PixelFormat pf) @@ -397,5 +175,46 @@ void require_pixelformat(PixelFormat pf) } } +GLenum get_gl_components(PixelComponents comp) +{ + switch(comp) + { + case RED: return GL_RED; + case RG: return GL_RG; + case RGB: return GL_RGB; + case RGBA: return GL_RGBA; + case DEPTH_COMPONENT: return GL_DEPTH_COMPONENT; + case STENCIL_INDEX: return GL_STENCIL_INDEX; + default: throw invalid_argument("get_gl_components"); + } +} + +GLenum get_gl_pixelformat(PixelFormat pf) +{ + switch(pf) + { + case R8: return GL_R8; + case R16F: return GL_R16F; + case R32F: return GL_R32F; + case RG8: return GL_RG8; + case RG16F: return GL_RG16F; + case RG32F: return GL_RG32F; + case RGB8: return GL_RGB8; + case RGB16F: return GL_RGB16F; + case RGB32F: return GL_RGB32F; + case RGBA8: return GL_RGBA8; + case RGBA16F: return GL_RGBA16F; + case RGBA32F: return GL_RGBA32F; + case SRGB8: return GL_SRGB8; + case SRGB8_ALPHA8: return GL_SRGB8_ALPHA8; + case DEPTH_COMPONENT16: return GL_DEPTH_COMPONENT16; + case DEPTH_COMPONENT24: return GL_DEPTH_COMPONENT24; + case DEPTH_COMPONENT32: return GL_DEPTH_COMPONENT32; + case DEPTH_COMPONENT32F: return GL_DEPTH_COMPONENT32F; + case STENCIL_INDEX8: return GL_STENCIL_INDEX8; + default: throw invalid_argument("get_gl_pixelformat"); + } +} + } // namespace GL } // namespace Msp diff --git a/source/core/pixelformat.h b/source/core/pixelformat.h index c9d813ce..dde8594e 100644 --- a/source/core/pixelformat.h +++ b/source/core/pixelformat.h @@ -19,81 +19,97 @@ namespace Msp { namespace GL { +/** +Identifies the components of a pixel, without type information. The values +are bitfields laid as follows: + +_grs dccc + │││ │ └╴Number of components + │││ └───╴Depth flag + ││└─────╴Stencil flag + │└──────╴Reverse order flag + └───────╴Grayscale flag + +This information is presented for internal documentation purposes only; it is +inadvisable for programs to rely on it. +*/ enum PixelComponents { - RED = GL_RED, - RG = GL_RG, - RGB = GL_RGB, - RGBA = GL_RGBA, - BGR = GL_BGR, - BGRA = GL_BGRA, - LUMINANCE = GL_LUMINANCE, - LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA, - DEPTH_COMPONENT = GL_DEPTH_COMPONENT, - STENCIL_INDEX = GL_STENCIL_INDEX + RED = 0x01, + RG = 0x02, + RGB = 0x03, + RGBA = 0x04, + DEPTH_COMPONENT = 0x09, + STENCIL_INDEX = 0x11, + BGR = 0x23, + BGRA = 0x24, + LUMINANCE = 0x41, + LUMINANCE_ALPHA = 0x42 }; +/** +Identifies a pixel format, with components and type. The values are bitfields +laid as follows: + +tnfg ssss cccc cccc +││││ │ └╴Components (see PixelComponents) +││││ └──────────╴Size of one component (bytes) +│││└───────────────╴Signed flag +││└────────────────╴Floating-point flag +│└─────────────────╴Normalized flag +└──────────────────╴sRGB flag + +This information is presented for internal documentation purposes only; it is +inadvisable for programs to rely on it. +*/ enum PixelFormat { - R8 = GL_R8, - R16F = GL_R16F, - R32F = GL_R32F, - RG8 = GL_RG8, - RG16F = GL_RG16F, - RG32F = GL_RG32F, - RGB8 = GL_RGB8, - RGB16F = GL_RGB16F, - RGB32F = GL_RGB32F, - RGBA8 = GL_RGBA8, - RGBA16F = GL_RGBA16F, - RGBA32F = GL_RGBA32F, - SRGB8 = GL_SRGB8, - SRGB8_ALPHA8 = GL_SRGB8_ALPHA8, - BGR8 = 200000, - BGRA8 = 200001, - SBGR8 = 200002, - SBGR8_ALPHA8 = 200003, - LUMINANCE8 = GL_LUMINANCE8, - LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8, - DEPTH_COMPONENT16 = GL_DEPTH_COMPONENT16, - DEPTH_COMPONENT24 = GL_DEPTH_COMPONENT24, - DEPTH_COMPONENT32 = GL_DEPTH_COMPONENT32, - DEPTH_COMPONENT32F = GL_DEPTH_COMPONENT32F, - STENCIL_INDEX8 = GL_STENCIL_INDEX8 + R8 = 0x4100|RED, + R16F = 0x3200|RED, + R32F = 0x3400|RED, + RG8 = 0x4100|RG, + RG16F = 0x3200|RG, + RG32F = 0x3400|RG, + RGB8 = 0x4100|RGB, + RGB16F = 0x3200|RGB, + RGB32F = 0x3400|RGB, + RGBA8 = 0x4100|RGBA, + RGBA16F = 0x3200|RGBA, + RGBA32F = 0x3400|RGBA, + SRGB8 = 0xC100|RGB, + SRGB8_ALPHA8 = 0xC100|RGBA, + BGR8 = 0x4100|BGR, + BGRA8 = 0x4100|BGRA, + SBGR8 = 0xC100|BGR, + SBGR8_ALPHA8 = 0xC100|BGRA, + LUMINANCE8 = 0x4100|LUMINANCE, + LUMINANCE8_ALPHA8 = 0x4100|LUMINANCE_ALPHA, + DEPTH_COMPONENT16 = 0x4200|DEPTH_COMPONENT, + DEPTH_COMPONENT24 = 0x4300|DEPTH_COMPONENT, + DEPTH_COMPONENT32 = 0x4400|DEPTH_COMPONENT, + DEPTH_COMPONENT32F = 0x3400|DEPTH_COMPONENT, + STENCIL_INDEX8 = 0x0100|STENCIL_INDEX }; void operator>>(const LexicalConverter &, PixelComponents &); void operator>>(const LexicalConverter &, PixelFormat &); -DEPRECATED PixelComponents pixelformat_from_graphics(Graphics::PixelFormat); -DEPRECATED PixelComponents storage_pixelformat_from_graphics(Graphics::PixelFormat, bool); +PixelComponents components_from_graphics(Graphics::PixelFormat); PixelFormat pixelformat_from_image(const Graphics::Image &); PixelFormat make_pixelformat(PixelComponents, DataType, bool = false); -DEPRECATED PixelFormat get_base_pixelformat(PixelFormat); -PixelComponents get_components(PixelFormat); -DEPRECATED PixelFormat get_default_sized_pixelformat(PixelComponents); -DEPRECATED PixelFormat get_srgb_pixelformat(PixelFormat); - -unsigned get_component_count(PixelComponents); -inline unsigned get_component_count(PixelFormat f) -{ return get_component_count(get_components(f)); } - -DataType get_component_type(PixelFormat); -inline unsigned get_component_size(PixelFormat f) -{ return get_type_size(get_component_type(f)); } - -bool is_srgb(PixelFormat); - -unsigned get_pixel_size(PixelFormat); +inline PixelComponents get_components(PixelFormat f) { return static_cast(f&0xFF); } +inline unsigned get_component_count(PixelComponents c) { return c&7; } +inline unsigned get_component_count(PixelFormat f) { return get_component_count(get_components(f)); } +inline DataType get_component_type(PixelFormat f) { return static_cast((f&0xF00)>>8 | (f&0x3000)>>4); } +inline unsigned get_component_size(PixelFormat f) { return get_type_size(get_component_type(f)); } +inline bool is_srgb(PixelFormat f) { return f&0x8000; } +inline unsigned get_pixel_size(PixelFormat f) { return get_component_count(f)*get_type_size(get_component_type(f)); } void require_pixelformat(PixelFormat); -DEPRECATED inline PixelFormat get_sized_pixelformat(PixelComponents c, unsigned s = 1) -{ return make_pixelformat(c, (s==2 ? HALF_FLOAT : s==4 ? FLOAT : UNSIGNED_BYTE)); } - -DEPRECATED inline PixelComponents get_unsized_pixelformat(PixelFormat f) -{ return get_components(f); } +GLenum get_gl_components(PixelComponents); +GLenum get_gl_pixelformat(PixelFormat); } // namespace GL } // namespace Msp diff --git a/source/core/renderbuffer.cpp b/source/core/renderbuffer.cpp index 6851329b..844fcd3a 100644 --- a/source/core/renderbuffer.cpp +++ b/source/core/renderbuffer.cpp @@ -30,12 +30,13 @@ void Renderbuffer::storage(PixelFormat fmt, unsigned wd, unsigned ht) require_pixelformat(fmt); width = wd; height = ht; + GLenum gl_fmt = get_gl_pixelformat(fmt); if(ARB_direct_state_access) - glNamedRenderbufferStorage(id, fmt, width, height); + glNamedRenderbufferStorage(id, gl_fmt, width, height); else { glBindRenderbuffer(GL_RENDERBUFFER, id); - glRenderbufferStorage(GL_RENDERBUFFER, fmt, width, height); + glRenderbufferStorage(GL_RENDERBUFFER, gl_fmt, width, height); glBindRenderbuffer(GL_RENDERBUFFER, 0); } } @@ -58,12 +59,13 @@ void Renderbuffer::storage_multisample(unsigned samples, PixelFormat fmt, unsign width = wd; height = ht; + GLenum gl_fmt = get_gl_pixelformat(fmt); if(ARB_direct_state_access) - glNamedRenderbufferStorageMultisample(id, samples, fmt, width, height); + glNamedRenderbufferStorageMultisample(id, samples, gl_fmt, width, height); else { glBindRenderbuffer(GL_RENDERBUFFER, id); - glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, fmt, width, height); + glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, gl_fmt, width, height); glBindRenderbuffer(GL_RENDERBUFFER, 0); } } diff --git a/source/core/texture1d.cpp b/source/core/texture1d.cpp index 4c58d470..feff9f98 100644 --- a/source/core/texture1d.cpp +++ b/source/core/texture1d.cpp @@ -63,10 +63,11 @@ void Texture1D::allocate_(unsigned level) if(ARB_texture_storage) { + GLenum fmt = get_gl_pixelformat(storage_fmt); if(ARB_direct_state_access) - glTextureStorage1D(id, levels, storage_fmt, width); + glTextureStorage1D(id, levels, fmt, width); else - glTexStorage1D(target, levels, storage_fmt, width); + glTexStorage1D(target, levels, fmt, width); apply_swizzle(); allocated |= (1< size = get_level_size(level); - PixelComponents comp = get_components(storage_fmt); + GLenum fmt = get_gl_pixelformat(storage_fmt); + GLenum comp = get_gl_components(get_components(storage_fmt)); GLenum type = get_gl_type(get_component_type(storage_fmt)); - glTexImage2D(target, level, storage_fmt, size.x, size.y, 0, comp, type, data); + glTexImage2D(target, level, fmt, size.x, size.y, 0, comp, type, data); allocated |= 1< size = get_level_size(level); - PixelComponents comp = get_components(storage_fmt); + GLenum fmt = get_gl_pixelformat(storage_fmt); + GLenum comp = get_gl_components(get_components(storage_fmt)); GLenum type = get_gl_type(get_component_type(storage_fmt)); - glTexImage3D(target, level, storage_fmt, size.x, size.y, size.z, 0, comp, type, data); + glTexImage3D(target, level, fmt, size.x, size.y, size.z, 0, comp, type, data); allocated |= 1<