]> git.tdb.fi Git - libs/gl.git/commitdiff
Use a scratch binding to modify textures and buffers
authorMikko Rasa <tdb@tdb.fi>
Thu, 16 Sep 2021 18:52:22 +0000 (21:52 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 16 Sep 2021 22:06:54 +0000 (01:06 +0300)
This simplifies the code quite a bit.  It's assumed that textures are
not modified during rendering, as that would potentially interfere with
the rendering pipeline state.

15 files changed:
source/core/buffer.cpp
source/core/buffer.h
source/core/pipelinestate.cpp
source/core/texture.cpp
source/core/texture.h
source/core/texture1d.cpp
source/core/texture1d.h
source/core/texture2d.cpp
source/core/texture2d.h
source/core/texture2dmultisample.cpp
source/core/texture3d.cpp
source/core/texture3d.h
source/core/texturecube.cpp
source/core/texturecube.h
source/core/vertexsetup.cpp

index ecf7b49a15e35d29493c83f1a6ea2f8013065483..78e85af0456b721a27316d9622849f00a2b37c3e 100644 (file)
@@ -15,6 +15,8 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
+Buffer *Buffer::scratch_binding = 0;
+
 Buffer::Buffer():
        size(0),
        allocated(false)
@@ -29,6 +31,8 @@ Buffer::Buffer():
 
 Buffer::~Buffer()
 {
+       if(this==scratch_binding)
+               unbind_scratch();
        glDeleteBuffers(1, &id);
 }
 
@@ -60,9 +64,8 @@ void Buffer::allocate()
                        glNamedBufferStorage(id, size, 0, flags);
                else
                {
-                       glBindBuffer(GL_ARRAY_BUFFER, id);
+                       bind_scratch();
                        glBufferStorage(GL_ARRAY_BUFFER, size, 0, flags);
-                       glBindBuffer(GL_ARRAY_BUFFER, 0);
                }
 
                allocated = true;
@@ -87,9 +90,8 @@ void Buffer::data(const void *d)
                glNamedBufferData(id, size, d, STATIC_DRAW);
        else
        {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
+               bind_scratch();
                glBufferData(GL_ARRAY_BUFFER, size, d, STATIC_DRAW);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
 
        allocated = true;
@@ -116,9 +118,8 @@ void Buffer::sub_data(unsigned off, unsigned sz, const void *d)
                glNamedBufferSubData(id, off, sz, d);
        else
        {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
+               bind_scratch();
                glBufferSubData(GL_ARRAY_BUFFER, off, sz, d);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
        }
 }
 
@@ -137,9 +138,8 @@ void *Buffer::map()
                return glMapNamedBufferRange(id, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
        else
        {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
+               bind_scratch();
                void *result = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
                return result;
        }
 }
@@ -151,9 +151,8 @@ bool Buffer::unmap()
                return glUnmapNamedBuffer(id);
        else if(OES_mapbuffer)
        {
-               glBindBuffer(GL_ARRAY_BUFFER, id);
+               bind_scratch();
                bool result = glUnmapBuffer(GL_ARRAY_BUFFER);
-               glBindBuffer(GL_ARRAY_BUFFER, 0);
                return result;
        }
        else
@@ -170,5 +169,23 @@ void Buffer::set_debug_name(const string &name)
 #endif
 }
 
+void Buffer::bind_scratch()
+{
+       if(scratch_binding!=this)
+       {
+               glBindBuffer(GL_ARRAY_BUFFER, id);
+               scratch_binding = this;
+       }
+}
+
+void Buffer::unbind_scratch()
+{
+       if(scratch_binding)
+       {
+               glBindBuffer(GL_ARRAY_BUFFER, 0);
+               scratch_binding = 0;
+       }
+}
+
 } // namespace GL
 } // namespace Msp
index a80e52a68b9c34b00e499c6a16fb0b9e85446d39..ca9a595555869668adbf9a56f910b305ee37bae9 100644 (file)
@@ -57,6 +57,8 @@ private:
        unsigned size;
        bool allocated;
 
+       static Buffer *scratch_binding;
+
 public:
        Buffer();
        ~Buffer();
@@ -96,6 +98,11 @@ public:
        bool unmap();
 
        void set_debug_name(const std::string &);
+
+private:
+       void bind_scratch();
+public:
+       static void unbind_scratch();
 };
 
 } // namespace GL
