]> git.tdb.fi Git - libs/gl.git/commitdiff
Deprecate the mipmap_levels parameter in Texture
authorMikko Rasa <tdb@tdb.fi>
Sat, 30 Jan 2021 17:57:58 +0000 (19:57 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 31 Jan 2021 00:26:45 +0000 (02:26 +0200)
Instead specify the desired amount of mipmap levels when loading an
image.  This can be more robustly checked against the defined storage.

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

index 68e4486120cb9cecdc919142727eb5f881a8d8a6..401cb968578d9d9eb7ac7e433869929d3f221e2f 100644 (file)
@@ -63,7 +63,6 @@ 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),
@@ -183,8 +182,6 @@ 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
@@ -221,12 +218,6 @@ 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)
@@ -308,11 +299,21 @@ void Texture::set_compare_func(Predicate f)
 }
 
 void Texture::load_image(const string &fn, bool srgb)
+{
+       load_image(fn, 0, srgb);
+}
+
+void Texture::load_image(const string &fn, unsigned lv, bool srgb)
 {
        Graphics::Image img;
        img.load_file(fn);
 
-       image(img, srgb);
+       image(img, lv, srgb);
+}
+
+void Texture::image(const Graphics::Image &img, bool srgb)
+{
+       image(img, 0, srgb);
 }
 
 void Texture::bind_to(unsigned i) const
@@ -386,6 +387,7 @@ Texture::Loader::Loader(Texture &t, Collection &c):
 
 void Texture::Loader::init()
 {
+       levels = 0;
        if(Resources *res = dynamic_cast<Resources *>(coll))
                srgb = res->get_srgb_conversion();
        else
@@ -413,7 +415,7 @@ void Texture::Loader::external_image(const string &fn)
                throw IO::file_not_found(fn);
        img.load_io(*io);
 
-       obj.image(img, srgb);
+       obj.image(img, levels, srgb);
 }
 
 void Texture::Loader::filter(TextureFilter f)
@@ -432,7 +434,7 @@ void Texture::Loader::image_data(const string &data)
        IO::Memory mem(data.data(), data.size());
        img.load_io(mem);
 
-       obj.image(img, srgb);
+       obj.image(img, levels, srgb);
 }
 
 void Texture::Loader::mag_filter(TextureFilter f)
@@ -452,7 +454,7 @@ void Texture::Loader::min_filter(TextureFilter f)
 
 void Texture::Loader::mipmap_levels(unsigned l)
 {
-       obj.set_mipmap_levels(l);
+       levels = l;
 }
 
 void Texture::Loader::wrap(TextureWrap w)
index 3fa29f60603ca66272d306b9cbe35c49e1d0ea27..8aac05927288cfcbcdb8253230f8df97829f6c82 100644 (file)
@@ -74,6 +74,7 @@ protected:
        class Loader: public DataFile::CollectionObjectLoader<Texture>
        {
        protected:
+               unsigned levels;
                bool srgb;
 
        public:
@@ -106,8 +107,7 @@ protected:
                COMPARE = 64,
                COMPARE_FUNC = 128,
                MAX_ANISOTROPY = 256,
-               FORMAT_SWIZZLE = 512,
-               MIPMAP_LEVELS = 1024
+               FORMAT_SWIZZLE = 512
        };
 
        enum FormatSwizzle
@@ -123,7 +123,6 @@ protected:
        FormatSwizzle swizzle;
        TextureFilter min_filter;
        TextureFilter mag_filter;
-       unsigned mipmap_levels;
        float max_anisotropy;
        TextureWrap wrap_s;
        TextureWrap wrap_t;
@@ -157,7 +156,7 @@ public:
        is not applicable to magnification, LINEAR is used instead. */
        void set_filter(TextureFilter);
 
-       void set_mipmap_levels(unsigned);
+       DEPRECATED void set_mipmap_levels(unsigned) { }
 
        void set_max_anisotropy(float);
 
@@ -191,13 +190,17 @@ public:
        /// Loads a Graphics::Image from a file and uploads it to the texture.
        virtual void load_image(const std::string &, bool srgb = false);
 
+       virtual void load_image(const std::string &, unsigned, bool srgb = false);
+
        /** 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 the defined storage.  Semantics depend on the type of texture.
 
        If srgb is true and storage is determined by this call, then an sRGB pixel
        format will be used. */
-       virtual void image(const Graphics::Image &, bool srgb = false) = 0;
+       virtual void image(const Graphics::Image &, bool srgb = false);
+
+       virtual void image(const Graphics::Image &, unsigned, bool srgb = false) = 0;
 
        GLenum get_target() const { return target; }
        unsigned get_id() const { return id; }
index d88b88c02e57c763d7c3b7731cbb4a159eb430d4..d09a9570306e077b771d31dce598757e2fc715fb 100644 (file)
@@ -71,13 +71,16 @@ void Texture1D::image(unsigned level, PixelFormat fmt, DataType type, const void
                return sub_image(level, 0, w, fmt, type, data);
 
        BindRestore _bind(this);
+
+       if(!allocated)
+               glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
        glTexImage1D(target, level, ifmt, w, 0, get_upload_format(fmt), type, data);
 
        allocated |= 1<<level;
        if(auto_gen_mipmap && level==0)
        {
                generate_mipmap();
-               allocated |= (1<<get_n_levels())-1;
+               allocated |= (1<<levels)-1;
        }
 }
 
@@ -99,7 +102,7 @@ void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelFormat fmt, D
                generate_mipmap();
 }
 
-void Texture1D::image(const Graphics::Image &img, bool srgb)
+void Texture1D::image(const Graphics::Image &img, unsigned lv, bool srgb)
 {
        if(img.get_height()!=1)
                throw incompatible_data("Texture1D::image");
@@ -108,7 +111,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) ? mipmap_levels ? mipmap_levels : 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? lv : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, l);
        }
        else if(w!=width)
index 506356c77676d98cea1a01d52d8a8f373a71f024..52a768759eba68cd26149d61b12c1060161b5460 100644 (file)
@@ -33,7 +33,8 @@ public:
        void allocate(unsigned);
        void image(unsigned, PixelFormat, DataType, const void *);
        void sub_image(unsigned, int, unsigned, PixelFormat, DataType, const void *);
-       virtual void image(const Graphics::Image &, bool = false);
+       virtual void image(const Graphics::Image &, unsigned, bool = false);
+       using Texture::image;
        unsigned get_width() const { return width; }
 
 private:
index 47e0c7434d0ef56c7fbf892b0ee45a31f4552710..7586862591675534a50bf13b076021701ec004b0 100644 (file)
@@ -101,13 +101,16 @@ 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);
+
+       if(!allocated)
+               glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
        glTexImage2D(target, level, ifmt, w, h, 0, get_upload_format(fmt), type, data);
 
        allocated |= 1<<level;
        if(auto_gen_mipmap && level==0)
        {
                generate_mipmap();
-               allocated |= (1<<get_n_levels())-1;
+               allocated |= (1<<levels)-1;
        }
 }
 
@@ -129,22 +132,22 @@ void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht
                generate_mipmap();
 }
 
-void Texture2D::image(const Graphics::Image &img, bool srgb)
+void Texture2D::image(const Graphics::Image &img, unsigned lv, bool srgb)
 {
-       image(img, srgb, false);
+       image(img, lv, srgb, false);
 }
 
-void Texture2D::image(const Graphics::Image &img, bool srgb, bool from_buffer)
+void Texture2D::image(const Graphics::Image &img, unsigned lv, bool srgb, bool from_buffer)
 {
        unsigned w = img.get_width();
        unsigned h = img.get_height();
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
        {
-               unsigned l = (is_mipmapped(min_filter) ? mipmap_levels ? mipmap_levels : 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? lv : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, l);
        }
-       else if(w!=width || h!=height)
+       else if(w!=width || h!=height || (lv && lv!=levels))
                throw incompatible_data("Texture2D::image");
 
        PixelStore pstore = PixelStore::from_image(img);
@@ -277,7 +280,7 @@ bool Texture2D::AsyncLoader::process()
                        else
                                glGenTextures(1, &texture.id);
                }
-               texture.image(image, srgb_conversion, true);
+               texture.image(image, 0, srgb_conversion, true);
        }
 
        ++phase;
