Allow the maximum mipmap level of a texture to be specified
authorMikko Rasa <tdb@tdb.fi>
Mon, 2 Jul 2018 12:49:48 +0000 (15:49 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 2 Jul 2018 12:50:20 +0000 (15:50 +0300)
This doubles as a way to specify the number of mipmap levels to allocate
when the tetxure image is loaded from a Graphics::Image.

source/texture.cpp
source/texture.h
source/texture1d.cpp
source/texture2d.cpp
source/texture3d.cpp
source/texturecube.cpp

index 820dd10fd90318c64278ae9b0aed66cf227d8743..719d4a56ac029218cbd176ac076644865fc20c72 100644 (file)
@@ -63,6 +63,7 @@ Texture::Texture(GLenum t, ResourceManager *m):
        ifmt(RGB),
        min_filter(NEAREST_MIPMAP_LINEAR),
        mag_filter(LINEAR),
+       mipmap_levels(0),
        max_anisotropy(1.0f),
        wrap_s(REPEAT),
        wrap_t(REPEAT),
@@ -178,6 +179,8 @@ void Texture::update_parameter(int mask) const
                                glTexParameteriv(target, GL_TEXTURE_SWIZZLE_RGBA, swizzle_orders+swizzle*4);
                }
        }
+       if(mask&MIPMAP_LEVELS)
+               set_parameter_i(GL_TEXTURE_MAX_LEVEL, (mipmap_levels ? mipmap_levels-1 : 1000));
 }
 
 void Texture::set_parameter_i(GLenum param, int value) const
@@ -214,6 +217,12 @@ void Texture::set_filter(TextureFilter f)
        set_mag_filter(f==NEAREST ? NEAREST : LINEAR);
 }
 
+void Texture::set_mipmap_levels(unsigned l)
+{
+       mipmap_levels = l;
+       update_parameter(MIPMAP_LEVELS);
+}
+
 void Texture::set_max_anisotropy(float a)
 {
        if(a<1.0f)
@@ -403,6 +412,7 @@ void Texture::Loader::init()
        add("mag_filter", &Loader::mag_filter);
        add("max_anisotropy", &Loader::max_anisotropy);
        add("min_filter", &Loader::min_filter);
+       add("mipmap_levels", &Loader::mipmap_levels);
        add("wrap",       &Loader::wrap);
        add("wrap_r",     &Loader::wrap_r);
        add("wrap_s",     &Loader::wrap_s);
@@ -452,6 +462,11 @@ void Texture::Loader::min_filter(TextureFilter f)
        obj.set_min_filter(f);
 }
 
+void Texture::Loader::mipmap_levels(unsigned l)
+{
+       obj.set_mipmap_levels(l);
+}
+
 void Texture::Loader::wrap(TextureWrap w)
 {
        obj.set_wrap(w);
index ffc5e1a4ab40a1f2f6ccee04b93c8423ee003eea..94614c45c7319748c102456dcd6c1b3bb6119649 100644 (file)
@@ -88,6 +88,7 @@ protected:
                void mag_filter(TextureFilter);
                void max_anisotropy(float);
                void min_filter(TextureFilter);
+               void mipmap_levels(unsigned);
                void wrap(TextureWrap);
                void wrap_r(TextureWrap);
                void wrap_s(TextureWrap);
@@ -105,7 +106,8 @@ protected:
                COMPARE = 64,
                COMPARE_FUNC = 128,
                MAX_ANISOTROPY = 256,
-               FORMAT_SWIZZLE = 512
+               FORMAT_SWIZZLE = 512,
+               MIPMAP_LEVELS = 1024
        };
 
        enum FormatSwizzle
@@ -121,6 +123,7 @@ protected:
        FormatSwizzle swizzle;
        TextureFilter min_filter;
        TextureFilter mag_filter;
+       unsigned mipmap_levels;
        float max_anisotropy;
        TextureWrap wrap_s;
        TextureWrap wrap_t;
@@ -154,6 +157,8 @@ public:
        is not applicable to magnification, LINEAR is used instead. */
        void set_filter(TextureFilter);
 
+       void set_mipmap_levels(unsigned);
+
        void set_max_anisotropy(float);
 
        /** Sets the wrapping mode for all coordinates. */
index a1ee418b22381a27916c407a6d8050459c02ddb0..7466a9efa2bc0d0fb3ef9b48f2330bb8499b59cf 100644 (file)
@@ -108,7 +108,7 @@ void Texture1D::image(const Graphics::Image &img, bool srgb)
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
        {
-               unsigned l = (is_mipmapped(min_filter) ? 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, l);
        }
        else if(w!=width)
index 44ee6406420e85f261c988f5e8b14f678c90cfe3..45c2e665d056973ee4ecdb41eb6033dd831c2b5b 100644 (file)
@@ -141,7 +141,7 @@ void Texture2D::image(const Graphics::Image &img, bool srgb, bool from_buffer)
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
        {
-               unsigned l = (is_mipmapped(min_filter) ? 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, l);
        }
        else if(w!=width || h!=height)
index 36fdfa0f3b8f6b591fd19b7f4d4047fa45c0ba06..ed5619cb4aed30f567cf7e3e063a7ad05f60fd27 100644 (file)
@@ -188,7 +188,7 @@ void Texture3D::image(const Graphics::Image &img, bool srgb)
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
        {
-               unsigned l = (is_mipmapped(min_filter) ? 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, d, l);
        }
        else if(w!=width || h!=height || d!=depth)
index ee8c71c5b0399e88f7c15b375878cf64623a4472..03e65167d73fee7a1d89ba9ea3cea7ef2c68d81d 100644 (file)
@@ -161,7 +161,7 @@ void TextureCube::image(const Graphics::Image &img, bool srgb)
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(size==0)
        {
-               unsigned l = (is_mipmapped(min_filter) ? 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, l);
        }
        else if(w!=size || h!=size)