]> git.tdb.fi Git - libs/gl.git/commitdiff
Load textures in a type-generic way
authorMikko Rasa <tdb@tdb.fi>
Thu, 7 Oct 2021 13:04:57 +0000 (16:04 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 7 Oct 2021 13:04:57 +0000 (16:04 +0300)
blender/io_mspgl/export_texture.py
source/core/texture.cpp
source/core/texture.h
source/resources/resources.cpp
source/resources/resources.h

index 54b2105492f898e30f8502f936e518b30b983c84..3d21cd1a796a77d540cda19ff72ba39179509ea6 100644 (file)
@@ -29,7 +29,9 @@ class TextureExporter:
        def export_texture(self, tex_node, usage='RGB', *, invert_green=False):
                image = tex_node.image
                from .datafile import Resource, Statement, Token
-               tex_res = Resource(image.name+".tex2d", "texture2d")
+               tex_res = Resource(image.name+".tex", "texture")
+
+               tex_res.statements.append(Statement("type", Token("\\2d")))
 
                if tex_node.use_mipmap:
                        tex_res.statements.append(Statement("generate_mipmap", True))
index 568479a6d7fd9d187b3a9805af63591283bc9239..54577aacd55e06f389361f0eda96305b42a63057 100644 (file)
@@ -2,6 +2,11 @@
 #include "error.h"
 #include "resourcemanager.h"
 #include "texture.h"
+#include "texture1d.h"
+#include "texture2d.h"
+#include "texture2darray.h"
+#include "texture3d.h"
+#include "texturecube.h"
 
 using namespace std;
 
@@ -61,6 +66,22 @@ void Texture::load_image(const string &fn, unsigned lv)
        image(img, lv);
 }
 
+Texture::GenericLoader::TypeRegistry &Texture::get_texture_registry()
+{
+       static GenericLoader::TypeRegistry registry;
+       static bool initialized = false;
+       if(!initialized)
+       {
+               initialized = true;
+               registry.register_type<Texture1D>("1d");
+               registry.register_type<Texture2D>("2d");
+               registry.register_type<Texture3D>("3d");
+               registry.register_type<Texture2DArray>("2d_array");
+               registry.register_type<TextureCube>("cube");
+       }
+       return registry;
+}
+
 
 Texture::Loader::Loader(Texture &t, Collection *c):
        CollectionObjectLoader<Texture>(t, c),
index 33e0769d65431ac8c6a25152b486ea589337fed4..154a8c030018f0087e062001ad851c8c8ae77758 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_GL_TEXTURE_H_
 #define MSP_GL_TEXTURE_H_
 
+#include <msp/datafile/dynamicobjectloader.h>
 #include <msp/datafile/objectloader.h>
 #include <msp/graphics/image.h>
 #include "pixelformat.h"
@@ -49,6 +50,19 @@ protected:
                void mipmap_levels(unsigned);
        };
 
+public:
+       class GenericLoader: public DataFile::DynamicObjectLoader<Texture>
+       {
+               friend class Texture;
+
+       public:
+               GenericLoader(Collection &c): DynamicObjectLoader<Texture>(&c) { }
+
+       protected:
+               virtual const TypeRegistry &get_type_registry() const { return get_texture_registry(); }
+       };
+
+protected:
        enum FormatSwizzle
        {
                NO_SWIZZLE,
@@ -83,6 +97,9 @@ public:
        virtual std::uint64_t get_data_size() const { return 0; }
 
        using TextureBackend::set_debug_name;
+
+private:
+       static GenericLoader::TypeRegistry &get_texture_registry();
 };
 
 } // namespace GL
index 12448a901fc436ce1059b7a92bc834b57f0d6166..a37496b93771190add82369f87cea33fa6b0ce2c 100644 (file)
@@ -85,16 +85,20 @@ Resources::Resources(bool set_as_global):
                .creator([this](const string &n) -> SimpleScene * { create_generic<Scene>(n); return 0; });
        add_type<Technique>().suffix(".tech").keyword("technique")
                .notify(&set_debug_name<Technique>);
-       add_type<Texture1D>().base<Texture>().suffix(".tex1d").keyword("texture1d")
+       add_type<Texture1D>().base<Texture>().suffix(".tex")
+               .creator([this](const string &n) -> Texture1D * { create_texture(n); return 0; })
                .notify(&set_debug_name<Texture1D>);
-       add_type<Texture2D>().base<Texture>().suffix(".tex2d").suffix(".png").suffix(".jpg").keyword("texture2d")
-               .creator([this](const string &n){ return create_texture2d(n); })
+       add_type<Texture2D>().base<Texture>().suffix(".tex").suffix(".png").suffix(".jpg")
+               .creator([this](const string &n) -> Texture2D * { create_texture(n); return 0; })
                .notify(&set_debug_name<Texture2D>);
-       add_type<Texture3D>().base<Texture>().suffix(".tex3d").keyword("texture3d")
+       add_type<Texture3D>().base<Texture>().suffix(".tex")
+               .creator([this](const string &n) -> Texture3D * { create_texture(n); return 0; })
                .notify(&set_debug_name<Texture3D>);
-       add_type<TextureCube>().base<Texture>().suffix(".texcb").keyword("texture_cube")
+       add_type<TextureCube>().base<Texture>().suffix(".tex")
+               .creator([this](const string &n) -> TextureCube * { create_texture(n); return 0; })
                .notify(&set_debug_name<TextureCube>);
-       add_type<Texture2DArray>().base<Texture>().suffix(".tex2da").keyword("texture2d_array")
+       add_type<Texture2DArray>().base<Texture>().suffix(".tex")
+               .creator([this](const string &n) -> Texture2DArray * { create_texture(n); return 0; })
                .notify(&set_debug_name<Texture2DArray>);
        add_type<UnlitMaterial>().base<Material>().suffix(".mat")
                .creator([this](const string &n) -> UnlitMaterial * { create_generic<Material>(n); return 0; })
@@ -146,13 +150,13 @@ void Resources::set_resource_manager(ResourceManager *m)
        resource_manager = m;
 }
 
-template<typename T>
+template<typename T, typename L>
 T *Resources::create_generic(const string &name)
 {
        if(RefPtr<IO::Seekable> io = open_raw(name))
        {
                DataFile::Parser parser(*io, name);
-               typename T::GenericLoader ldr(*this);
+               L ldr(*this);
                ldr.load(parser);
                ldr.store_object(*this, name);
        }
@@ -176,40 +180,31 @@ Mesh *Resources::create_mesh(const string &name)
        return 0;
 }
 
-Texture2D *Resources::create_texture2d(const string &name)
+Texture *Resources::create_texture(const string &name)
 {
        string ext = FS::extpart(name);
-       if(ext==".tex2d" && !resource_manager)
-               return 0;
+       if(ext==".tex")
+               return create_generic<Texture, GenericResourceLoader<Texture>>(name);
 
        if(RefPtr<IO::Seekable> io = open_raw(name))
        {
                RefPtr<Texture2D> tex;
 
-               if(ext==".tex2d")
-               {
-                       tex = new Texture2D;
-                       tex->set_manager(resource_manager);
-                       DataFile::Parser parser(*io, name);
-                       Texture2D::Loader ldr(*tex, *this);
-                       ldr.load(parser);
-               }
-               else
-               {
-                       // Verify that the image is loadable
-                       Graphics::Image image;
-                       if(!resource_manager)
-                               image.load_io(*io);
+               // Verify that the image is loadable
+               Graphics::Image image;
+               if(!resource_manager)
+                       image.load_io(*io);
 
-                       tex = new Texture2D(resource_manager);
+               tex = new Texture2D;
+               tex->set_manager(resource_manager);
 
-                       if(resource_manager)
-                               resource_manager->set_resource_location(*tex, *this, name);
-                       else
-                               tex->image(image);
-               }
+               if(resource_manager)
+                       resource_manager->set_resource_location(*tex, *this, name);
+               else
+                       tex->image(image);
 
-               return tex.release();
+               add(name, tex.get());
+               tex.release();
        }
 
        return 0;
@@ -280,15 +275,24 @@ Resources::Loader::Loader(Resources &r):
        add("light", &Loader::generic<Light>);
        add("material", &Loader::generic<Material>);
        add("scene", &Loader::generic<Scene>);
+       add("texture", &Loader::generic<Texture, GenericResourceLoader<Texture>>);
 }
 
-template<typename T>
+template<typename T, typename L>
 void Resources::Loader::generic(const string &name)
 {
-       typename T::GenericLoader ldr(obj);
+       L ldr(obj);
        load_sub_with(ldr);
        ldr.store_object(obj, name);
 }
 
+
+template<typename T>
+void Resources::GenericResourceLoader<T>::type(const DataFile::Symbol &t)
+{
+       T::GenericLoader::type(t);
+       this->object->set_manager(resources.resource_manager);
+}
+
 } // namespace GL
 } // namespace Msp
index f830faaa510ff722a7dfc485195b015217efef48..f1aec26b283b2d6cb871f551e84456ffcc8e6b1e 100644 (file)
@@ -28,11 +28,24 @@ public:
                Loader(Resources &);
 
        private:
-               template<typename T>
+               template<typename T, typename L = typename T::GenericLoader>
                void generic(const std::string &);
        };
 
 private:
+       template<typename T>
+       class GenericResourceLoader: public T::GenericLoader
+       {
+       private:
+               Resources &resources;
+
+       public:
+               GenericResourceLoader(Resources &r): T::GenericLoader(r), resources(r) { }
+
+       protected:
+               virtual void type(const DataFile::Symbol &);
+       };
+
        bool srgb_conversion;
        ResourceManager *resource_manager;
 
@@ -54,11 +67,11 @@ public:
        void set_resource_manager(ResourceManager *);
 
 protected:
-       template<typename T>
+       template<typename T, typename L = typename T::GenericLoader>
        T *create_generic(const std::string &);
 
        Mesh *create_mesh(const std::string &);
-       Texture2D *create_texture2d(const std::string &);
+       Texture *create_texture(const std::string &);
        Module *create_module(const std::string &);
        Program *create_program(const std::string &);