index 2a49eca572ee06e25a7a770488b0639d6fd07fc9..aec31678b03a341efa7891ba0a0277f12cd9c624 100644 (file)
@@ -68,10 +68,12 @@ public:
 
        If srgb is true and storage is determined by this call, then an sRGB pixel
        format will be used. */
-       virtual void image(const Graphics::Image &, bool srgb = false);
+       virtual void image(const Graphics::Image &, unsigned lv, bool srgb = false);
+
+       using Texture::image;
 
 private:
-       void image(const Graphics::Image &, bool, bool);
+       void image(const Graphics::Image &, unsigned, bool, bool);
 
 public:
        unsigned get_width() const { return width; }
index 971d3f165393fd00ec631bd3620740111b3bfae5..c107fd7451a16a6f2f9c5368e065d20442249277 100644 (file)
@@ -90,13 +90,16 @@ 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);
+
+       if(!allocated)
+               glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
        glTexImage3D(target, level, ifmt, width, height, depth, 0, get_upload_format(fmt), type, data);
 
        allocated |= 1<<level;
        if(auto_gen_mipmap && level==0)
        {
                generate_mipmap();
-               allocated |= (1<<get_n_levels())-1;
+               allocated |= (1<<levels)-1;
        }
 }
 
@@ -164,7 +167,7 @@ void Texture3D::load_image(const string &fn, int dp)
        image(0, fmt, UNSIGNED_BYTE, img.get_data());
 }
 
-void Texture3D::image(const Graphics::Image &img, bool srgb)
+void Texture3D::image(const Graphics::Image &img, unsigned lv, bool srgb)
 {
        unsigned w = img.get_width();
        unsigned h = img.get_height();
@@ -188,7 +191,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) ? mipmap_levels ? mipmap_levels : 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? lv : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, h, d, l);
        }
        else if(w!=width || h!=height || d!=depth)
index 679b6a50ee609175c4725e4998a7aa5538b4f6bf..7847c2fc7b7889027fad0553aee364967e4517bf 100644 (file)
@@ -82,7 +82,9 @@ public:
 
        If srgb is true and storage is determined by this call, then an sRGB pixel
        format will be used. */
-       virtual void image(const Graphics::Image &, bool = false);
+       virtual void image(const Graphics::Image &, unsigned, bool = false);
+
+       using Texture::image;
 
        unsigned get_width() const { return width; }
        unsigned get_height() const { return height; }
index da7bb9250c59377267f0453163898c27ccff5801..82447e65b8f91cb53f2170aa6e44617ccbbf8aff 100644 (file)
@@ -102,6 +102,9 @@ 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);
+
+       if(!allocated)
+               glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
        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
@@ -110,7 +113,7 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelFormat fmt, D
        {
                // TODO Only do this once all faces are created
                generate_mipmap();
-               allocated |= (1<<get_n_levels())-1;
+               allocated |= (1<<levels)-1;
        }
 }
 
@@ -149,7 +152,7 @@ void TextureCube::image(TextureCubeFace face, const Graphics::Image &img, bool s
        image(face, 0, fmt, UNSIGNED_BYTE, img.get_data());
 }
 
-void TextureCube::image(const Graphics::Image &img, bool srgb)
+void TextureCube::image(const Graphics::Image &img, unsigned lv, bool srgb)
 {
        unsigned w = img.get_width();
        unsigned h = img.get_height();
@@ -161,7 +164,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) ? mipmap_levels ? mipmap_levels : 0 : 1);
+               unsigned l = (is_mipmapped(min_filter) ? lv : 1);
                storage(storage_pixelformat_from_graphics(img.get_format(), srgb), w, l);
        }
        else if(w!=size || h!=size)
index 0882a5e31004c3cef3e129b65ff24a2671e88fc0..f5a364047874aa10569e2fe1a4c727e69b47063b 100644 (file)
@@ -86,7 +86,8 @@ public:
 
        void image(TextureCubeFace, const Graphics::Image &, bool = false);
 
-       virtual void image(const Graphics::Image &, bool = false);
+       virtual void image(const Graphics::Image &, unsigned, bool = false);
+       using Texture::image;
 
        unsigned get_size() const { return size; }
 private: