X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fcore%2Ftexture2d.cpp;h=a0ba9515e68babe3387b9e2af1278087b1d6d3f9;hp=74071535e73f41e768f053cd5041479fe80353c3;hb=225dbd7ba2dde73bb28e54e03ae960e88e708f57;hpb=3054756d04a94ec9471448970421de4a7aa7b247 diff --git a/source/core/texture2d.cpp b/source/core/texture2d.cpp index 74071535..a0ba9515 100644 --- a/source/core/texture2d.cpp +++ b/source/core/texture2d.cpp @@ -1,3 +1,5 @@ +#include +#include #include "error.h" #include "texture2d.h" @@ -6,6 +8,27 @@ using namespace std; namespace Msp { namespace GL { +class Texture2D::AsyncLoader: public Resource::AsyncLoader +{ +private: + Texture2D &texture; + IO::Seekable &io; + Texture2D::AsyncTransfer transfer; + Graphics::Image image; + Graphics::ImageLoader *img_loader = 0; + DataFile::RawData *raw_data = 0; + unsigned n_bytes = 0; + int phase = 0; + +public: + AsyncLoader(Texture2D &, IO::Seekable &); + ~AsyncLoader(); + + virtual bool needs_sync() const; + virtual bool process(); +}; + + Texture2D::~Texture2D() { set_manager(0); @@ -72,6 +95,11 @@ LinAl::Vector Texture2D::get_level_size(unsigned level) const return LinAl::Vector(w, h); } +Resource::AsyncLoader *Texture2D::load(IO::Seekable &io, const Resources *) +{ + return new AsyncLoader(static_cast(*this), io); +} + Texture2D::Loader::Loader(Texture2D &t): DataFile::DerivedObjectLoader(t) @@ -156,5 +184,76 @@ Texture2D::AsyncTransfer::~AsyncTransfer() finalize(); } + +Texture2D::AsyncLoader::AsyncLoader(Texture2D &t, IO::Seekable &i): + texture(t), + io(i) +{ + char magic[4] = { }; + io.read(magic, 4); + io.seek(0, IO::S_BEG); + + if(DataFile::RawData::detect_signature(string(magic, 4))) + { + raw_data = new DataFile::RawData; + raw_data->open_io(io, "async"); + } + else + img_loader = Graphics::ImageLoader::open_io(io); +} + +Texture2D::AsyncLoader::~AsyncLoader() +{ + delete img_loader; + delete raw_data; +} + +bool Texture2D::AsyncLoader::needs_sync() const +{ + return phase%2; +} + +bool Texture2D::AsyncLoader::process() +{ + if(phase==0) + { + if(raw_data) + n_bytes = raw_data->get_size(); + else + { + image.load_headers(*img_loader); + n_bytes = image.get_stride()*image.get_height(); + } + } + else if(phase==1) + { + if(img_loader) + { + unsigned w = image.get_width(); + unsigned h = image.get_height(); + texture.storage(pixelformat_from_image(image, texture.use_srgb_format), w, h); + } + + transfer = texture.sub_image_async(0, 0, 0, texture.width, texture.height); + } + else if(phase==2) + { + if(raw_data) + raw_data->load_into(transfer.get_address()); + else + image.load_into(*img_loader, transfer.get_address()); + } + else if(phase==3) + { + transfer = Texture2D::AsyncTransfer(); + + if(texture.auto_gen_mipmap) + texture.generate_mipmap(); + } + + ++phase; + return phase>3; +} + } // namespace GL } // namespace Msp