]> git.tdb.fi Git - libs/gl.git/commitdiff
Remove support for texture borders
authorMikko Rasa <tdb@tdb.fi>
Tue, 30 Nov 2010 13:10:50 +0000 (13:10 +0000)
committerMikko Rasa <tdb@tdb.fi>
Tue, 30 Nov 2010 13:10:50 +0000 (13:10 +0000)
Implement missing Texture3D::sub_image
Add allocate methods to Texture2D and Texture3D
Fix a bug in Texture

12 files changed:
maketex.py
mesh_export.py
source/bloom.cpp
source/pipeline.cpp
source/pixelformat.cpp
source/pixelformat.h
source/shadowmap.cpp
source/texture.cpp
source/texture2d.cpp
source/texture2d.h
source/texture3d.cpp
source/texture3d.h

index 017aa121368057e42a7119ef6973f9a2aadc6ddc..fa8e70d80022d8f3ad84add0af47741f0105b761 100755 (executable)
@@ -26,7 +26,7 @@ def make_tex(fn):
        elif fmt=="L":
                fmt="LUMINANCE"
 
        elif fmt=="L":
                fmt="LUMINANCE"
 
-       result="storage %s %d %d 0;\n"%(fmt, img.size[0], img.size[1])
+       result="storage %s %d %d;\n"%(fmt, img.size[0], img.size[1])
        result+="min_filter LINEAR;\n"
        result+="raw_data \""
        data=list(img.getdata())
        result+="min_filter LINEAR;\n"
        result+="raw_data \""
        data=list(img.getdata())
index 9e09ef4d39c0d4d970fc24eed6cbdfb98ff102f9..1e0047dc483cf67817fdb27a6797e8871c18b881 100644 (file)
@@ -671,7 +671,7 @@ class Exporter:
                                self.out_file.begin("texture2d")
                                self.out_file.write("min_filter", "NEAREST")
                                self.out_file.write("mag_filter", "NEAREST")
                                self.out_file.begin("texture2d")
                                self.out_file.write("min_filter", "NEAREST")
                                self.out_file.write("mag_filter", "NEAREST")
-                               self.out_file.write("storage", "RGB", len(mesh.materials), 1, 0)
+                               self.out_file.write("storage", "RGB", len(mesh.materials), 1)
                                texdata = '"'
                                for m in mesh.materials:
                                        texdata += "\\x%02X\\x%02X\\x%02X"%(int(m.R*255), int(m.G*255), int(m.B*255))
                                texdata = '"'
                                for m in mesh.materials:
                                        texdata += "\\x%02X\\x%02X\\x%02X"%(int(m.R*255), int(m.G*255), int(m.B*255))
index 040fd6c7b1fa5ea5f995aafc4e45784665a87269..7c4338f8e1fe975706b677ec810e42b9dd91bd36 100644 (file)
@@ -76,7 +76,7 @@ Bloom::Bloom(unsigned w, unsigned h):
        {
                blur_shdata[i].uniform(loc, 0);
                tex[i].set_min_filter(NEAREST);
        {
                blur_shdata[i].uniform(loc, 0);
                tex[i].set_min_filter(NEAREST);
-               tex[i].storage(RGB16F, w, h, 0);
+               tex[i].storage(RGB16F, w, h);
                tex[i].image(0, RGB, UNSIGNED_BYTE, 0);
        }
 
                tex[i].image(0, RGB, UNSIGNED_BYTE, 0);
        }
 
index f05d15b8271fe0ce9f216b62258f50d10758f231..95f96536f81c1f6891c5be726c2517ca95a08e2a 100644 (file)
@@ -119,7 +119,7 @@ void Pipeline::add_postprocessor(PostProcessor &pp)
                color_buf = new Texture2D;
                color_buf->set_min_filter(NEAREST);
                color_buf->set_mag_filter(NEAREST);
                color_buf = new Texture2D;
                color_buf->set_min_filter(NEAREST);
                color_buf->set_mag_filter(NEAREST);
-               color_buf->storage((hdr ? RGB16F : RGB), width, height, 0);
+               color_buf->storage((hdr ? RGB16F : RGB), width, height);
                color_buf->image(0, RGB, UNSIGNED_BYTE, 0);
                fbo->attach(COLOR_ATTACHMENT0, *color_buf, 0);
                depth_buf = new Renderbuffer;
                color_buf->image(0, RGB, UNSIGNED_BYTE, 0);
                fbo->attach(COLOR_ATTACHMENT0, *color_buf, 0);
                depth_buf = new Renderbuffer;
index 27a814e21e1c30b946c24cf2fad6287dc073a664..91f102261cf63006d933b017427656adc8cb867d 100644 (file)
@@ -65,5 +65,25 @@ PixelFormat pixelformat_from_graphics(Graphics::PixelFormat pf)
        }
 }
 
        }
 }
 
+PixelFormat get_base_pixelformat(PixelFormat pf)
+{
+       switch(pf)
+       {
+       case RGB8:
+       case RGB16F:
+       case RGB32F: return RGB;
+       case RGBA8:
+       case RGBA16F:
+       case RGBA32F: return RGBA;
+       case LUMINANCE8:
+       case LUMINANCE16F:
+       case LUMINANCE32F: return LUMINANCE;
+       case LUMINANCE_ALPHA8:
+       case LUMINANCE_ALPHA16F:
+       case LUMINANCE_ALPHA32F: return LUMINANCE_ALPHA;
+       default: return pf;
+       }
+}
+
 } // namespace GL
 } // namespace Msp
 } // namespace GL
 } // namespace Msp
index 6063145ad859c042eb5070c5ae787ad94d904d87..81662cb9ea63dd798fe91a4218e8f47f0cdf3fae 100644 (file)
@@ -49,6 +49,8 @@ std::istream &operator>>(std::istream &, PixelFormat &);
 
 PixelFormat pixelformat_from_graphics(Graphics::PixelFormat);
 
 
 PixelFormat pixelformat_from_graphics(Graphics::PixelFormat);
 
+PixelFormat get_base_pixelformat(PixelFormat);
+
 } // namespace GL
 } // namespace Msp
 
 } // namespace GL
 } // namespace Msp
 
index c8730426e6a557b113440914bef162239bc02751..dbc4bd56524688170770d0e5d9fabe68ea3eac3c 100644 (file)
@@ -30,7 +30,7 @@ ShadowMap::ShadowMap(unsigned s, const Scene &c, const Light &l):
        depth_buf.set_compare_enabled(true);
        depth_buf.set_compare_func(LEQUAL);
        depth_buf.set_wrap(CLAMP_TO_EDGE);
        depth_buf.set_compare_enabled(true);
        depth_buf.set_compare_func(LEQUAL);
        depth_buf.set_wrap(CLAMP_TO_EDGE);
-       depth_buf.storage(DEPTH_COMPONENT, size, size, 0);
+       depth_buf.storage(DEPTH_COMPONENT, size, size);
        depth_buf.image(0, DEPTH_COMPONENT, UNSIGNED_BYTE, 0);
        fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0);
 }
        depth_buf.image(0, DEPTH_COMPONENT, UNSIGNED_BYTE, 0);
        fbo.attach(DEPTH_ATTACHMENT, depth_buf, 0);
 }
index dc69732fe2f33dafff253b51359898bbcaf1c260..52ad074281d30b945f0b2f328883f25ef06704da 100644 (file)
@@ -76,7 +76,7 @@ void Texture::update_parameter(int mask) const
                        glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, gen_mipmap);
                if(mask&COMPARE)
                        glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, (compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE));
                        glTexParameteri(target, GL_GENERATE_MIPMAP_SGIS, gen_mipmap);
                if(mask&COMPARE)
                        glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, (compare ? GL_COMPARE_R_TO_TEXTURE : GL_NONE));
-               if(mask&cmp_func)
+               if(mask&COMPARE_FUNC)
                        glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, cmp_func);
        }
        else
                        glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, cmp_func);
        }
        else
index 8935933f995117322069ad1652b6b1d9ffc87d0c..c92099cedb35e79c362ab6cab25acd0d7359bd25 100644 (file)
@@ -17,10 +17,11 @@ namespace GL {
 Texture2D::Texture2D():
        Texture(GL_TEXTURE_2D),
        width(0),
 Texture2D::Texture2D():
        Texture(GL_TEXTURE_2D),
        width(0),
-       height(0)
+       height(0),
+       allocated(0)
 { }
 
 { }
 
-void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht, int brd)
+void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht)
 {
        if(width>0)
                throw InvalidState("Texture storage may only be specified once");
 {
        if(width>0)
                throw InvalidState("Texture storage may only be specified once");
@@ -30,22 +31,39 @@ void Texture2D::storage(PixelFormat fmt, unsigned wd, unsigned ht, int brd)
        ifmt = fmt;
        width = wd;
        height = ht;
        ifmt = fmt;
        width = wd;
        height = ht;
-       border = brd;
 }
 
 }
 
