]> git.tdb.fi Git - libs/gl.git/commitdiff
Implement 2D array textures
authorMikko Rasa <tdb@tdb.fi>
Thu, 27 Oct 2016 08:13:39 +0000 (11:13 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 27 Oct 2016 08:13:39 +0000 (11:13 +0300)
extensions/arb_geometry_shader4.glext
extensions/ext_texture_array.glext [new file with mode: 0644]
scripts/extgen.py
source/resources.cpp
source/texture2darray.cpp [new file with mode: 0644]
source/texture2darray.h [new file with mode: 0644]
source/texture3d.cpp
source/texture3d.h

index 04cfbb3be881cb907b1a0f4a1c377cf2a2618610..801f39b56b33cabfef457da5840af7651417087b 100644 (file)
@@ -1,2 +1,3 @@
 extension ARB_geometry_shader4
 backport none
+ignore glFramebufferTextureLayerARB
diff --git a/extensions/ext_texture_array.glext b/extensions/ext_texture_array.glext
new file mode 100644 (file)
index 0000000..7051d8e
--- /dev/null
@@ -0,0 +1,2 @@
+extension EXT_texture_array
+backport none
index fd239d7077de3344f998bd6ffab84f22007c01ac..45094a4df35df26fe2608e0f07a4005378ec125e 100755 (executable)
@@ -33,6 +33,7 @@ if sys.argv[i].startswith("gl"):
 target_ext = sys.argv[i]
 backport_ext = None
 out_base = None
+ignore_things = []
 if target_ext.endswith(".glext"):
        fn = target_ext
        target_ext = None
@@ -49,6 +50,8 @@ if target_ext.endswith(".glext"):
                        secondary.append(parts[1])
                elif parts[0]=="backport":
                        backport_ext = parts[1]
+               elif parts[0]=="ignore":
+                       ignore_things.append(parts[1])
        if i+1<len(sys.argv):
                out_base = os.path.splitext(sys.argv[i+1])[0]
 else:
@@ -221,6 +224,9 @@ def parse_extension(ext):
                enums = get_nested_elements(req, "enum")
                for t in itertools.chain(commands, enums):
                        name = t.getAttribute("name")
+                       if name in ignore_things:
+                               continue
+
                        thing = things.get(name)
                        if thing:
                                if thing.extension and extension.name!=target_ext:
index c30426633e60746756428951c8e907e82829c690..32709e30e2ebf521bd6bcf69eeb262069f517e4f 100644 (file)
@@ -14,6 +14,7 @@
 #include "technique.h"
 #include "texture1d.h"
 #include "texture2d.h"
+#include "texture2darray.h"
 #include "texturecube.h"
 
 using namespace std;
@@ -40,6 +41,7 @@ Resources::Resources():
        add_type<Texture2D>().base<Texture>().suffix(".tex2d").suffix(".png").suffix(".jpg").keyword("texture2d").creator(&Resources::create_texture2d);
        add_type<Texture3D>().base<Texture>().suffix(".tex3d").keyword("texture3d");
        add_type<TextureCube>().base<Texture>().suffix(".texcb").keyword("texture_cube");
+       add_type<Texture2DArray>().base<Texture>().suffix(".tex2da").keyword("texture2d_array");
 }
 
 void Resources::set_default_texture_filter(TextureFilter tf)
diff --git a/source/texture2darray.cpp b/source/texture2darray.cpp
new file mode 100644 (file)
index 0000000..27e0d53
--- /dev/null
@@ -0,0 +1,73 @@
+#include <msp/datafile/collection.h>
+#include <msp/gl/extensions/ext_texture_array.h>
+#include "error.h"
+#include "pixelstore.h"
+#include "texture2darray.h"
+
+using namespace std;
+
+namespace Msp {
+namespace GL {
+
+Texture2DArray::Texture2DArray():
+       Texture3D(GL_TEXTURE_2D_ARRAY)
+{
+       static Require _req(EXT_texture_array);
+}
+
+void Texture2DArray::layer_image(unsigned level, unsigned z, PixelFormat fmt, DataType type, 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, fmt, type, data);
+}
+
+void Texture2DArray::layer_image(unsigned level, unsigned z, const Graphics::Image &img)
+{
+       if(!get_width())
+               throw invalid_operation("Texture2D::layer_image");
+
+       unsigned w = img.get_width();
+       unsigned h = img.get_height();
+       PixelFormat fmt = pixelformat_from_graphics(img.get_format());
+       if(w!=get_width() || h!=get_height())
+               throw incompatible_data("Texture2D::image");
+
+       PixelStore pstore = PixelStore::from_image(img);
+       BindRestore _bind_ps(pstore);
+
+       layer_image(level, z, fmt, UNSIGNED_BYTE, img.get_data());
+}
+
+
+Texture2DArray::Loader::Loader(Texture2DArray &t):
+       DataFile::DerivedObjectLoader<Texture2DArray, Texture3D::Loader>(t)
+{
+       init();
+}
+
+Texture2DArray::Loader::Loader(Texture2DArray &t, Collection &c):
+       DataFile::DerivedObjectLoader<Texture2DArray, Texture3D::Loader>(t, c)
+{
+       init();
+}
+
+void Texture2DArray::Loader::init()
+{
+       add("external_image", &Loader::external_image);
+}
+
+void Texture2DArray::Loader::external_image(unsigned z, const string &fn)
+{
+       Graphics::Image img;
+       RefPtr<IO::Seekable> io = get_collection().open_raw(fn);
+       img.load_io(*io);
+
+       obj.layer_image(0, z, img);
+}
+
+} // namespace GL
+} // namespace Msp
diff --git a/source/texture2darray.h b/source/texture2darray.h
new file mode 100644 (file)
index 0000000..5e0969a
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef MSP_GL_TEXTURE2DARRAY_H_
+#define MSP_GL_TEXTURE2DARRAY_H_
+
+#include "texture3d.h"
+
+namespace Msp {
+namespace GL {
+
+/**
+An array of two-dimensional textures.  It's very much like a 3D texture, with
+two important differences: there's no filtering nor mipmapping along the third
+dimension.
+*/
+class Texture2DArray: public Texture3D
+{
+public:
+       class Loader: public Msp::DataFile::DerivedObjectLoader<Texture2DArray, Texture3D::Loader>
+       {
+       public:
+               Loader(Texture2DArray &);
+               Loader(Texture2DArray &, Collection &);
+       private:
+               void init();
+
+               void external_image(unsigned, const std::string &);
+       };
+
+       Texture2DArray();
+
+       void layer_image(unsigned, unsigned, PixelFormat, DataType, const void *);
+       void layer_image(unsigned, unsigned, const Graphics::Image &);
+
+       unsigned get_layers() const { return get_depth(); }
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif
index 8b014aee0c262fb811444c1c44a1fba0083df21e..8cb26e7f76713bf44932f25744aea5d31be4defd 100644 (file)
@@ -11,6 +11,15 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
+Texture3D::Texture3D(GLenum t):
+       Texture(t),
+       ifmt(RGB),
+       width(0),
+       height(0),
+       depth(0),
+       allocated(0)
+{ }
+
 Texture3D::Texture3D():
        Texture(GL_TEXTURE_3D),
        ifmt(RGB),
@@ -161,7 +170,8 @@ void Texture3D::get_level_size(unsigned level, unsigned &w, unsigned &h, unsigne
 {
        w >>= level;
        h >>= level;
-       d >>= level;
+       if(target!=GL_TEXTURE_2D_ARRAY)
+               d >>= level;
 
        if(!w && (h || d))
                w = 1;
index 75ae0fe902acb1eb8974591df86b67c9505e5fb3..55a0e3dbe8ec4ce214bdc56f5532655160965b58 100644 (file)
@@ -33,6 +33,8 @@ private:
        unsigned depth;
        unsigned allocated;
 
+protected:
+       Texture3D(GLenum);
 public:
        Texture3D();
 
@@ -82,7 +84,7 @@ public:
        unsigned get_width() const { return width; }
        unsigned get_height() const { return height; }
        unsigned get_depth() const { return depth; }
-private:
+protected:
        void get_level_size(unsigned, unsigned &, unsigned &, unsigned &);
 
 public: