From 9087cc0a372b9c739f15398c7a22c0a6eb5041bb Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 1 Feb 2021 21:08:29 +0200 Subject: [PATCH] Separate abstract pixel compositions from concrete pixel formats Texture and renderbuffer storage must now be specified using a sized pixel format. The PixelFormat API has also been refactored. --- extensions/msp_luminance_formats.glext | 1 + gl.msp.xml | 9 + source/ambientocclusion.cpp | 4 +- source/colorcurve.cpp | 2 +- source/datatype.h | 6 +- source/environmentmap.cpp | 4 +- source/pipeline.cpp | 2 +- source/pixelformat.cpp | 297 +++++++++++++++---------- source/pixelformat.h | 65 ++++-- source/pixelstore.cpp | 2 +- source/renderbuffer.cpp | 10 - source/renderbuffer.h | 4 - source/rendertarget.cpp | 33 ++- source/shadowmap.cpp | 2 +- source/texture.cpp | 26 +-- source/texture.h | 3 +- source/texture1d.cpp | 29 ++- source/texture1d.h | 8 +- source/texture2d.cpp | 29 ++- source/texture2d.h | 7 +- source/texture2darray.cpp | 8 +- source/texture2darray.h | 2 +- source/texture3d.cpp | 29 ++- source/texture3d.h | 7 +- source/texturecube.cpp | 34 +-- source/texturecube.h | 7 +- 26 files changed, 358 insertions(+), 272 deletions(-) create mode 100644 extensions/msp_luminance_formats.glext diff --git a/extensions/msp_luminance_formats.glext b/extensions/msp_luminance_formats.glext new file mode 100644 index 00000000..c513e084 --- /dev/null +++ b/extensions/msp_luminance_formats.glext @@ -0,0 +1 @@ +extension MSP_luminance_formats diff --git a/gl.msp.xml b/gl.msp.xml index 0309a61d..7895a806 100644 --- a/gl.msp.xml +++ b/gl.msp.xml @@ -45,5 +45,14 @@ + + + + + + + + + diff --git a/source/ambientocclusion.cpp b/source/ambientocclusion.cpp index 8826964a..b1dccc0e 100644 --- a/source/ambientocclusion.cpp +++ b/source/ambientocclusion.cpp @@ -12,7 +12,7 @@ namespace Msp { namespace GL { AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float): - occlude_target(w, h, (RENDER_COLOR,RED)), + occlude_target(w, h, (RENDER_COLOR,R8)), occlude_shader("ambientocclusion_occlude.glsl"), combine_shader("ambientocclusion_combine.glsl"), quad(get_fullscreen_quad()) @@ -21,7 +21,7 @@ AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float): texturing.attach(2, occlude_target.get_target_texture(RENDER_COLOR)); unsigned seed = 1; - rotate_lookup.storage(RGBA, 4, 4, 1); + rotate_lookup.storage(RGBA8, 4, 4, 1); rotate_lookup.get_default_sampler().set_filter(NEAREST); unsigned char data[64]; for(unsigned i=0; i<16; ++i) diff --git a/source/colorcurve.cpp b/source/colorcurve.cpp index 8983df2b..1f6f7bf9 100644 --- a/source/colorcurve.cpp +++ b/source/colorcurve.cpp @@ -18,7 +18,7 @@ ColorCurve::ColorCurve(): shdata.uniform("source", 0); shdata.uniform("curve", 1); - curve.storage(LUMINANCE, 256, 1); + curve.storage(LUMINANCE8, 256, 1); Sampler &sampler = curve.get_default_sampler(); sampler.set_min_filter(LINEAR); sampler.set_wrap(CLAMP_TO_EDGE); diff --git a/source/datatype.h b/source/datatype.h index 0d52408a..2d783f61 100644 --- a/source/datatype.h +++ b/source/datatype.h @@ -2,6 +2,7 @@ #define MSP_GL_DATATYPE_H_ #include "gl.h" +#include namespace Msp { namespace GL { @@ -14,9 +15,12 @@ enum DataType UNSIGNED_SHORT = GL_UNSIGNED_SHORT, INT = GL_INT, UNSIGNED_INT = GL_UNSIGNED_INT, - FLOAT = GL_FLOAT + FLOAT = GL_FLOAT, + HALF_FLOAT = GL_HALF_FLOAT }; +unsigned get_type_size(DataType); + } // namespace GL } // namespace Msp diff --git a/source/environmentmap.cpp b/source/environmentmap.cpp index ac68ff99..f4000c76 100644 --- a/source/environmentmap.cpp +++ b/source/environmentmap.cpp @@ -17,11 +17,11 @@ EnvironmentMap::EnvironmentMap(unsigned s, Renderable &r, Renderable &e): update_interval(1), update_delay(0) { - env_tex.storage(RGB, size, 1); + env_tex.storage(RGB8, size, 1); Sampler &env_samp = env_tex.get_default_sampler(); env_samp.set_wrap(CLAMP_TO_EDGE); env_samp.set_min_filter(LINEAR); - depth_buf.storage(DEPTH_COMPONENT, size, size); + depth_buf.storage(DEPTH_COMPONENT32F, size, size); for(unsigned i=0; i<6; ++i) { fbo[i].attach(COLOR_ATTACHMENT0, env_tex, TextureCube::enumerate_faces(i), 0); diff --git a/source/pipeline.cpp b/source/pipeline.cpp index 26073549..a7f4130b 100644 --- a/source/pipeline.cpp +++ b/source/pipeline.cpp @@ -234,7 +234,7 @@ void Pipeline::create_targets(unsigned recreate) target_ms = 0; } - PixelFormat color_pf = (hdr ? (alpha ? RGBA16F : RGB16F) : (alpha ? RGBA : RGB)); + PixelFormat color_pf = (hdr ? (alpha ? RGBA16F : RGB16F) : (alpha ? RGBA8 : RGB8)); RenderTargetFormat fmt = (RENDER_COLOR,color_pf, RENDER_DEPTH); if(!postproc.empty() || samples) { diff --git a/source/pixelformat.cpp b/source/pixelformat.cpp index dcc6b4ee..cc6a6d00 100644 --- a/source/pixelformat.cpp +++ b/source/pixelformat.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include "pixelformat.h" @@ -8,37 +8,84 @@ 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; + 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()=="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) { @@ -54,36 +101,105 @@ 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) + 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 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; - 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) { @@ -95,99 +211,49 @@ 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 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: 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; - 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"); + default: throw invalid_argument("get_components"); } } -PixelFormat get_default_sized_pixelformat(PixelFormat pf) +PixelFormat get_default_sized_pixelformat(PixelComponents comp) { - pf = get_unsized_pixelformat(pf); - unsigned size = 1; - if(pf==DEPTH_COMPONENT) + DataType type = UNSIGNED_BYTE; + if(comp==DEPTH_COMPONENT) { if(get_gl_api()==OPENGL_ES2 && !ARB_depth_buffer_float) - size = 2; + type = UNSIGNED_SHORT; else - size = 4; + type = FLOAT; } - return get_sized_pixelformat(pf, size); + 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; 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: @@ -208,7 +274,7 @@ unsigned get_component_count(PixelFormat pf) } } -unsigned get_component_size(PixelFormat pf) +DataType get_component_type(PixelFormat pf) { switch(pf) { @@ -218,30 +284,34 @@ unsigned get_component_size(PixelFormat pf) case RGBA8: case SRGB8: case SRGB8_ALPHA8: - return 1; + case LUMINANCE8: + case LUMINANCE8_ALPHA8: + 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) @@ -257,9 +327,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; @@ -276,19 +344,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: { 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: @@ -298,11 +357,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"); } } diff --git a/source/pixelformat.h b/source/pixelformat.h index 377335f2..9dec8234 100644 --- a/source/pixelformat.h +++ b/source/pixelformat.h @@ -1,7 +1,8 @@ #ifndef MSP_GL_PIXELFORMAT_H_ #define MSP_GL_PIXELFORMAT_H_ -#include +#include +#include #include #include "gl.h" #include @@ -12,22 +13,28 @@ #include #include #include +#include +#include "datatype.h" namespace Msp { namespace GL { -enum PixelFormat +enum PixelComponents { STENCIL_INDEX = GL_STENCIL_INDEX, DEPTH_COMPONENT = GL_DEPTH_COMPONENT, - DEPTH_COMPONENT16 = GL_DEPTH_COMPONENT16, - DEPTH_COMPONENT24 = GL_DEPTH_COMPONENT24, - DEPTH_COMPONENT32 = GL_DEPTH_COMPONENT32, - DEPTH_COMPONENT32F = GL_DEPTH_COMPONENT32F, 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 +}; + +enum PixelFormat +{ R8 = GL_R8, R16F = GL_R16F, R32F = GL_R32F, @@ -40,32 +47,48 @@ enum PixelFormat RGBA8 = GL_RGBA8, RGBA16F = GL_RGBA16F, RGBA32F = GL_RGBA32F, - SRGB = GL_SRGB, - SRGB_ALPHA = GL_SRGB_ALPHA, SRGB8 = GL_SRGB8, SRGB8_ALPHA8 = GL_SRGB8_ALPHA8, - BGR = GL_BGR, - BGRA = GL_BGRA, - LUMINANCE = GL_LUMINANCE, - LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA + 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 }; +void operator>>(const LexicalConverter &, PixelComponents &); void operator>>(const LexicalConverter &, PixelFormat &); -PixelFormat pixelformat_from_graphics(Graphics::PixelFormat); -PixelFormat storage_pixelformat_from_graphics(Graphics::PixelFormat, bool = false); +DEPRECATED PixelComponents pixelformat_from_graphics(Graphics::PixelFormat); +DEPRECATED PixelComponents storage_pixelformat_from_graphics(Graphics::PixelFormat, bool); +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)); } -PixelFormat get_base_pixelformat(PixelFormat); -PixelFormat get_unsized_pixelformat(PixelFormat); -PixelFormat get_sized_pixelformat(PixelFormat, unsigned = 1); -PixelFormat get_default_sized_pixelformat(PixelFormat); -PixelFormat get_srgb_pixelformat(PixelFormat); -unsigned get_component_count(PixelFormat); -unsigned get_component_size(PixelFormat); unsigned get_pixel_size(PixelFormat); 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); } + } // namespace GL } // namespace Msp diff --git a/source/pixelstore.cpp b/source/pixelstore.cpp index e1a7cc0e..409f0f9a 100644 --- a/source/pixelstore.cpp +++ b/source/pixelstore.cpp @@ -23,7 +23,7 @@ PixelStore PixelStore::from_image(const Graphics::Image &img) { PixelStore pstore; unsigned stride = img.get_stride(); - unsigned ncomp = get_component_count(pixelformat_from_graphics(img.get_format())); + unsigned ncomp = get_component_count(pixelformat_from_image(img)); pstore.set_canvas_size(img.get_stride()/ncomp, 0); pstore.set_alignment(min(stride&~(stride-1), 8U)); return pstore; diff --git a/source/renderbuffer.cpp b/source/renderbuffer.cpp index 5bea07fc..e86a97a5 100644 --- a/source/renderbuffer.cpp +++ b/source/renderbuffer.cpp @@ -24,17 +24,8 @@ Renderbuffer::~Renderbuffer() glDeleteRenderbuffers(1, &id); } -PixelFormat Renderbuffer::normalize_format(PixelFormat fmt) -{ - if(!get_component_size(fmt) && OES_required_internalformat) - return get_default_sized_pixelformat(fmt); - - return fmt; -} - void Renderbuffer::storage(PixelFormat fmt, unsigned wd, unsigned ht) { - fmt = normalize_format(fmt); require_pixelformat(fmt); width = wd; height = ht; @@ -62,7 +53,6 @@ void Renderbuffer::storage_multisample(unsigned samples, PixelFormat fmt, unsign if(samples>get_max_samples()) throw out_of_range("Renderbuffer::storage_multisample"); - fmt = normalize_format(fmt); require_pixelformat(fmt); width = wd; diff --git a/source/renderbuffer.h b/source/renderbuffer.h index 751374bd..afc6ed20 100644 --- a/source/renderbuffer.h +++ b/source/renderbuffer.h @@ -31,10 +31,6 @@ public: unsigned get_width() const { return width; } unsigned get_height() const { return height; } -private: - static PixelFormat normalize_format(PixelFormat); - -public: /** Allocates storage for the renderbuffer. */ void storage(PixelFormat fmt, unsigned wd, unsigned ht); diff --git a/source/rendertarget.cpp b/source/rendertarget.cpp index 74b4f322..1349944b 100644 --- a/source/rendertarget.cpp +++ b/source/rendertarget.cpp @@ -34,19 +34,21 @@ RenderTargetFormat RenderTargetFormat::operator,(PixelFormat f) const if(!count) throw invalid_operation("RenderTargetFormat::operator,"); - PixelFormat unsized = get_unsized_pixelformat(f); + PixelComponents comp = get_components(f); unsigned size = get_component_size(f); unsigned char out = outputs[count-1]; if(get_output_type(out)>=get_output_type(RENDER_DEPTH)) { - if(unsized!=DEPTH_COMPONENT) - throw invalid_argument("RenderTargetformat::operator,"); + if(comp!=DEPTH_COMPONENT) + throw invalid_argument("RenderTargetFormat::operator,"); if(size>1) --size; + if(get_component_type(f)==UNSIGNED_INT) + --size; } else { - if(unsized!=RED && unsized!=RG && unsized!=RGB && unsized!=RGBA) + if(comp!=RED && comp!=RG && comp!=RGB && comp!=RGBA) throw invalid_argument("RenderTargetformat::operator,"); if(size>3) --size; @@ -72,26 +74,23 @@ int RenderTargetFormat::index(RenderOutput o) const PixelFormat get_output_pixelformat(unsigned char o) { - unsigned size = ((o>>2)&3); - PixelFormat base; + PixelComponents comp; + DataType type; if(get_output_type(o)>=get_output_type(RENDER_DEPTH)) { - base = DEPTH_COMPONENT; - if(size) - ++size; + static DataType types[4] = { UNSIGNED_SHORT, UNSIGNED_SHORT, UNSIGNED_INT, FLOAT }; + comp = DEPTH_COMPONENT; + type = types[(o>>2)&3]; } else { - static PixelFormat base_formats[4] = { RED, RG, RGB, RGBA }; - base = base_formats[o&3]; - if(size==3) - ++size; + static PixelComponents components[4] = { RED, RG, RGB, RGBA }; + static DataType types[4] = { UNSIGNED_BYTE, UNSIGNED_SHORT, HALF_FLOAT, FLOAT }; + comp = components[o&3]; + type = types[(o>>2)&3]; } - if(size) - return get_sized_pixelformat(base, size); - else - return base; + return make_pixelformat(comp, type); } diff --git a/source/shadowmap.cpp b/source/shadowmap.cpp index 5d658807..6250f899 100644 --- a/source/shadowmap.cpp +++ b/source/shadowmap.cpp @@ -24,7 +24,7 @@ ShadowMap::ShadowMap(unsigned s, Renderable &r, const Light &l): depth_samp.set_min_filter(LINEAR); depth_samp.set_compare(LEQUAL); depth_samp.set_wrap(CLAMP_TO_EDGE); - depth_buf.storage(DEPTH_COMPONENT, size, size, 1); + depth_buf.storage(DEPTH_COMPONENT32F, size, size, 1); fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0); fbo.require_complete(); diff --git a/source/texture.cpp b/source/texture.cpp index 772f2d16..f0c55999 100644 --- a/source/texture.cpp +++ b/source/texture.cpp @@ -24,7 +24,7 @@ int Texture::swizzle_orders[] = Texture::Texture(GLenum t, ResourceManager *m): id(0), target(t), - ifmt(RGB), + ifmt(RGB8), swizzle(NO_SWIZZLE), auto_gen_mipmap(false), default_sampler(*this) @@ -46,30 +46,24 @@ Texture::~Texture() glDeleteTextures(1, &id); } -DataType Texture::get_alloc_type(PixelFormat fmt) -{ - return (get_base_pixelformat(fmt)==DEPTH_COMPONENT ? UNSIGNED_SHORT : UNSIGNED_BYTE); -} - void Texture::set_internal_format(PixelFormat fmt) { + PixelComponents comp = get_components(fmt); FormatSwizzle swiz = NO_SWIZZLE; - switch(get_base_pixelformat(fmt)) + switch(comp) { case LUMINANCE: - fmt = RED; + comp = RED; swiz = R_TO_LUMINANCE; break; case LUMINANCE_ALPHA: - fmt = RG; + comp = RG; swiz = RG_TO_LUMINANCE_ALPHA; break; default:; } - if(!get_component_size(fmt) && OES_required_internalformat) - fmt = get_default_sized_pixelformat(fmt); - + fmt = make_pixelformat(comp, get_component_type(fmt)); require_pixelformat(fmt); if(swiz!=NO_SWIZZLE) static Require _req(ARB_texture_swizzle); @@ -77,12 +71,12 @@ void Texture::set_internal_format(PixelFormat fmt) swizzle = swiz; } -PixelFormat Texture::get_upload_format(PixelFormat fmt) const +PixelComponents Texture::get_upload_components(PixelComponents comp) const { - if(fmt==LUMINANCE || fmt==LUMINANCE_ALPHA) - return get_base_pixelformat(ifmt); + if(comp==LUMINANCE || comp==LUMINANCE_ALPHA) + return get_components(ifmt); else - return fmt; + return comp; } void Texture::apply_swizzle() diff --git a/source/texture.h b/source/texture.h index adcfa76b..71192fef 100644 --- a/source/texture.h +++ b/source/texture.h @@ -83,9 +83,8 @@ public: ~Texture(); protected: - static DataType get_alloc_type(PixelFormat); void set_internal_format(PixelFormat); - PixelFormat get_upload_format(PixelFormat) const; + PixelComponents get_upload_components(PixelComponents) const; void apply_swizzle(); void set_parameter_i(GLenum, int) const; diff --git a/source/texture1d.cpp b/source/texture1d.cpp index b50f8cf4..24266150 100644 --- a/source/texture1d.cpp +++ b/source/texture1d.cpp @@ -53,13 +53,10 @@ void Texture1D::allocate(unsigned level) allocated |= (1< _bind(!ARB_direct_state_access, this); allocate(level); - fmt = get_upload_format(fmt); + comp = get_upload_components(comp); if(ARB_direct_state_access) - glTextureSubImage1D(id, level, x, wd, fmt, type, data); + glTextureSubImage1D(id, level, x, wd, comp, type, data); else - glTexSubImage1D(target, level, x, wd, fmt, type, data); + glTexSubImage1D(target, level, x, wd, comp, type, data); if(auto_gen_mipmap && level==0) generate_mipmap(); @@ -110,13 +107,15 @@ void Texture1D::image(const Graphics::Image &img, unsigned lv, bool srgb) throw incompatible_data("Texture1D::image"); unsigned w = img.get_width(); - PixelFormat fmt = pixelformat_from_graphics(img.get_format()); + PixelFormat fmt = pixelformat_from_image(img); + PixelComponents comp = get_components(fmt); + DataType type = get_component_type(fmt); if(width==0) - storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, lv); + storage(make_pixelformat(comp, type, srgb), w, lv); else if(w!=width) throw incompatible_data("Texture1D::image"); - image(0, fmt, UNSIGNED_BYTE, img.get_data()); + image(0, comp, type, img.get_data()); } unsigned Texture1D::get_n_levels() const @@ -158,7 +157,7 @@ void Texture1D::Loader::init() void Texture1D::Loader::raw_data(const string &data) { - obj.image(0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data()); + obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data()); } void Texture1D::Loader::storage(PixelFormat fmt, unsigned w) diff --git a/source/texture1d.h b/source/texture1d.h index eb16696f..b0a9c681 100644 --- a/source/texture1d.h +++ b/source/texture1d.h @@ -31,9 +31,13 @@ public: Texture1D(); void storage(PixelFormat, unsigned, unsigned = 0); + + DEPRECATED void storage(PixelComponents c, unsigned w, unsigned l = 0) + { storage(make_pixelformat(c, UNSIGNED_BYTE), w, l); } + void allocate(unsigned); - void image(unsigned, PixelFormat, DataType, const void *); - void sub_image(unsigned, int, unsigned, PixelFormat, DataType, const void *); + void image(unsigned, PixelComponents, DataType, const void *); + void sub_image(unsigned, int, unsigned, PixelComponents, DataType, const void *); virtual void image(const Graphics::Image &, unsigned, bool = false); using Texture::image; unsigned get_width() const { return width; } diff --git a/source/texture2d.cpp b/source/texture2d.cpp index 559167f8..8846a555 100644 --- a/source/texture2d.cpp +++ b/source/texture2d.cpp @@ -81,13 +81,10 @@ void Texture2D::allocate(unsigned level) allocated |= (1< _bind(!ARB_direct_state_access, this); allocate(level); - fmt = get_upload_format(fmt); + comp = get_upload_components(comp); if(ARB_direct_state_access) - glTextureSubImage2D(id, level, x, y, wd, ht, fmt, type, data); + glTextureSubImage2D(id, level, x, y, wd, ht, comp, type, data); else - glTexSubImage2D(target, level, x, y, wd, ht, fmt, type, data); + glTexSubImage2D(target, level, x, y, wd, ht, comp, type, data); if(auto_gen_mipmap && level==0) generate_mipmap(); @@ -143,16 +140,18 @@ void Texture2D::image(const Graphics::Image &img, unsigned lv, bool srgb, bool f { unsigned w = img.get_width(); unsigned h = img.get_height(); - PixelFormat fmt = pixelformat_from_graphics(img.get_format()); + PixelFormat fmt = pixelformat_from_image(img); + PixelComponents comp = get_components(fmt); + DataType type = get_component_type(fmt); if(width==0) - storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, lv); + storage(make_pixelformat(comp, type, srgb), w, h, lv); else if(w!=width || h!=height || (lv && lv!=levels)) throw incompatible_data("Texture2D::image"); PixelStore pstore = PixelStore::from_image(img); BindRestore _bind_ps(pstore); - image(0, fmt, UNSIGNED_BYTE, from_buffer ? 0 : img.get_data()); + image(0, comp, type, from_buffer ? 0 : img.get_data()); } unsigned Texture2D::get_n_levels() const @@ -216,7 +215,7 @@ void Texture2D::Loader::init() void Texture2D::Loader::raw_data(const string &data) { - obj.image(0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data()); + obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data()); } void Texture2D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h) diff --git a/source/texture2d.h b/source/texture2d.h index 092f12ba..801d18dd 100644 --- a/source/texture2d.h +++ b/source/texture2d.h @@ -48,6 +48,9 @@ public: it can't be changed. */ void storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned lv = 0); + DEPRECATED void storage(PixelComponents cm, unsigned wd, unsigned ht, unsigned lv = 0) + { storage(make_pixelformat(cm, UNSIGNED_BYTE), wd, ht, lv); } + /** Allocates storage for the texture. The contents are initially undefined. If storage has already been allocated, does nothing. */ void allocate(unsigned level); @@ -55,13 +58,13 @@ public: /** Uploads an image to the texture. Storage must be defined beforehand. The image data must have dimensions and format compatible with the defined storage. */ - void image(unsigned level, PixelFormat fmt, DataType type, const void *data); + void image(unsigned level, PixelComponents fmt, DataType type, const void *data); /** Updates a rectangular region of the texture. Storage must be defined and allocated beforehand. The update region must be fully inside the texture. */ void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, - PixelFormat fmt, DataType type, const void *data); + PixelComponents fmt, DataType type, const void *data); /** Uploads an image to the texture. If storage has not been defined, it will be set to match the image. Otherwise the image must be compatible with diff --git a/source/texture2darray.cpp b/source/texture2darray.cpp index 1a085ed8..34b9532d 100644 --- a/source/texture2darray.cpp +++ b/source/texture2darray.cpp @@ -15,14 +15,14 @@ Texture2DArray::Texture2DArray(): static Require _req(EXT_texture_array); } -void Texture2DArray::layer_image(unsigned level, unsigned z, PixelFormat fmt, DataType type, const void *data) +void Texture2DArray::layer_image(unsigned level, unsigned z, PixelComponents comp, DataType type, const void *data) { unsigned w = get_width(); unsigned h = get_height(); unsigned d = get_depth(); get_level_size(level, w, h, d); - sub_image(level, 0, 0, z, w, h, 1, fmt, type, data); + sub_image(level, 0, 0, z, w, h, 1, comp, type, data); } void Texture2DArray::layer_image(unsigned level, unsigned z, const Graphics::Image &img) @@ -32,14 +32,14 @@ void Texture2DArray::layer_image(unsigned level, unsigned z, const Graphics::Ima unsigned w = img.get_width(); unsigned h = img.get_height(); - PixelFormat fmt = pixelformat_from_graphics(img.get_format()); + PixelFormat fmt = pixelformat_from_image(img); if(w!=get_width() || h!=get_height()) throw incompatible_data("Texture2DArray::layer_image"); PixelStore pstore = PixelStore::from_image(img); BindRestore _bind_ps(pstore); - layer_image(level, z, fmt, UNSIGNED_BYTE, img.get_data()); + layer_image(level, z, get_components(fmt), get_component_type(fmt), img.get_data()); } diff --git a/source/texture2darray.h b/source/texture2darray.h index 5e0969aa..6aa4886c 100644 --- a/source/texture2darray.h +++ b/source/texture2darray.h @@ -27,7 +27,7 @@ public: Texture2DArray(); - void layer_image(unsigned, unsigned, PixelFormat, DataType, const void *); + void layer_image(unsigned, unsigned, PixelComponents, DataType, const void *); void layer_image(unsigned, unsigned, const Graphics::Image &); unsigned get_layers() const { return get_depth(); } diff --git a/source/texture3d.cpp b/source/texture3d.cpp index 5c09f1ea..010609a8 100644 --- a/source/texture3d.cpp +++ b/source/texture3d.cpp @@ -69,13 +69,10 @@ void Texture3D::allocate(unsigned level) allocated |= (1< _bind(!ARB_direct_state_access, this); allocate(level); - fmt = get_upload_format(fmt); + comp = get_upload_components(comp); if(ARB_direct_state_access) - glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, fmt, type, data); + glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, comp, type, data); else - glTexSubImage3D(target, level, x, y, z, wd, ht, dp, fmt, type, data); + glTexSubImage3D(target, level, x, y, z, wd, ht, dp, comp, type, data); if(auto_gen_mipmap && level==0) generate_mipmap(); @@ -144,16 +141,18 @@ void Texture3D::image(const Graphics::Image &img, unsigned lv, bool srgb) h = w; } - PixelFormat fmt = pixelformat_from_graphics(img.get_format()); + PixelFormat fmt = pixelformat_from_image(img); + PixelComponents comp = get_components(fmt); + DataType type = get_component_type(fmt); if(width==0) - storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, d, lv); + storage(make_pixelformat(comp, type, srgb), w, h, d, lv); else if(w!=width || h!=height || d!=depth) throw incompatible_data("Texture3D::load_image"); PixelStore pstore = PixelStore::from_image(img); BindRestore _bind_ps(pstore); - image(0, fmt, UNSIGNED_BYTE, img.get_data()); + image(0, comp, type, img.get_data()); } unsigned Texture3D::get_n_levels() const @@ -208,7 +207,7 @@ void Texture3D::Loader::init() void Texture3D::Loader::raw_data(const string &data) { - obj.image(0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data()); + obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data()); } void Texture3D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h, unsigned d) diff --git a/source/texture3d.h b/source/texture3d.h index 08084716..ecdff9d6 100644 --- a/source/texture3d.h +++ b/source/texture3d.h @@ -46,6 +46,9 @@ public: it can't be changed. */ void storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned dp, unsigned lv = 0); + DEPRECATED void storage(PixelComponents c, unsigned w, unsigned h, unsigned d, unsigned l = 0) + { storage(make_pixelformat(c, UNSIGNED_BYTE), w, h, d, l); } + /** Allocates storage for the texture. The contents are initially undefined. If storage has already been allocated, does nothing. */ void allocate(unsigned level); @@ -53,14 +56,14 @@ public: /** Uploads an image to the texture. Storage must be defined beforehand. The image data must have dimensions and format compatible with the defined storage. */ - void image(unsigned level, PixelFormat fmt, DataType type, const void *data); + void image(unsigned level, PixelComponents, DataType type, const void *data); /** Updates a cuboid-shaped region of the texture. Storage must be defined and allocated beforehand. The update region must be fully inside the texture. */ void sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, - PixelFormat fmt, DataType type, const void *data); + PixelComponents comp, DataType type, const void *data); /** Uploads an image to the texture. If storage has not been defined, it will be set to match the image. In this case the image will be treated as diff --git a/source/texturecube.cpp b/source/texturecube.cpp index 8d194c42..b0887ca8 100644 --- a/source/texturecube.cpp +++ b/source/texturecube.cpp @@ -83,14 +83,14 @@ void TextureCube::allocate(unsigned level) } else { - PixelFormat base_fmt = get_base_pixelformat(ifmt); - DataType type = get_alloc_type(base_fmt); + PixelComponents comp = get_components(ifmt); + DataType type = get_component_type(ifmt); for(unsigned i=0; i<6; ++i) - image(enumerate_faces(i), level, base_fmt, type, 0); + image(enumerate_faces(i), level, comp, type, 0); } } -void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, DataType type, const void *data) +void TextureCube::image(TextureCubeFace face, unsigned level, PixelComponents comp, DataType type, const void *data) { if(size==0) throw invalid_operation("TextureCube::image"); @@ -100,7 +100,7 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, D throw out_of_range("TextureCube::image"); if(ARB_texture_storage) - return sub_image(face, level, 0, 0, s, s, fmt, type, data); + return sub_image(face, level, 0, 0, s, s, comp, type, data); BindRestore _bind(this); @@ -109,7 +109,7 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, D glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1); apply_swizzle(); } - glTexImage2D(face, level, ifmt, s, s, 0, get_upload_format(fmt), type, data); + glTexImage2D(face, level, ifmt, s, s, 0, get_upload_components(comp), type, data); if(level==0) { @@ -128,13 +128,13 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, D { for(unsigned i=0; i<6; ++i) if(enumerate_faces(i)!=face) - glTexImage2D(enumerate_faces(i), level, ifmt, s, s, 0, get_upload_format(fmt), type, 0); + glTexImage2D(enumerate_faces(i), level, ifmt, s, s, 0, comp, type, 0); allocated |= 64<(img.get_data()); unsigned face_size = img.get_stride()*size; for(unsigned i=0; i<6; ++i) - image(enumerate_faces(i), 0, fmt, UNSIGNED_BYTE, cdata+i*face_size); + image(enumerate_faces(i), 0, comp, type, cdata+i*face_size); } unsigned TextureCube::get_n_levels() const @@ -298,7 +300,7 @@ void TextureCube::Loader::image_data(TextureCubeFace face, const string &data) void TextureCube::Loader::raw_data(TextureCubeFace face, const string &data) { - obj.image(face, 0, get_base_pixelformat(obj.ifmt), UNSIGNED_BYTE, data.data()); + obj.image(face, 0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data()); } void TextureCube::Loader::storage(PixelFormat fmt, unsigned s) diff --git a/source/texturecube.h b/source/texturecube.h index 7659917d..f7160983 100644 --- a/source/texturecube.h +++ b/source/texturecube.h @@ -70,6 +70,9 @@ public: it can't be changed. */ void storage(PixelFormat fmt, unsigned size, unsigned lv = 0); + DEPRECATED void storage(PixelComponents c, unsigned s, unsigned l = 0) + { storage(make_pixelformat(c, UNSIGNED_BYTE), s, l); } + /** Allocates storage for the cube faces. The contents are initially undefined. If storage has already been allocated, does nothing. */ void allocate(unsigned level); @@ -78,14 +81,14 @@ public: image data must have dimensions and format compatible with the defined storage. */ void image(TextureCubeFace face, unsigned level, - PixelFormat fmt, DataType type, const void *data); + PixelComponents comp, DataType type, const void *data); /** Updates a rectangular region of a face. Storage must be defined and allocated beforehand. The update region must be fully inside the texture. The data format must be compatible with the defined storage. */ void sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned w, unsigned h, - PixelFormat fmt, DataType type, const void *data); + PixelComponents comp, DataType type, const void *data); void image(TextureCubeFace, const Graphics::Image &, bool = false); -- 2.43.0