From be92396630a2065e43c21d9d1904e97014844cff Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Thu, 7 Oct 2021 16:04:57 +0300 Subject: [PATCH] Load textures in a type-generic way --- blender/io_mspgl/export_texture.py | 4 +- source/core/texture.cpp | 21 +++++++++ source/core/texture.h | 17 +++++++ source/resources/resources.cpp | 72 ++++++++++++++++-------------- source/resources/resources.h | 19 ++++++-- 5 files changed, 95 insertions(+), 38 deletions(-) diff --git a/blender/io_mspgl/export_texture.py b/blender/io_mspgl/export_texture.py index 54b21054..3d21cd1a 100644 --- a/blender/io_mspgl/export_texture.py +++ b/blender/io_mspgl/export_texture.py @@ -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)) diff --git a/source/core/texture.cpp b/source/core/texture.cpp index 568479a6..54577aac 100644 --- a/source/core/texture.cpp +++ b/source/core/texture.cpp @@ -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("1d"); + registry.register_type("2d"); + registry.register_type("3d"); + registry.register_type("2d_array"); + registry.register_type("cube"); + } + return registry; +} + Texture::Loader::Loader(Texture &t, Collection *c): CollectionObjectLoader(t, c), diff --git a/source/core/texture.h b/source/core/texture.h index 33e0769d..154a8c03 100644 --- a/source/core/texture.h +++ b/source/core/texture.h @@ -1,6 +1,7 @@ #ifndef MSP_GL_TEXTURE_H_ #define MSP_GL_TEXTURE_H_ +#include #include #include #include "pixelformat.h" @@ -49,6 +50,19 @@ protected: void mipmap_levels(unsigned); }; +public: + class GenericLoader: public DataFile::DynamicObjectLoader + { + friend class Texture; + + public: + GenericLoader(Collection &c): DynamicObjectLoader(&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 diff --git a/source/resources/resources.cpp b/source/resources/resources.cpp index 12448a90..a37496b9 100644 --- a/source/resources/resources.cpp +++ b/source/resources/resources.cpp @@ -85,16 +85,20 @@ Resources::Resources(bool set_as_global): .creator([this](const string &n) -> SimpleScene * { create_generic(n); return 0; }); add_type().suffix(".tech").keyword("technique") .notify(&set_debug_name); - add_type().base().suffix(".tex1d").keyword("texture1d") + add_type().base().suffix(".tex") + .creator([this](const string &n) -> Texture1D * { create_texture(n); return 0; }) .notify(&set_debug_name); - add_type().base().suffix(".tex2d").suffix(".png").suffix(".jpg").keyword("texture2d") - .creator([this](const string &n){ return create_texture2d(n); }) + add_type().base().suffix(".tex").suffix(".png").suffix(".jpg") + .creator([this](const string &n) -> Texture2D * { create_texture(n); return 0; }) .notify(&set_debug_name); - add_type().base().suffix(".tex3d").keyword("texture3d") + add_type().base().suffix(".tex") + .creator([this](const string &n) -> Texture3D * { create_texture(n); return 0; }) .notify(&set_debug_name); - add_type().base().suffix(".texcb").keyword("texture_cube") + add_type().base().suffix(".tex") + .creator([this](const string &n) -> TextureCube * { create_texture(n); return 0; }) .notify(&set_debug_name); - add_type().base().suffix(".tex2da").keyword("texture2d_array") + add_type().base().suffix(".tex") + .creator([this](const string &n) -> Texture2DArray * { create_texture(n); return 0; }) .notify(&set_debug_name); add_type().base().suffix(".mat") .creator([this](const string &n) -> UnlitMaterial * { create_generic(n); return 0; }) @@ -146,13 +150,13 @@ void Resources::set_resource_manager(ResourceManager *m) resource_manager = m; } -template +template T *Resources::create_generic(const string &name) { if(RefPtr 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>(name); if(RefPtr io = open_raw(name)) { RefPtr 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); add("material", &Loader::generic); add("scene", &Loader::generic); + add("texture", &Loader::generic>); } -template +template 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 +void Resources::GenericResourceLoader::type(const DataFile::Symbol &t) +{ + T::GenericLoader::type(t); + this->object->set_manager(resources.resource_manager); +} + } // namespace GL } // namespace Msp diff --git a/source/resources/resources.h b/source/resources/resources.h index f830faaa..f1aec26b 100644 --- a/source/resources/resources.h +++ b/source/resources/resources.h @@ -28,11 +28,24 @@ public: Loader(Resources &); private: - template + template void generic(const std::string &); }; private: + template + 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 + template 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 &); -- 2.43.0