-void Texture2D::image(int level, PixelFormat fmt, DataType type, const void *data)
+void Texture2D::allocate(unsigned level)
 {
 {
-       if(width==0)
-               throw InvalidState("Texture storage has not been specified");
+       if(allocated&(1<<level))
+               return;
+
+       image(level, get_base_pixelformat(ifmt), UNSIGNED_BYTE, 0);
+}
+
+void Texture2D::image(unsigned level, PixelFormat fmt, DataType type, const void *data)
+{
+       require_storage();
+
+       unsigned w = width;
+       unsigned h = height;
+       get_level_size(level, w, h);
 
        Bind _bind(this, true);
 
        Bind _bind(this, true);
-       glTexImage2D(target, level, ifmt, width, height, border, fmt, type, data);
+       glTexImage2D(target, level, ifmt, w, h, 0, fmt, type, data);
+
+       allocated |= 1<<level;
+       if(gen_mipmap && level==0)
+       {
+               for(; (w || h); w>>=1, h>>=1, ++level) ;
+               allocated |= (1<<level)-1;
+       }
 }
 
 }
 
-void Texture2D::sub_image(int level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data)
+void Texture2D::sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data)
 {
 {
-       if(width==0)
-               throw InvalidState("Texture storage has not been specified");
+       require_storage();
+       allocate(level);
 
        Bind _bind(this, true);
        glTexSubImage2D(target, level, x, y, wd, ht, fmt, type, data);
 
        Bind _bind(this, true);
        glTexSubImage2D(target, level, x, y, wd, ht, fmt, type, data);
@@ -65,13 +83,30 @@ void Texture2D::image(const Graphics::Image &img)
        unsigned h = img.get_height();
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
        unsigned h = img.get_height();
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
-               storage(fmt, w, h, 0);
+               storage(fmt, w, h);
        else if(w!=width || h!=height)
                throw IncompatibleData("Image does not match texture storage");
 
        image(0, fmt, UNSIGNED_BYTE, img.get_data());
 }
 
        else if(w!=width || h!=height)
                throw IncompatibleData("Image does not match texture storage");
 
        image(0, fmt, UNSIGNED_BYTE, img.get_data());
 }
 
+void Texture2D::require_storage()
+{
+       if(width==0 || height==0)
+               throw InvalidState("Texture storage has not been specified");
+}
+
+void Texture2D::get_level_size(unsigned level, unsigned &w, unsigned &h)
+{
+       w >>= level;
+       h >>= level;
+
+       if(!w && h)
+               w = 1;
+       else if(!h && w)
+               h = 1;
+}
+
 
 Texture2D::Loader::Loader(Texture2D &t):
        Texture::Loader(t)
 
 Texture2D::Loader::Loader(Texture2D &t):
        Texture::Loader(t)
@@ -79,6 +114,7 @@ Texture2D::Loader::Loader(Texture2D &t):
        add("image_data", &Loader::image_data);
        add("raw_data", &Loader::raw_data);
        add("storage", &Loader::storage);
        add("image_data", &Loader::image_data);
        add("raw_data", &Loader::raw_data);
        add("storage", &Loader::storage);
+       add("storage", &Loader::storage_b);
 }
 
 void Texture2D::Loader::image_data(const string &data)
 }
 
 void Texture2D::Loader::image_data(const string &data)
@@ -95,9 +131,14 @@ void Texture2D::Loader::raw_data(const string &data)
        t2d.image(0, t2d.ifmt, UNSIGNED_BYTE, data.data());
 }
 
        t2d.image(0, t2d.ifmt, UNSIGNED_BYTE, data.data());
 }
 
-void Texture2D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h, unsigned b)
+void Texture2D::Loader::storage(PixelFormat fmt, unsigned w, unsigned h)
+{
+       static_cast<Texture2D &>(obj).storage(fmt, w, h);
+}
+
+void Texture2D::Loader::storage_b(PixelFormat fmt, unsigned w, unsigned h, unsigned)
 {
 {
-       static_cast<Texture2D &>(obj).storage(fmt, w, h, b);
+       storage(fmt, w, h);
 }
 
 } // namespace GL
 }
 
 } // namespace GL
