]> git.tdb.fi Git - libs/gl.git/commitdiff
Prefer RG pixelformats over LUMINANCE
authorMikko Rasa <tdb@tdb.fi>
Thu, 3 Nov 2016 11:12:06 +0000 (13:12 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 3 Nov 2016 11:25:41 +0000 (13:25 +0200)
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 [new file with mode: 0644]
source/pixelformat.h
source/texture.cpp
source/texture.h
source/texture1d.cpp
source/texture2d.cpp
source/texture3d.cpp
source/texturecube.cpp

diff --git a/extensions/arb_texture_swizzle.glext b/extensions/arb_texture_swizzle.glext
new file mode 100644 (file)
index 0000000..5249652
--- /dev/null
@@ -0,0 +1 @@
+extension ARB_texture_swizzle
index dcbb5948f69ad87a391cc1a6f2af4a26a3f997be..14ca580e5fc7e9cbdb22ebc9f5ce6f2725312f0b 100644 (file)
@@ -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,
index b545b16606eaa64a47c2baac3cedd82df39df029..18746e5f2ecad265652b12804c2ec927e5d13fcd 100644 (file)
@@ -1,5 +1,6 @@
 #include <msp/gl/extensions/arb_direct_state_access.h>
 #include <msp/gl/extensions/arb_shadow.h>
+#include <msp/gl/extensions/arb_texture_swizzle.h>
 #include <msp/gl/extensions/ext_framebuffer_object.h>
 #include <msp/gl/extensions/ext_texture3d.h>
 #include <msp/gl/extensions/ext_texture_filter_anisotropic.h>
@@ -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
index 1b80e950f08d93e54debd3bdc8b14ae4c7f458ac..abccb8d8122de9db6519fff679232d9923392715 100644 (file)
@@ -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;
index 6affe8999a2414ae61b950c8f3c232a9269e4af1..e25a11c09ce579b0fbed76a7ec6dc5a6ed5569fd 100644 (file)
@@ -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<<level;
        if(gen_mipmap && level==0)
@@ -83,6 +83,7 @@ void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelFormat fmt, D
        Conditional<BindRestore> _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
index e15f9a33562d1e1527ba3c5d76905db437945c7f..7ce18d00a9fa075b5df6b2a5ea1dac741411165f 100644 (file)
@@ -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<<level;
        if(gen_mipmap && level==0)
@@ -113,6 +113,7 @@ void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht
        Conditional<BindRestore> _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
index 680880a820be1507ba81fb0c252eafdcd98677ad..85b3f075f5096e47d92800ad734958189d0f0fa1 100644 (file)
@@ -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<<level;
        if(gen_mipmap && level==0)
@@ -101,6 +101,7 @@ void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsi
        Conditional<BindRestore> _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
index 19c3bf074b9a3557adf7668c4752f22bda3bcb8c..db679cf9e1259cb4feb0e087c0f3e066c40921c3 100644 (file)
@@ -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<<level;
@@ -116,7 +116,7 @@ void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y,
        BindRestore _bind(this);
        allocate(level);
 
-       glTexSubImage2D(face, level, x, y, wd, ht, fmt, type, data);
+       glTexSubImage2D(face, level, x, y, wd, ht, get_upload_format(fmt), type, data);
 
        if(gen_mipmap && level==0)
                auto_generate_mipmap();