]> git.tdb.fi Git - libs/gl.git/commitdiff
Require texture data to be uploaded in a format matching the storage
authorMikko Rasa <tdb@tdb.fi>
Mon, 1 Feb 2021 20:17:35 +0000 (22:17 +0200)
committerMikko Rasa <tdb@tdb.fi>
Mon, 1 Feb 2021 20:25:37 +0000 (22:25 +0200)
This is almost always the case anyway.  It makes things simpler as I don't
have to figure out what to do if someone tries to upload RGB data into a
LUMINANCE_ALPHA texture, which is really an RG texture in disguise.

There are some potential exceptions, like uploading FLOAT data to a
texture with HALF_FLOAT storage.  I'll write conversion routines if those
become relevant.

14 files changed:
source/ambientocclusion.cpp
source/colorcurve.cpp
source/texture.cpp
source/texture.h
source/texture1d.cpp
source/texture1d.h
source/texture2d.cpp
source/texture2d.h
source/texture2darray.cpp
source/texture2darray.h
source/texture3d.cpp
source/texture3d.h
source/texturecube.cpp
source/texturecube.h

index b1dccc0e4c632ea8dd55ad5390c7fea5135413d4..1cfdff09e8572b83f83442d834008b1724191610 100644 (file)
@@ -34,7 +34,7 @@ AmbientOcclusion::AmbientOcclusion(unsigned w, unsigned h, float):
                data[i*4+2] = 255-s;
                data[i*4+3] = ((i+i/4)%2)*255;
        }
-       rotate_lookup.image(0, RGBA, UNSIGNED_BYTE, data);
+       rotate_lookup.image(0, data);
 
        texturing.attach(3, rotate_lookup);
 
index 1f6f7bf9ec1f77df01f8db326b4bafa9c5e94ce8..78a7fc168f13439bcfbeb7f772e125cdd6519493 100644 (file)
@@ -50,7 +50,7 @@ void ColorCurve::set_gamma(float g)
        unsigned char curve_data[256];
        for(unsigned i=0; i<256; ++i)
                curve_data[i] = pow(i/255.0f, 1/g)*255+0.5f;
-       curve.image(0, LUMINANCE, UNSIGNED_BYTE, curve_data);
+       curve.image(0, curve_data);
 }
 
 void ColorCurve::set_srgb()
@@ -59,7 +59,7 @@ void ColorCurve::set_srgb()
        curve_data[0] = 0;
        for(unsigned i=1; i<256; ++i)
                curve_data[i] = to_srgb(i/255.0f)*255+0.5f;
-       curve.image(0, LUMINANCE, UNSIGNED_BYTE, curve_data);
+       curve.image(0, curve_data);
 }
 
 void ColorCurve::set_linear()
@@ -67,7 +67,7 @@ void ColorCurve::set_linear()
        unsigned char curve_data[256];
        for(unsigned i=0; i<256; ++i)
                curve_data[i] = i;
-       curve.image(0, LUMINANCE, UNSIGNED_BYTE, curve_data);
+       curve.image(0, curve_data);
 }
 
 void ColorCurve::render(Renderer &renderer, const Texture2D &color_buf, const Texture2D &)
index cf32ca301cab4bf10bc513ad65de9546c1b757e4..b747a2a6b0d7001b3d06e7a2811f91e93f075e78 100644 (file)
@@ -25,7 +25,8 @@ int Texture::swizzle_orders[] =
 Texture::Texture(GLenum t, ResourceManager *m):
        id(0),
        target(t),
-       ifmt(RGB8),
+       format(RGB8),
+       storage_fmt(RGB8),
        swizzle(NO_SWIZZLE),
        auto_gen_mipmap(false),
        default_sampler(*this)
@@ -47,45 +48,40 @@ Texture::~Texture()
                glDeleteTextures(1, &id);
 }
 