index 21cb64f9f51bb88c5f7ccd02b4a5f65fb4006daf..318522d6563b547eebcf6b823ed3e5ddbb9c0305 100644 (file)
@@ -162,6 +162,9 @@ void PipelineState::set_blend(const Blend *b)
 
 void PipelineState::apply() const
 {
+       if(!last_applied)
+               Texture::unbind_scratch();
+
        apply(this==last_applied ? changes : ~0U);
 }
 
index 347634d4c27fa204d169c6a731f39139165f3213..b40046705b32bdfbecd459b56ce5e9b7c81ae4d9 100644 (file)
@@ -21,6 +21,8 @@ int Texture::swizzle_orders[] =
        GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA
 };
 
+Texture *Texture::scratch_binding = 0;
+
 Texture::Texture(GLenum t, ResourceManager *m):
        id(0),
        target(t),
@@ -45,6 +47,8 @@ Texture::Texture(GLenum t, ResourceManager *m):
 
 Texture::~Texture()
 {
+       if(this==scratch_binding)
+               unbind_scratch();
        if(id)
                glDeleteTextures(1, &id);
 }
@@ -139,22 +143,13 @@ void Texture::generate_mipmap()
        // glGenerateMipmap is defined here
        static Require _req(EXT_framebuffer_object);
 
-       if(!ARB_direct_state_access)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-       generate_mipmap_();
-       if(!ARB_direct_state_access)
-               glBindTexture(target, 0);
-}
-
-void Texture::generate_mipmap_()
-{
        if(ARB_direct_state_access)
                glGenerateTextureMipmap(id);
        else
+       {
+               bind_scratch();
                glGenerateMipmap(target);
+       }
 }
 
 void Texture::set_auto_generate_mipmap(bool gm)
@@ -194,6 +189,28 @@ void Texture::set_debug_name(const string &name)
 #endif
 }
 
+void Texture::bind_scratch()
+{
+       if(!scratch_binding)
+               glActiveTexture(GL_TEXTURE0);
+       if(scratch_binding!=this)
+       {
+               if(scratch_binding && scratch_binding->target!=target)
+                       glBindTexture(scratch_binding->target, 0);
+               glBindTexture(target, id);
+               scratch_binding = this;
+       }
+}
+
+void Texture::unbind_scratch()
+{
+       if(scratch_binding)
+       {
+               glBindTexture(scratch_binding->target, 0);
+               scratch_binding = 0;
+       }
+}
+
 
 Texture::Loader::Loader(Texture &t):
        DataFile::CollectionObjectLoader<Texture>(t, 0)
index 3057ef36ed0ae57c84c133c836db12c35319e556..1631f69f248109a1a06764f9fd038b05841e685e 100644 (file)
@@ -67,6 +67,7 @@ protected:
        std::string debug_name;
 
        static int swizzle_orders[];
+       static Texture *scratch_binding;
 
        Texture(GLenum, ResourceManager * = 0);
        Texture(const Texture &);
@@ -86,10 +87,7 @@ public:
        static bool can_generate_mipmap();
 
        void generate_mipmap();
-protected:
-       void generate_mipmap_();
 
-public:
        /** Sets automatic mipmap generation.  If enabled, mipmaps are generated
        when a texture image is uploaded. */
        void set_auto_generate_mipmap(bool);
@@ -115,6 +113,11 @@ public:
        virtual UInt64 get_data_size() const { return 0; }
 
        void set_debug_name(const std::string &);
+
+protected:
+       void bind_scratch();
+public:
+       static void unbind_scratch();
 };
 
 } // namespace GL
index feff9f9883f3f1b39921193fd75eb4c4e5effde4..1dbe36eb293e6b02d6a01608b23fb546938eb71a 100644 (file)
@@ -42,22 +42,6 @@ void Texture1D::allocate(unsigned level)
                throw invalid_operation("Texture1D::allocate");
        if(level>=levels)
                throw invalid_argument("Texture1D::allocate");
-
-       bool direct = ARB_texture_storage && ARB_direct_state_access;
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
-
-       if(!direct)
-               glBindTexture(target, 0);
-}
-
-void Texture1D::allocate_(unsigned level)
-{
        if(allocated&(1<<level))
                return;
 
@@ -67,12 +51,15 @@ void Texture1D::allocate_(unsigned level)
                if(ARB_direct_state_access)
                        glTextureStorage1D(id, levels, fmt, width);
                else
+               {
+                       bind_scratch();
                        glTexStorage1D(target, levels, fmt, width);
+               }
                apply_swizzle();
                allocated |= (1<<levels)-1;
        }
        else
-               image_(level, 0);
+               image(level, 0);
 }
 
 void Texture1D::image(unsigned level, const void *data)
@@ -85,22 +72,8 @@ void Texture1D::image(unsigned level, const void *data)
        if(ARB_texture_storage)
                return sub_image(level, 0, get_level_size(level), data);
 
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture(target, id);
-
-       image_(level, data);
-
-       if(auto_gen_mipmap && level==0)
-       {
-               generate_mipmap_();
-               allocated |= (1<<levels)-1;
-       }
+       bind_scratch();
 
-       glBindTexture(target, 0);
-}
-
-void Texture1D::image_(unsigned level, const void *data)
-{
        if(!allocated)
        {
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
@@ -113,6 +86,11 @@ void Texture1D::image_(unsigned level, const void *data)
        glTexImage1D(target, level, fmt, get_level_size(level), 0, comp, type, data);
 
        allocated |= 1<<level;
+       if(auto_gen_mipmap && level==0)
+       {
+               generate_mipmap();
+               allocated |= (1<<levels)-1;
+       }
 }
 
 void Texture1D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
@@ -129,27 +107,20 @@ void Texture1D::sub_image(unsigned level, int x, unsigned wd, const void *data)
        if(level>=levels)
                throw out_of_range("Texture1D::sub_image");
 
-       bool direct = (ARB_direct_state_access && (ARB_texture_storage || (allocated&(1<<level))));
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
+       allocate(level);
 
        GLenum comp = get_gl_components(get_components(storage_fmt));
        GLenum type = get_gl_type(get_component_type(storage_fmt));
        if(ARB_direct_state_access)
                glTextureSubImage1D(id, level, x, wd, comp, type, data);
        else
+       {
+               bind_scratch();
                glTexSubImage1D(target, level, x, wd, comp, type, data);
+       }
 
        if(auto_gen_mipmap && level==0)
-               generate_mipmap_();
-
-       if(!direct)
-               glBindTexture(target, 0);
+               generate_mipmap();
 }
 
 void Texture1D::sub_image(unsigned level, int x, unsigned wd, PixelComponents comp, DataType type, const void *data)
index 09d805e7869f8afd2819596bab336a8db23389a8..b14ff917666f88cb02fc7fbbcd5c55a8330b0075 100644 (file)
@@ -36,13 +36,7 @@ public:
        { storage(make_pixelformat(c, UNSIGNED_BYTE), w, l); }
 
        void allocate(unsigned);
-private:
-       void allocate_(unsigned);
-public:
        void image(unsigned, const void *);
-private:
-       void image_(unsigned, const void *);
-public:
        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 *);
index 9ebc3cc5fc496e0e7afe057f12f26c7796637b10..ed0b206c1e05069ada3d8e677c84995b706e920b 100644 (file)
@@ -70,22 +70,6 @@ void Texture2D::allocate(unsigned level)
                throw invalid_operation("Texture2D::allocate");
        if(level>=levels)
                throw invalid_argument("Texture2D::allocate");
-
-       bool direct = ARB_texture_storage && ARB_direct_state_access;
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
-
-       if(!direct)
-               glBindTexture(target, 0);
-}
-
-void Texture2D::allocate_(unsigned level)
-{
        if(allocated&(1<<level))
                return;
 
@@ -95,12 +79,15 @@ void Texture2D::allocate_(unsigned level)
                if(ARB_direct_state_access)
                        glTextureStorage2D(id, levels, fmt, width, height);
                else
+               {
+                       bind_scratch();
                        glTexStorage2D(target, levels, fmt, width, height);
+               }
                apply_swizzle();
                allocated |= (1<<levels)-1;
        }
        else
-               image_(level, 0);
+               image(level, 0);
 }
 
 void Texture2D::image(unsigned level, const void *data)
@@ -110,41 +97,30 @@ void Texture2D::image(unsigned level, const void *data)
        if(level>=levels)
                throw out_of_range("Texture2D::image");
 
+       LinAl::Vector<unsigned, 2> size = get_level_size(level);
+
        if(ARB_texture_storage)
-       {
-               LinAl::Vector<unsigned, 2> size = get_level_size(level);
                return sub_image(level, 0, 0, size.x, size.y, data);
-       }
-
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture(target, id);
-
-       image_(level, data);
-
-       if(auto_gen_mipmap && level==0)
-       {
-               generate_mipmap_();
-               allocated |= (1<<levels)-1;
-       }
 
-       glBindTexture(target, 0);
-}
+       bind_scratch();
 
-void Texture2D::image_(unsigned level, const void *data)
-{
        if(!allocated)
        {
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
                apply_swizzle();
        }
 
-       LinAl::Vector<unsigned, 2> size = get_level_size(level);
        GLenum fmt = get_gl_pixelformat(storage_fmt);
        GLenum comp = get_gl_components(get_components(storage_fmt));
        GLenum type = get_gl_type(get_component_type(storage_fmt));
        glTexImage2D(target, level, fmt, size.x, size.y, 0, comp, type, data);
 
        allocated |= 1<<level;
+       if(auto_gen_mipmap && level==0)
+       {
+               generate_mipmap();
+               allocated |= (1<<levels)-1;
+       }
 }
 
 void Texture2D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
@@ -161,27 +137,20 @@ void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht
        if(level>=levels)
                throw out_of_range("Texture2D::sub_image");
 
-       bool direct = (ARB_direct_state_access && (ARB_texture_storage || (allocated&(1<<level))));
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
+       allocate(level);
 
        GLenum comp = get_gl_components(get_components(storage_fmt));
        GLenum type = get_gl_type(get_component_type(storage_fmt));
        if(ARB_direct_state_access)
                glTextureSubImage2D(id, level, x, y, wd, ht, comp, type, data);
        else
+       {
+               bind_scratch();
                glTexSubImage2D(target, level, x, y, wd, ht, comp, type, data);
+       }
 
        if(auto_gen_mipmap && level==0)
-               generate_mipmap_();
-
-       if(!direct)
-               glBindTexture(target, 0);
+               generate_mipmap();
 }
 
 void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelComponents comp, DataType type, const void *data)
index 8f5c9b21df7df778559e2f52e40bf10bd841144a..877555c0f5ba43d4cdefb5a78af34225cc2e4756 100644 (file)
@@ -56,19 +56,11 @@ public:
        undefined.  If storage has already been allocated, does nothing. */
        void allocate(unsigned level);
 
-private:
-       void allocate_(unsigned level);
-
-public:
        /** 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);
 
-private:
-       void image_(unsigned level, const void *data);
-
-public:
        DEPRECATED void image(unsigned level, PixelComponents fmt, DataType type, const void *data);
 
        /** Updates a rectangular region of the texture.  Storage must be defined
index 18e21b76ba45eeeaaf585504104aa8558335daa3..4fdb7c1d9ed17bc721942644f58592fdb49bc47c 100644 (file)
@@ -36,27 +36,23 @@ void Texture2DMultisample::storage(PixelFormat fmt, unsigned wd, unsigned ht, un
        height = ht;
        samples = sm;
 
-       bool direct = ARB_texture_storage_multisample && ARB_direct_state_access;
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
        GLenum gl_fmt = get_gl_pixelformat(storage_fmt);
        if(ARB_texture_storage_multisample)
        {
                if(ARB_direct_state_access)
                        glTextureStorage2DMultisample(id, samples, gl_fmt, width, height, false);
                else
+               {
+                       bind_scratch();
                        glTexStorage2DMultisample(target, samples, gl_fmt, width, height, false);
+               }
        }
        else
+       {
+               bind_scratch();
                glTexImage2DMultisample(target, samples, gl_fmt, width, height, false);
+       }
        apply_swizzle();
-
-       if(!direct)
-               glBindTexture(target, 0);
 }
 
 void Texture2DMultisample::image(const Graphics::Image &, unsigned)
index bdb87882e878333c23e88373bc85b57d277c7e74..705a40ba5574cc950078d119e9061a90e6bd9272 100644 (file)
@@ -57,22 +57,6 @@ void Texture3D::allocate(unsigned level)
                throw invalid_operation("Texture3D::allocate");
        if(level>=levels)
                throw invalid_argument("Texture3D::allocate");
-
-       bool direct = ARB_texture_storage && ARB_direct_state_access;
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
-
-       if(!direct)
-               glBindTexture(target, 0);
-}
-
-void Texture3D::allocate_(unsigned level)
-{
        if(allocated&(1<<level))
                return;
 
@@ -82,12 +66,15 @@ void Texture3D::allocate_(unsigned level)
                if(ARB_direct_state_access)
                        glTextureStorage3D(id, levels, fmt, width, height, depth);
                else
+               {
+                       bind_scratch();
                        glTexStorage3D(target, levels, fmt, width, height, depth);
+               }
                apply_swizzle();
                allocated |= (1<<levels)-1;
        }
        else
-               image_(level, 0);
+               image(level, 0);
 }
 
 void Texture3D::image(unsigned level, const void *data)
@@ -97,41 +84,30 @@ void Texture3D::image(unsigned level, const void *data)
        if(level>=levels)
                throw out_of_range("Texture3D::image");
 
+       LinAl::Vector<unsigned, 3> size = get_level_size(level);
+
        if(ARB_texture_storage)
-       {
-               LinAl::Vector<unsigned, 3> size = get_level_size(level);
                return sub_image(level, 0, 0, 0, size.x, size.y, size.z, data);
-       }
-
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture(target, id);
-
-       image_(level, data);
-
-       if(auto_gen_mipmap && level==0)
-       {
-               generate_mipmap_();
-               allocated |= (1<<levels)-1;
-       }
 
-       glBindTexture(target, 0);
-}
+       bind_scratch();
 
-void Texture3D::image_(unsigned level, const void *data)
-{
        if(!allocated)
        {
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
                apply_swizzle();
        }
 
-       LinAl::Vector<unsigned, 3> size = get_level_size(level);
        GLenum fmt = get_gl_pixelformat(storage_fmt);
        GLenum comp = get_gl_components(get_components(storage_fmt));
        GLenum type = get_gl_type(get_component_type(storage_fmt));
        glTexImage3D(target, level, fmt, size.x, size.y, size.z, 0, comp, type, data);
 
        allocated |= 1<<level;
+       if(auto_gen_mipmap && level==0)
+       {
+               generate_mipmap();
+               allocated |= (1<<levels)-1;
+       }
 }
 
 void Texture3D::image(unsigned level, PixelComponents comp, DataType type, const void *data)
@@ -148,27 +124,20 @@ void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsi
        if(level>=levels)
                throw out_of_range("Texture3D::sub_image");
 
-       bool direct = (ARB_direct_state_access && (ARB_texture_storage || (allocated&(1<<level))));
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
+       allocate(level);
 
        GLenum comp = get_gl_components(get_components(storage_fmt));
        GLenum type = get_gl_type(get_component_type(storage_fmt));
        if(ARB_direct_state_access)
                glTextureSubImage3D(id, level, x, y, z, wd, ht, dp, comp, type, data);
        else
+       {
+               bind_scratch();
                glTexSubImage3D(target, level, x, y, z, wd, ht, dp, comp, type, data);
+       }
 
        if(auto_gen_mipmap && level==0)
-               generate_mipmap_();
-
-       if(!direct)
-               glBindTexture(target, 0);
+               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)
index 2a8f653cd04422c333a1dcb81e937978dee38fda..df52bf66ee8daeb1e1a879440c63ed52ab799833 100644 (file)
@@ -53,19 +53,11 @@ public:
        undefined.  If storage has already been allocated, does nothing. */
        void allocate(unsigned level);
 
-private:
-       void allocate_(unsigned);
-
-public:
        /** 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);
 
-private:
-       void image_(unsigned, const void *);
-
-public:
        DEPRECATED void image(unsigned level, PixelComponents comp, DataType type, const void *data);
 
        /** Updates a cuboid-shaped region of the texture.  Storage must be defined
index 2db1b63b92162c358618c7c3d7a6a0831ce3cb5e..a2c6c8eb62725c21ce21553cf30926b01fe127e8 100644 (file)
@@ -77,22 +77,6 @@ void TextureCube::allocate(unsigned level)
                throw invalid_operation("TextureCube::allocate");
        if(level>=levels)
                throw invalid_argument("TextureCube::allocate");
-
-       bool direct = ARB_texture_storage && ARB_direct_state_access;
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
-
-       if(!direct)
-               glBindTexture(target, 0);
-}
-
-void TextureCube::allocate_(unsigned level)
-{
        if(allocated&(64<<level))
                return;
 
@@ -102,14 +86,17 @@ void TextureCube::allocate_(unsigned level)
                if(ARB_direct_state_access)
                        glTextureStorage2D(id, levels, fmt, size, size);
                else
+               {
+                       bind_scratch();
                        glTexStorage2D(target, levels, fmt, size, size);
+               }
                apply_swizzle();
                allocated |= (64<<levels)-1;
        }
        else
        {
                for(unsigned i=0; i<6; ++i)
-                       image_(enumerate_faces(i), level, 0);
+                       image(enumerate_faces(i), level, 0);
        }
 }
 
@@ -120,35 +107,17 @@ void TextureCube::image(TextureCubeFace face, unsigned level, const void *data)
        if(level>=levels)
                throw out_of_range("TextureCube::image");
 
+       unsigned lsz = get_level_size(level);
+
        if(ARB_texture_storage)
-       {
-               unsigned lsz = get_level_size(level);
                return sub_image(face, level, 0, 0, lsz, lsz, data);
-       }
-
-       glActiveTexture(GL_TEXTURE0);
-       glBindTexture(target, id);
-
-       image_(face, level, data);
 
-       if(auto_gen_mipmap && level==0 && (allocated&63)==63)
-       {
-               generate_mipmap_();
-               allocated |= (64<<levels)-1;
-       }
-
-       glBindTexture(target, 0);
-}
-
-void TextureCube::image_(TextureCubeFace face, unsigned level, const void *data)
-{
        if(!allocated)
        {
                glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, levels-1);
                apply_swizzle();
        }
 
-       unsigned lsz = get_level_size(level);
        GLenum fmt = get_gl_pixelformat(storage_fmt);
        GLenum comp = get_gl_components(get_components(storage_fmt));
        GLenum type = get_gl_type(get_component_type(storage_fmt));
@@ -158,7 +127,14 @@ void TextureCube::image_(TextureCubeFace face, unsigned level, const void *data)
        {
                allocated |= 1<<get_face_index(face);
                if((allocated&63)==63)
+               {
                        allocated |= 64;
+                       if(auto_gen_mipmap && level==0 && (allocated&63)==63)
+                       {
+                               generate_mipmap();
+                               allocated |= (64<<levels)-1;
+                       }
+               }
        }
        else if(!(allocated&(64<<level)))
        {
@@ -184,27 +160,20 @@ void TextureCube::sub_image(TextureCubeFace face, unsigned level, int x, int y,
        if(level>=levels)
                throw out_of_range("TextureCube::sub_image");
 
-       bool direct = (ARB_direct_state_access && (ARB_texture_storage || (allocated&(1<<level))));
-       if(!direct)
-       {
-               glActiveTexture(GL_TEXTURE0);
-               glBindTexture(target, id);
-       }
-
-       allocate_(level);
+       allocate(level);
 
        GLenum comp = get_gl_components(get_components(storage_fmt));
        GLenum type = get_gl_type(get_component_type(storage_fmt));
        if(ARB_direct_state_access)
                glTextureSubImage3D(id, level, x, y, get_face_index(face), wd, ht, 1, comp, type, data);
        else
+       {
+               bind_scratch();
                glTexSubImage2D(face, level, x, y, wd, ht, comp, type, data);
+       }
 
        if(auto_gen_mipmap && level==0)
-               generate_mipmap_();
-
-       if(!direct)
-               glBindTexture(target, 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)
index 39fe0c699b4b6358fa9efe6c7348504450690742..ae305153fec6860a8f37e3128f037214f07d5e25 100644 (file)
@@ -77,19 +77,11 @@ public:
        undefined.  If storage has already been allocated, does nothing. */
        void allocate(unsigned level);
 
-private:
-       void allocate_(unsigned);
-
-public:
        /** 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, const void *data);
 
-private:
-       void image_(TextureCubeFace, unsigned, const void *);
-
-public:
        DEPRECATED void image(TextureCubeFace face, unsigned level,
                PixelComponents comp, DataType type, const void *data);
 
index 81d2261e6aa78b55b3240e231ea72b25232bea60..7a24da7350b5f332a1e2aaaaa5c80a29fc7646e8 100644 (file)
@@ -148,7 +148,10 @@ void VertexSetup::update() const
 void VertexSetup::update_vertex_array(const VertexArray &array, unsigned binding, unsigned divisor, bool direct) const
 {
        if(!direct)
+       {
+               Buffer::unbind_scratch();
                glBindBuffer(GL_ARRAY_BUFFER, array.get_buffer()->get_id());
+       }
 
        const VertexFormat &fmt = array.get_format();
        unsigned stride = fmt.stride();