index 012718528af72592039831c2a27c69b6a58aa728..8508b0435847eaa7eaf9485c5b0765017e4dbe6f 100644 (file)
@@ -30,14 +30,15 @@ public:
        private:
                void image_data(const std::string &);
                void raw_data(const std::string &);
        private:
                void image_data(const std::string &);
                void raw_data(const std::string &);
-               void storage(PixelFormat, unsigned, unsigned, unsigned);
+               void storage(PixelFormat, unsigned, unsigned);
+               void storage_b(PixelFormat, unsigned, unsigned, unsigned);
        };
 
 private:
        PixelFormat ifmt;
        unsigned width;
        unsigned height;
        };
 
 private:
        PixelFormat ifmt;
        unsigned width;
        unsigned height;
-       int border;
+       unsigned allocated;
 
 public:
        Texture2D();
 
 public:
        Texture2D();
@@ -46,20 +47,22 @@ public:
        Defines the texture storage.  This function may only be successfully called
        once.
        */
        Defines the texture storage.  This function may only be successfully called
        once.
        */
-       void storage(PixelFormat fmt, unsigned wd, unsigned ht, int brd);
+       void storage(PixelFormat fmt, unsigned wd, unsigned ht);
+
+       /** Allocates texture storage.  If storage has already been allocated, this
+       function does nothing. */
+       void allocate(unsigned level);
        
        
-       /**
-       Uploads an image to the texture.  storage() must have been called prior to
+       /** Uploads an image to the texture.  storage() must have been called prior to
        this, and the image must have dimensions conforming to the specified
        this, and the image must have dimensions conforming to the specified
-       storage.
-       */
-       void image(int level, PixelFormat fmt, DataType type, const void *data);
+       storage.  For level>0, mipmapping rules apply to the image dimensions. */
+       void image(unsigned level, PixelFormat fmt, DataType type, const void *data);
 
        /**
        Uploads a sub-image into the texture.  Unlike full image upload, there are
        no constraints on the size of the sub-image.
        */
 
        /**
        Uploads a sub-image into the texture.  Unlike full image upload, there are
        no constraints on the size of the sub-image.
        */
-       void sub_image(int level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data);
+       void sub_image(unsigned level, int x, int y, unsigned wd, unsigned ht, PixelFormat fmt, DataType type, const void *data);
 
        /**
        Loads an image from a file and uploads it to the texture.  If storage() has
 
        /**
        Loads an image from a file and uploads it to the texture.  If storage() has
@@ -72,6 +75,8 @@ public:
 
 private:
        void image(const Graphics::Image &);
 
 private:
        void image(const Graphics::Image &);
+       void require_storage();
+       void get_level_size(unsigned, unsigned &, unsigned &);
 };
 
 } // namespace GL
 };
 
 } // namespace GL
index 7edc908098c73ed0866ff6d9733874f4efa7993d..6515946bb2bba5885dd6dd6d5c425438804cc400 100644 (file)
@@ -22,12 +22,13 @@ Texture3D::Texture3D():
        Texture(GL_TEXTURE_3D),
        width(0),
        height(0),
        Texture(GL_TEXTURE_3D),
        width(0),
        height(0),
-       depth(0)
+       depth(0),
+       allocated(0)
 {
        static RequireVersion _ver(1, 2);
 }
 
 {
        static RequireVersion _ver(1, 2);
 }
 
-void Texture3D::storage(PixelFormat f, unsigned w, unsigned h, unsigned d, int b)
+void Texture3D::storage(PixelFormat f, unsigned w, unsigned h, unsigned d)
 {
        if(width>0)
                throw InvalidState("Textures storage may only be specified once");
 {
        if(width>0)
                throw InvalidState("Textures storage may only be specified once");
@@ -38,18 +39,45 @@ void Texture3D::storage(PixelFormat f, unsigned w, unsigned h, unsigned d, int b
        height = h;
        depth = d;
        ifmt = f;
        height = h;
        depth = d;
        ifmt = f;
-       border = b;
 
        image(0, ifmt, UNSIGNED_BYTE, 0);
 }
 
 
        image(0, ifmt, UNSIGNED_BYTE, 0);
 }
 
-void Texture3D::image(int level, PixelFormat fmt, DataType type, const void *data)
+void Texture3D::allocate(unsigned level)
 {
 {
-       if(width==0)
-               throw InvalidState("Texture storage has not been specified");
+       if(allocated&(1<<level))
+               return;
+
+       image(level, get_base_pixelformat(ifmt), UNSIGNED_BYTE, 0);
+}
+
+void Texture3D::image(unsigned level, PixelFormat fmt, DataType type, const void *data)
+{
+       require_storage();
+
+       unsigned w = width;
+       unsigned h = height;
+       unsigned d = depth;
+       get_level_size(level, w, h, d);
+
+       Bind _bind(this, true);
+       glTexImage3D(target, level, ifmt, width, height, depth, 0, fmt, type, data);
+
+       allocated |= 1<<level;
+       if(gen_mipmap && level==0)
+       {
+               for(; (w || h || d); w>>=1, h>>=1, d>>=1, ++level) ;
+               allocated |= (1<<level)-1;
+       }
+}
+
+void Texture3D::sub_image(unsigned level, int x, int y, int z, unsigned wd, unsigned ht, unsigned dp, PixelFormat fmt, DataType type, const void *data)
+{
+       require_storage();
+       allocate(level);
 
        Bind _bind(this, true);
 
        Bind _bind(this, true);
-       glTexImage3D(target, level, ifmt, width, height, depth, border, fmt, type, data);
+       glTexSubImage3D(target, level, x, y, z, wd, ht, dp, fmt, type, data);
 }
 
 void Texture3D::load_image(const string &fn, int dp)
 }
 
 void Texture3D::load_image(const string &fn, int dp)
@@ -81,12 +109,32 @@ void Texture3D::load_image(const string &fn, int dp)
 
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
 
        PixelFormat fmt = pixelformat_from_graphics(img.get_format());
        if(width==0)
-               storage(fmt, w, h, d, 0);
+               storage(fmt, w, h, d);
        else if(w!=width || h!=height || d!=depth)
                throw IncompatibleData("Image does not match texture storage");
 
        image(0, fmt, UNSIGNED_INT, img.get_data());
 }
 
        else if(w!=width || h!=height || d!=depth)
                throw IncompatibleData("Image does not match texture storage");
 
        image(0, fmt, UNSIGNED_INT, img.get_data());
 }
 
+void Texture3D::require_storage()
+{
+       if(width==0 || height==0 || depth==0)
+               throw InvalidState("Texture storage has not been specified");
+}
+
+void Texture3D::get_level_size(unsigned level, unsigned &w, unsigned &h, unsigned &d)
+{
+       w >>= level;
+       h >>= level;
+       d >>= level;
+
+       if(!w && (h || d))
+               w = 1;
+       if(!h && (w || d))
+               h = 1;
+       if(!d && (w || h))
+               d = 1;
+}
+
 } // namespace GL
 } // namespace Msp
 } // namespace GL
 } // namespace Msp
index 50e4555aa56cca44e3ec0d66ee09d2641a81f3ab..15d244dec10f116eca42f8c53515e3994720e90a 100644 (file)
@@ -23,17 +23,21 @@ private:
        unsigned width;
        unsigned height;
        unsigned depth;
        unsigned width;
        unsigned height;
        unsigned depth;
-       int border;
+       unsigned allocated;
 
 public:
        Texture3D();
 
 public:
        Texture3D();
-       void storage(PixelFormat, unsigned, unsigned, unsigned, int);
-       void image(int, PixelFormat, DataType, const void *);
-       void sub_image(int, int, int, unsigned, unsigned, unsigned, PixelFormat, DataType, const void *);
+       void storage(PixelFormat, unsigned, unsigned, unsigned);
+       void allocate(unsigned);
+       void image(unsigned, PixelFormat, DataType, const void *);
+       void sub_image(unsigned, int, int, int, unsigned, unsigned, unsigned, PixelFormat, DataType, const void *);
        void load_image(const std::string &fn, int dp = -1);
        unsigned get_width() const { return width; }
        unsigned get_height() const { return height; }
        unsigned get_depth() const { return depth; }
        void load_image(const std::string &fn, int dp = -1);
        unsigned get_width() const { return width; }
        unsigned get_height() const { return height; }
        unsigned get_depth() const { return depth; }
+private:
+       void require_storage();
+       void get_level_size(unsigned, unsigned &, unsigned &, unsigned &);
 };
 
 } // namespace GL
 };
 
 } // namespace GL