-void Texture::set_internal_format(PixelFormat fmt)
+void Texture::set_format(PixelFormat fmt)
 {
        PixelComponents comp = get_components(fmt);
+       PixelComponents st_comp = comp;
        FormatSwizzle swiz = NO_SWIZZLE;
        switch(comp)
        {
        case LUMINANCE:
-               comp = RED;
+               st_comp = RED;
                swiz = R_TO_LUMINANCE;
                break;
        case LUMINANCE_ALPHA:
-               comp = RG;
+               st_comp = RG;
                swiz = RG_TO_LUMINANCE_ALPHA;
                break;
        case BGR:
-               comp = RGB;
+               st_comp = RGB;
                swiz = RGB_TO_BGR;
                break;
        case BGRA:
-               comp = RGBA;
+               st_comp = RGBA;
                swiz = RGB_TO_BGR;
                break;
        default:;
        }
 
-       fmt = make_pixelformat(comp, get_component_type(fmt));
-       require_pixelformat(fmt);
+       PixelFormat st_fmt = make_pixelformat(st_comp, get_component_type(fmt));
+       require_pixelformat(st_fmt);
        if(swiz!=NO_SWIZZLE)
                static Require _req(ARB_texture_swizzle);
-       ifmt = fmt;
-       swizzle = swiz;
-}
 
-PixelComponents Texture::get_upload_components(PixelComponents comp) const
-{
-       if(comp==LUMINANCE || comp==LUMINANCE_ALPHA || comp==BGR || comp==BGRA)
-               return get_components(ifmt);
-       else
-               return comp;
+       format = fmt;
+       storage_fmt = st_fmt;
+       swizzle = swiz;
 }
 
 void Texture::apply_swizzle()
index 6c0fbf2574b6cb6f8a897e62f0977b8db9486e4f..30c6496a5658525e00a6ac59374996c25f08d7e3 100644 (file)
@@ -70,7 +70,8 @@ protected:
 
        unsigned id;
        GLenum target;
-       PixelFormat ifmt;
+       PixelFormat format;
+       PixelFormat storage_fmt;
        FormatSwizzle swizzle;
        bool auto_gen_mipmap;
        Sampler default_sampler;
@@ -84,8 +85,7 @@ public:
        ~Texture();
 
 protected:
-       void set_internal_format(PixelFormat);
-       PixelComponents get_upload_components(PixelComponents) const;
+       void set_format(PixelFormat);
        void apply_swizzle();
        void set_parameter_i(GLenum, int) const;
 
index 24266150672a90fab1f1a5acd4fd8cb4d16f849a..553d4ffa8ab265f26f7d685b2c510a51bbb52286 100644 (file)
@@ -26,7 +26,7 @@ void Texture1D::storage(PixelFormat fmt, unsigned wd, unsigned lv)
        if(wd==0)
                throw invalid_argument("Texture1D::storage");
 
-       set_internal_format(fmt);
+       set_format(fmt);
        width = wd;
        levels = get_n_levels();
        if(lv)
@@ -46,17 +46,17 @@ void Texture1D::allocate(unsigned level)
        {
                Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
                if(ARB_direct_state_access)
-                       glTextureStorage1D(id, levels, ifmt, width);
+                       glTextureStorage1D(id, levels, storage_fmt, width);
                else
-                       glTexStorage1D(target, levels, ifmt, width);
+                       glTexStorage1D(target, levels, storage_fmt, width);
                apply_swizzle();
                allocated |= (1<<levels)-1;
        }
        else
-               image(level, get_components(ifmt), get_component_type(ifmt), 0);
+               image(level, 0);
 }
 
-void Texture1D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
+void Texture1D::image(unsigned level, const void *data)
 {
        if(width==0)
                throw invalid_operation("Texture1D::image");
@@ -64,7 +64,7 @@ void Texture1D::image(unsigned level, PixelComponents comp, DataType type, const
        unsigned w = get_level_size(level);
 
        if(ARB_texture_storage)
-               return sub_image(level, 0, w, comp, type, data);
+               return sub_image(level, 0, w, data);
 
        BindRestore _bind(this);
 
@@ -73,7 +73,10 @@ void Texture1D::image(unsigned level, PixelComponents comp, DataType type, const
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
                apply_swizzle();
        }
-       glTexImage1D(target, level, ifmt, w, 0, get_upload_components(comp), type, data);
+
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
+       glTexImage1D(target, level, storage_fmt, w, 0, comp, type, data);
 
        allocated |= 1<<level;
        if(auto_gen_mipmap && level==0)
@@ -83,7 +86,14 @@ void Texture1D::image(unsigned level, PixelComponents comp, DataType type, const
        }
 }
 
-void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelComponents comp, DataType type, const void *data)
+void Texture1D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("Texture1D::image");
+       image(level, data);
+}
+
+void Texture1D::sub_image(unsigned level, int x, unsigned wd, const void *data)
 {
        if(width==0)
                throw invalid_operation("Texture3D::image");
@@ -91,7 +101,8 @@ void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelComponents co
        Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
        allocate(level);
 
-       comp = get_upload_components(comp);
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
        if(ARB_direct_state_access)
                glTextureSubImage1D(id, level, x, wd, comp, type, data);
        else
@@ -101,6 +112,13 @@ void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelComponents co
                generate_mipmap();
 }
 
+void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("Texture1D::sub_image");
+       sub_image(level, x, wd, data);
+}
+
 void Texture1D::image(const Graphics::Image &img, unsigned lv, bool srgb)
 {
        if(img.get_height()!=1)
@@ -108,14 +126,12 @@ void Texture1D::image(const Graphics::Image &img, unsigned lv, bool srgb)
 
        unsigned w = img.get_width();
        PixelFormat fmt = pixelformat_from_image(img);
-       PixelComponents comp = get_components(fmt);
-       DataType type = get_component_type(fmt);
        if(width==0)
-               storage(make_pixelformat(comp, type, srgb), w, lv);
+               storage(make_pixelformat(get_components(fmt), get_component_type(fmt), srgb), w, lv);
        else if(w!=width)
                throw incompatible_data("Texture1D::image");
 
-       image(0, comp, type, img.get_data());
+       image(0, img.get_data());
 }
 
 unsigned Texture1D::get_n_levels() const
@@ -132,7 +148,7 @@ unsigned Texture1D::get_level_size(unsigned level) const
 
 UInt64 Texture1D::get_data_size() const
 {
-       return id ? width*get_pixel_size(ifmt) : 0;
+       return id ? width*get_pixel_size(storage_fmt) : 0;
 }
 
 
@@ -157,7 +173,7 @@ void Texture1D::Loader::init()
 
 void Texture1D::Loader::raw_data(const string &data)
 {
-       obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
+       obj.image(0, data.data());
 }
 
 void Texture1D::Loader::storage(PixelFormat fmt, unsigned w)
index b0a9c681e2c4917d05d3a108289d9515a308515b..2b2a6b19cceec1236ee2d416d99bf08762328887 100644 (file)
@@ -36,8 +36,10 @@ public:
        { storage(make_pixelformat(c, UNSIGNED_BYTE), w, l); }
 
        void allocate(unsigned);
-       void image(unsigned, PixelComponents, DataType, const void *);
-       void sub_image(unsigned, int, unsigned, PixelComponents, DataType, const void *);
+       void image(unsigned, const void *);
+       DEPRECATED void image(unsigned, PixelComponents, DataType, const void *);
+       void sub_image(unsigned, int, unsigned, const void *);
+       DEPRECATED 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; }
index 8846a555d6437f6554c46e316a6f40be0b1c9728..fa92f1c97e52b3c980485827280def8e1c0057c2 100644 (file)
@@ -53,7 +53,7 @@ void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned lv)
        if(wd==0 || ht==0)
                throw invalid_argument("Texture2D::storage");
 
-       set_internal_format(fmt);
+       set_format(fmt);
        width = wd;
        height = ht;
        levels = get_n_levels();
@@ -74,17 +74,17 @@ void Texture2D::allocate(unsigned level)
        {
                Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
                if(ARB_direct_state_access)
-                       glTextureStorage2D(id, levels, ifmt, width, height);
+                       glTextureStorage2D(id, levels, storage_fmt, width, height);
                else
-                       glTexStorage2D(target, levels, ifmt, width, height);
+                       glTexStorage2D(target, levels, storage_fmt, width, height);
                apply_swizzle();
                allocated |= (1<<levels)-1;
        }
        else
-               image(level, get_components(ifmt), get_component_type(ifmt), 0);
+               image(level, 0);
 }
 
-void Texture2D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
+void Texture2D::image(unsigned level, const void *data)
 {
        if(width==0 || height==0)
                throw invalid_operation("Texture2D::image");
@@ -94,7 +94,7 @@ void Texture2D::image(unsigned level, PixelComponents comp, DataType type, const
        get_level_size(level, w, h);
 
        if(ARB_texture_storage)
-               return sub_image(level, 0, 0, w, h, comp, type, data);
+               return sub_image(level, 0, 0, w, h, data);
 
        BindRestore _bind(this);
 
@@ -103,7 +103,10 @@ void Texture2D::image(unsigned level, PixelComponents comp, DataType type, const
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
                apply_swizzle();
        }
-       glTexImage2D(target, level, ifmt, w, h, 0, get_upload_components(comp), type, data);
+
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
+       glTexImage2D(target, level, storage_fmt, w, h, 0, comp, type, data);
 
        allocated |= 1<<level;
        if(auto_gen_mipmap && level==0)
@@ -113,7 +116,14 @@ void Texture2D::image(unsigned level, PixelComponents comp, DataType type, const
        }
 }
 
-void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelComponents comp, DataType type, const void *data)
+void Texture2D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("Texture2D::image");
+       image(level, data);
+}
+
+void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data)
 {
        if(width==0 || height==0)
                throw invalid_operation("Texture2D::sub_image");
@@ -121,7 +131,8 @@ void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht
        Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
        allocate(level);
 
-       comp = get_upload_components(comp);
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
        if(ARB_direct_state_access)
                glTextureSubImage2D(id, level, x, y, wd, ht, comp, type, data);
        else
@@ -131,6 +142,13 @@ void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht
                generate_mipmap();
 }
 
+void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("Texture2D::sub_image");
+       sub_image(level, x, y, wd, ht, data);
+}
+
 void Texture2D::image(const Graphics::Image &img, unsigned lv, bool srgb)
 {
        image(img, lv, srgb, false);
@@ -141,17 +159,15 @@ 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_image(img);
-       PixelComponents comp = get_components(fmt);
-       DataType type = get_component_type(fmt);
        if(width==0)
-               storage(make_pixelformat(comp, type, srgb), w, h, lv);
+               storage(make_pixelformat(get_components(fmt), get_component_type(fmt), 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, comp, type, from_buffer ? 0 : img.get_data());
+       image(0, from_buffer ? 0 : img.get_data());
 }
 
 unsigned Texture2D::get_n_levels() const
@@ -182,7 +198,7 @@ Resource::AsyncLoader *Texture2D::load(IO::Seekable &io, const Resources *res)
 
 UInt64 Texture2D::get_data_size() const
 {
-       return id ? width*height*get_pixel_size(ifmt) : 0;
+       return id ? width*height*get_pixel_size(format) : 0;
 }
 
 void Texture2D::unload()
@@ -215,7 +231,7 @@ void Texture2D::Loader::init()
 
 void Texture2D::Loader::raw_data(const string &data)
 {
-       obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
+       obj.image(0, data.data());
 }
 
 void Texture2D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h)
index 801d18dd339524c15b945544d8e895aacd024d94..b7070e8f78093c1e4543b65feb4fafab0720888d 100644 (file)
@@ -55,20 +55,24 @@ public:
        undefined.  If storage has already been allocated, does nothing. */
        void allocate(unsigned level);
 
-       /** 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, PixelComponents fmt, DataType type, const void *data);
+       /** Updates the contents of the entire texture.  Storage must be defined
+       beforehand.  The image data must have dimensions and format matching the
+       defined storage. */
+       virtual void image(unsigned level, const void *data);
+
+       DEPRECATED 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,
+       beforehand.  The image data must be in a format mathing the defined storage
+       and the update region must be fully inside the texture. */
+       void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data);
+
+       DEPRECATED void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht,
                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
-       the defined storage.
+       /** Updates the contents of the entire texture from an image.  If storage
+       has not been defined, it will be set to match the image.  Otherwise the
+       image must match the defined storage.
 
        If srgb is true and storage is determined by this call, then an sRGB pixel
        format will be used. */
index 34b9532d3e80965dbc6777a2ff4d0e60a191d8ab..c080481b106590f5a6a159be78ad1618142cf85f 100644 (file)
@@ -15,14 +15,21 @@ Texture2DArray::Texture2DArray():
        static Require _req(EXT_texture_array);
 }
 
-void Texture2DArray::layer_image(unsigned level, unsigned z, PixelComponents comp, DataType type, const void *data)
+void Texture2DArray::layer_image(unsigned level, unsigned z, 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, comp, type, data);
+       sub_image(level, 0, 0, z, w, h, 1, data);
+}
+
+void Texture2DArray::layer_image(unsigned level, unsigned z, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("Texture2DArray::layer_image");
+       layer_image(level, z, data);
 }
 
 void Texture2DArray::layer_image(unsigned level, unsigned z, const Graphics::Image &img)
@@ -32,14 +39,16 @@ 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_image(img);
        if(w!=get_width() || h!=get_height())
                throw incompatible_data("Texture2DArray::layer_image");
+       PixelFormat fmt = pixelformat_from_image(img);
+       if(get_components(fmt)!=get_components(format) || get_component_type(fmt)!=get_component_type(format))
+               throw incompatible_data("Texture2DArray::layer_image");
 
        PixelStore pstore = PixelStore::from_image(img);
        BindRestore _bind_ps(pstore);
 
-       layer_image(level, z, get_components(fmt), get_component_type(fmt), img.get_data());
+       layer_image(level, z, img.get_data());
 }
 
 
index 6aa4886c1584f966eda461a5f0290b9a8dcec83a..bd7d03be9e8b3818b9c3c6d9435a438320f64a63 100644 (file)
@@ -27,7 +27,8 @@ public:
 
        Texture2DArray();
 
-       void layer_image(unsigned, unsigned, PixelComponents, DataType, const void *);
+       void layer_image(unsigned, unsigned, const void *);
+       DEPRECATED void layer_image(unsigned, unsigned, PixelComponents, DataType, const void *);
        void layer_image(unsigned, unsigned, const Graphics::Image &);
 
        unsigned get_layers() const { return get_depth(); }
index 010609a8e7a098c092524366990a9057efba1986..13bb3ff41a4ce99164a7443406a3eb3f4ac0bf50 100644 (file)
@@ -40,7 +40,7 @@ void Texture3D::storage(PixelFormat fmt, unsigned wd, unsigned ht, unsigned dp,
        if(wd==0 || ht==0 || dp==0)
                throw invalid_argument("Texture3D::storage");
 
-       set_internal_format(fmt);
+       set_format(fmt);
        width = wd;
        height = ht;
        depth = dp;
@@ -62,17 +62,17 @@ void Texture3D::allocate(unsigned level)
        {
                Conditional<BindRestore> _bind(!ARB_direct_state_access, this);
                if(ARB_direct_state_access)
-                       glTextureStorage3D(id, levels, ifmt, width, height, depth);
+                       glTextureStorage3D(id, levels, storage_fmt, width, height, depth);
                else
-                       glTexStorage3D(target, levels, ifmt, width, height, depth);
+                       glTexStorage3D(target, levels, storage_fmt, width, height, depth);
                apply_swizzle();
                allocated |= (1<<levels)-1;
        }
        else
-               image(level, get_components(ifmt), get_component_type(ifmt), 0);
+               image(level, 0);
 }
 
-void Texture3D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
+void Texture3D::image(unsigned level, const void *data)
 {
        if(width==0 || height==0 || depth==0)
                throw invalid_operation("Texture3D::image");
@@ -83,7 +83,7 @@ void Texture3D::image(unsigned level, PixelComponents comp, DataType type, const
        get_level_size(level, w, h, d);
 
        if(ARB_texture_storage)
-               return sub_image(level, 0, 0, 0, w, h, d, comp, type, data);
+               return sub_image(level, 0, 0, 0, w, h, d, data);
 
        BindRestore _bind(this);
 
@@ -92,7 +92,10 @@ void Texture3D::image(unsigned level, PixelComponents comp, DataType type, const
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
                apply_swizzle();
        }
-       glTexImage3D(target, level, ifmt, width, height, depth, 0, get_upload_components(comp), type, data);
+
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
+       glTexImage3D(target, level, storage_fmt, width, height, depth, 0, comp, type, data);
 
        allocated |= 1<<level;
        if(auto_gen_mipmap && level==0)
@@ -102,7 +105,14 @@ void Texture3D::image(unsigned level, PixelComponents comp, DataType type, const
        }
 }
 
-void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, PixelComponents comp, DataType type, const void *data)
+void Texture3D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("Texture3D::image");
+       image(level, data);
+}
+
+void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, const void *data)
 {
        if(width==0 || height==0 || depth==0)
                throw invalid_operation("Texture3D::image");
@@ -110,7 +120,8 @@ 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);
 
-       comp = get_upload_components(comp);
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
        if(ARB_direct_state_access)
                glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, comp, type, data);
        else
@@ -120,6 +131,13 @@ void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsi
                generate_mipmap();
 }
 
+void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("Texture3D::sub_image");
+       sub_image(level, x, y, z, wd, ht, dp, data);
+}
+
 void Texture3D::image(const Graphics::Image &img, unsigned lv, bool srgb)
 {
        unsigned w = img.get_width();
@@ -142,17 +160,15 @@ void Texture3D::image(const Graphics::Image &img, unsigned lv, bool srgb)
        }
 
        PixelFormat fmt = pixelformat_from_image(img);
-       PixelComponents comp = get_components(fmt);
-       DataType type = get_component_type(fmt);
        if(width==0)
-               storage(make_pixelformat(comp, type, srgb), w, h, d, lv);
+               storage(make_pixelformat(get_components(fmt), get_component_type(fmt), 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, comp, type, img.get_data());
+       image(0, img.get_data());
 }
 
 unsigned Texture3D::get_n_levels() const
@@ -182,7 +198,7 @@ void Texture3D::get_level_size(unsigned level, unsigned &w, unsigned &h, unsigne
 
 UInt64 Texture3D::get_data_size() const
 {
-       return id ? width*height*depth*get_pixel_size(ifmt) : 0;
+       return id ? width*height*depth*get_pixel_size(storage_fmt) : 0;
 }
 
 
@@ -207,7 +223,7 @@ void Texture3D::Loader::init()
 
 void Texture3D::Loader::raw_data(const string &data)
 {
-       obj.image(0, get_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
+       obj.image(0, data.data());
 }
 
 void Texture3D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h, unsigned d)
index ecdff9d6c90549ae7e958e815e67e8493a4b050c..d67d03be62a1c413dd913e73e3092d1b682f7f29 100644 (file)
@@ -53,22 +53,26 @@ public:
        undefined.  If storage has already been allocated, does nothing. */
        void allocate(unsigned level);
 
-       /** 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, PixelComponents, DataType type, const void *data);
+       /** Updates the contents of the entire texture.  Storage must be defined
+       beforehand.  The image data must have dimensions and format matching the
+       defined storage. */
+       void image(unsigned level, const void *data);
+
+       DEPRECATED void image(unsigned level, PixelComponents comp, 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,
+       beforehand.  The image data must be in a format mathing the defined storage
+       and 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, const void *data);
+
+       DEPRECATED void sub_image(unsigned level,
                int x, int y, int z, unsigned wd, unsigned ht, unsigned dp,
                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
-       a stack of square layers and its height must be divisible by its width.
-       Otherwise the image must be compatible with the defined storage.
+       /** Updates the contents of the entire texture from an image.  If storage
+       has not been defined, it will be set to match the image.  In this case the
+       image will be treated as a stack of square layers and its height must be
+       divisible by its width.  Otherwise the image must match the defined storage.
 
        If srgb is true and storage is determined by this call, then an sRGB pixel
        format will be used. */
index b0887ca85b1e4fca0e88769da87e4621f0d3af54..824ff2cc14d29743bf3e8adadd4709936a5f712d 100644 (file)
@@ -58,7 +58,7 @@ void TextureCube::storage(PixelFormat fmt, unsigned sz, unsigned lv)
        if(sz==0)
                throw invalid_argument("TextureCube::storage");
 
-       set_internal_format(fmt);
+       set_format(fmt);
        size = sz;
        levels = get_n_levels();
        if(lv>0)
@@ -77,20 +77,18 @@ void TextureCube::allocate(unsigned level)
        if(ARB_texture_storage)
        {
                BindRestore _bind(this);
-               glTexStorage2D(target, levels, ifmt, size, size);
+               glTexStorage2D(target, levels, storage_fmt, size, size);
                apply_swizzle();
                allocated |= (1<<levels)-1;
        }
        else
        {
-               PixelComponents comp = get_components(ifmt);
-               DataType type = get_component_type(ifmt);
                for(unsigned i=0; i<6; ++i)
-                       image(enumerate_faces(i), level, comp, type, 0);
+                       image(enumerate_faces(i), level, 0);
        }
 }
 
-void TextureCube::image(TextureCubeFace face, unsigned level, PixelComponents comp, DataType type, const void *data)
+void TextureCube::image(TextureCubeFace face, unsigned level, const void *data)
 {
        if(size==0)
                throw invalid_operation("TextureCube::image");
@@ -100,7 +98,7 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelComponents co
                throw out_of_range("TextureCube::image");
 
        if(ARB_texture_storage)
-               return sub_image(face, level, 0, 0, s, s, comp, type, data);
+               return sub_image(face, level, 0, 0, s, s, data);
 
        BindRestore _bind(this);
 
@@ -109,7 +107,10 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelComponents co
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
                apply_swizzle();
        }
-       glTexImage2D(face, level, ifmt, s, s, 0, get_upload_components(comp), type, data);
+
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
+       glTexImage2D(face, level, storage_fmt, s, s, 0, comp, type, data);
 
        if(level==0)
        {
@@ -128,13 +129,20 @@ void TextureCube::image(TextureCubeFace face, unsigned level, PixelComponents co
        {
                for(unsigned i=0; i<6; ++i)
                        if(enumerate_faces(i)!=face)
-                               glTexImage2D(enumerate_faces(i), level, ifmt, s, s, 0, comp, type, 0);
+                               glTexImage2D(enumerate_faces(i), level, storage_fmt, s, s, 0, comp, type, 0);
 
                allocated |= 64<<level;
        }
 }
 
-void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned wd, unsigned ht, PixelComponents comp, DataType type, const void *data)
+void TextureCube::image(TextureCubeFace face, unsigned level, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("TextureCube::image");
+       image(face, level, data);
+}
+
+void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned wd, unsigned ht, const void *data)
 {
        if(size==0)
                throw invalid_operation("TextureCube::sub_image");
@@ -142,12 +150,21 @@ void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y,
        BindRestore _bind(this);
        allocate(level);
 
-       glTexSubImage2D(face, level, x, y, wd, ht, get_upload_components(comp), type, data);
+       PixelComponents comp = get_components(storage_fmt);
+       DataType type = get_component_type(storage_fmt);
+       glTexSubImage2D(face, level, x, y, wd, ht, comp, type, data);
 
        if(auto_gen_mipmap && level==0)
                generate_mipmap();
 }
 
+void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned wd, unsigned ht, PixelComponents comp, DataType type, const void *data)
+{
+       if(comp!=get_components(format) || type!=get_component_type(format))
+               throw incompatible_data("TextureCube::subimage");
+       sub_image(face, level, x, y, wd, ht, data);
+}
+
 void TextureCube::image(TextureCubeFace face, const Graphics::Image &img, bool srgb)
 {
        unsigned w = img.get_width();
@@ -166,7 +183,7 @@ void TextureCube::image(TextureCubeFace face, const Graphics::Image &img, bool s
        PixelStore pstore = PixelStore::from_image(img);
        BindRestore _bind_ps(pstore);
 
-       image(face, 0, get_components(fmt), get_component_type(fmt), img.get_data());
+       image(face, 0, img.get_data());
 }
 
 void TextureCube::image(const Graphics::Image &img, unsigned lv, bool srgb)
@@ -179,10 +196,8 @@ void TextureCube::image(const Graphics::Image &img, unsigned lv, bool srgb)
        h /= 6;
 
        PixelFormat fmt = pixelformat_from_image(img);
-       PixelComponents comp = get_components(fmt);
-       DataType type = get_component_type(fmt);
        if(size==0)
-               storage(make_pixelformat(comp, type, srgb), w, lv);
+               storage(make_pixelformat(get_components(fmt), get_component_type(fmt), srgb), w, lv);
        else if(w!=size || h!=size)
                throw incompatible_data("TextureCube::image");
 
@@ -192,7 +207,7 @@ void TextureCube::image(const Graphics::Image &img, unsigned lv, bool srgb)
        const char *cdata = reinterpret_cast<const char *>(img.get_data());
        unsigned face_size = img.get_stride()*size;
        for(unsigned i=0; i<6; ++i)
-               image(enumerate_faces(i), 0, comp, type, cdata+i*face_size);
+               image(enumerate_faces(i), 0, cdata+i*face_size);
 }
 
 unsigned TextureCube::get_n_levels() const
@@ -255,7 +270,7 @@ Vector3 TextureCube::get_texel_direction(TextureCubeFace face, unsigned u, unsig
 
 UInt64 TextureCube::get_data_size() const
 {
-       return id ? size*size*6*get_pixel_size(ifmt) : 0;
+       return id ? size*size*6*get_pixel_size(storage_fmt) : 0;
 }
 
 
@@ -300,7 +315,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_components(obj.ifmt), get_component_type(obj.ifmt), data.data());
+       obj.image(face, 0, data.data());
 }
 
 void TextureCube::Loader::storage(PixelFormat fmt, unsigned s)
index f716098329cf09fc1a3a663c2de34501c5f25f16..8235620025aed86d0bc050733904590c0137a186 100644 (file)
@@ -77,16 +77,20 @@ public:
        undefined.  If storage has already been allocated, does nothing. */
        void allocate(unsigned level);
 
-       /** Uploads image data to a face.  Storage must be defined beforehand.  The
-       image data must have dimensions and format compatible with the defined
+       /** Updates the contents of a face.  Storage must be defined beforehand.
+       The image data must have dimensions and format matching the defined
        storage. */
-       void image(TextureCubeFace face, unsigned level,
+       void image(TextureCubeFace face, unsigned level, const void *data);
+
+       DEPRECATED void image(TextureCubeFace face, unsigned level,
                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,
+       /** Updates a rectangular region of a face.  Storage must be defined
+       beforehand.  The image data must be in a format mathing the defined storage
+       and the update region must be fully inside the face. */
+       void sub_image(TextureCubeFace face, unsigned level, int x, int y, unsigned w, unsigned h, const void *data);
+
+       DEPRECATED void sub_image(TextureCubeFace face, unsigned level,
                int x, int y, unsigned w, unsigned h,
                PixelComponents comp, DataType type, const void *data);