From 1955e583d7eeeb0a2ff054d90c3694f575d9a08d Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 3 Nov 2016 13:12:06 +0200 Subject: [PATCH] Prefer RG pixelformats over LUMINANCE LUMINANCE formats were deprecated in OpenGL 3.0. ARB_texture_swizzle was not promoted to core until 3.3, so it's possible this won't work on some transition period hardware. SLUMINANCE formats are marked as deprecated in mspgl since it's not possible to properly emulate them through swizzling. --- extensions/arb_texture_swizzle.glext | 1 + source/pixelformat.h | 2 ++ source/texture.cpp | 41 ++++++++++++++++++++++++++++ source/texture.h | 14 +++++++++- source/texture1d.cpp | 3 +- source/texture2d.cpp | 3 +- source/texture3d.cpp | 3 +- source/texturecube.cpp | 4 +-- 8 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 extensions/arb_texture_swizzle.glext diff --git a/extensions/arb_texture_swizzle.glext b/extensions/arb_texture_swizzle.glext new file mode 100644 index 00000000..52496521 --- /dev/null +++ b/extensions/arb_texture_swizzle.glext @@ -0,0 +1 @@ +extension ARB_texture_swizzle diff --git a/source/pixelformat.h b/source/pixelformat.h index dcbb5948..14ca580e 100644 --- a/source/pixelformat.h +++ b/source/pixelformat.h @@ -48,6 +48,8 @@ enum PixelFormat LUMINANCE8 = GL_LUMINANCE8, LUMINANCE_ALPHA = GL_LUMINANCE_ALPHA, LUMINANCE8_ALPHA8 = GL_LUMINANCE8_ALPHA8, + + // Deprecated SLUMINANCE = GL_SLUMINANCE, SLUMINANCE8 = GL_SLUMINANCE8, SLUMINANCE_ALPHA = GL_SLUMINANCE_ALPHA, diff --git a/source/texture.cpp b/source/texture.cpp index b545b166..18746e5f 100644 --- a/source/texture.cpp +++ b/source/texture.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -49,6 +50,13 @@ void operator>>(const LexicalConverter &c, TextureWrap &tw) } +int Texture::swizzle_orders[] = +{ + GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, + GL_RED, GL_RED, GL_RED, GL_ONE, + GL_RED, GL_RED, GL_RED, GL_GREEN +}; + Texture::Texture(GLenum t, ResourceManager *m): id(0), target(t), @@ -93,8 +101,34 @@ void Texture::set_internal_format(PixelFormat fmt) fmt = get_sized_pixelformat(fmt, size); } + FormatSwizzle swiz = NO_SWIZZLE; + if(ARB_texture_rg && ARB_texture_swizzle) + { + if(fmt==LUMINANCE8 || fmt==SLUMINANCE8) + { + fmt = R8; + swiz = R_TO_LUMINANCE; + } + else if(fmt==LUMINANCE8_ALPHA8 || fmt==SLUMINANCE8_ALPHA8) + { + fmt = RG8; + swiz = RG_TO_LUMINANCE_ALPHA; + } + } + require_pixelformat(fmt); ifmt = fmt; + swizzle = swiz; + if(swizzle) + update_parameter(FORMAT_SWIZZLE); +} + +PixelFormat Texture::get_upload_format(PixelFormat fmt) const +{ + if(fmt==LUMINANCE || fmt==LUMINANCE_ALPHA) + return get_base_pixelformat(ifmt); + else + return fmt; } void Texture::update_parameter(int mask) const @@ -129,6 +163,13 @@ void Texture::update_parameter(int mask) const set_parameter_i(GL_TEXTURE_COMPARE_MODE, (compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE)); if(mask&COMPARE_FUNC) set_parameter_i(GL_TEXTURE_COMPARE_FUNC, cmp_func); + if(mask&FORMAT_SWIZZLE) + { + if(ARB_direct_state_access) + glTextureParameteriv(id, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4); + else + glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4); + } } void Texture::set_parameter_i(GLenum param, int value) const diff --git a/source/texture.h b/source/texture.h index 1b80e950..abccb8d8 100644 --- a/source/texture.h +++ b/source/texture.h @@ -104,12 +104,21 @@ protected: GENERATE_MIPMAP = 32, COMPARE = 64, COMPARE_FUNC = 128, - MAX_ANISOTROPY = 256 + MAX_ANISOTROPY = 256, + FORMAT_SWIZZLE = 512 + }; + + enum FormatSwizzle + { + NO_SWIZZLE, + R_TO_LUMINANCE, + RG_TO_LUMINANCE_ALPHA }; unsigned id; GLenum target; PixelFormat ifmt; + FormatSwizzle swizzle; TextureFilter min_filter; TextureFilter mag_filter; float max_anisotropy; @@ -121,6 +130,8 @@ protected: Predicate cmp_func; mutable int dirty_params; + static int swizzle_orders[]; + Texture(GLenum, ResourceManager * = 0); Texture(const Texture &); Texture &operator=(const Texture &); @@ -130,6 +141,7 @@ public: protected: static DataType get_alloc_type(PixelFormat); void set_internal_format(PixelFormat); + PixelFormat get_upload_format(PixelFormat) const; void update_parameter(int) const; void set_parameter_i(GLenum, int) const; diff --git a/source/texture1d.cpp b/source/texture1d.cpp index 6affe899..e25a11c0 100644 --- a/source/texture1d.cpp +++ b/source/texture1d.cpp @@ -65,7 +65,7 @@ void Texture1D::image(unsigned level, PixelFormat fmt, DataType type, const void return sub_image(level, 0, w, fmt, type, data); BindRestore _bind(this); - glTexImage1D(target, level, ifmt, w, 0, fmt, type, data); + glTexImage1D(target, level, ifmt, w, 0, get_upload_format(fmt), type, data); allocated |= 1< _bind(!ARB_direct_state_access, this); allocate(level); + fmt = get_upload_format(fmt); if(ARB_direct_state_access) glTextureSubImage1D(id, level, x, wd, fmt, type, data); else diff --git a/source/texture2d.cpp b/source/texture2d.cpp index e15f9a33..7ce18d00 100644 --- a/source/texture2d.cpp +++ b/source/texture2d.cpp @@ -95,7 +95,7 @@ void Texture2D::image(unsigned level, PixelFormat fmt, DataType type, const void return sub_image(level, 0, 0, w, h, fmt, type, data); BindRestore _bind(this); - glTexImage2D(target, level, ifmt, w, h, 0, fmt, type, data); + glTexImage2D(target, level, ifmt, w, h, 0, get_upload_format(fmt), type, data); allocated |= 1< _bind(!ARB_direct_state_access, this); allocate(level); + fmt = get_upload_format(fmt); if(ARB_direct_state_access) glTextureSubImage2D(id, level, x, y, wd, ht, fmt, type, data); else diff --git a/source/texture3d.cpp b/source/texture3d.cpp index 680880a8..85b3f075 100644 --- a/source/texture3d.cpp +++ b/source/texture3d.cpp @@ -83,7 +83,7 @@ void Texture3D::image(unsigned level, PixelFormat fmt, DataType type, const void return sub_image(level, 0, 0, 0, w, h, d, fmt, type, data); BindRestore _bind(this); - glTexImage3D(target, level, ifmt, width, height, depth, 0, fmt, type, data); + glTexImage3D(target, level, ifmt, width, height, depth, 0, get_upload_format(fmt), type, data); allocated |= 1< _bind(!ARB_direct_state_access, this); allocate(level); + fmt = get_upload_format(fmt); if(ARB_direct_state_access) glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, fmt, type, data); else diff --git a/source/texturecube.cpp b/source/texturecube.cpp index 19c3bf07..db679cf9 100644 --- a/source/texturecube.cpp +++ b/source/texturecube.cpp @@ -96,7 +96,7 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, D return sub_image(face, level, 0, 0, s, s, fmt, type, data); BindRestore _bind(this); - glTexImage2D(face, level, ifmt, s, s, 0, fmt, type, data); + glTexImage2D(face, level, ifmt, s, s, 0, get_upload_format(fmt), type, data); // XXX Allocation should be tracked per-face, but we'll run out of bits allocated |= 1<