Automatic Texture reload

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
sudi
Posts: 1686
Joined: Fri Aug 26, 2005 8:38 pm

Automatic Texture reload

Post by sudi »

Lately i saw this feature in a lot of editors that allow the user to change textures and the change is directly present in their editor.
So i thought hmm that can't be to hard.
And actually it isn't with one drawback. the texture has to stay the same size otherwise you will have to go through a hell of replacing texture pointers.

anyway here it is. you will need some texture called tex.png. when the programm is then running open the texture with your favorite editor and change it and save. the change will be visible in game directly.(ok delay of 1sec)

Code: Select all

/*
  Copyright (C) 2011 Daniel Sudmann

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

  Daniel Sudmann suddani@googlemail.com
*/
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>

#include <irrlicht.h>

class TextureReloader
{
public:
    TextureReloader(irr::video::IVideoDriver* d, irr::io::IFileSystem* s)
    {
        driver = d;
        system = s;
    }
    void reloadTexturesOnChange(void)
    {
        for (unsigned texId = 0; texId<driver->getTextureCount(); ++texId)
        {
            irr::video::ITexture* texture = driver->getTextureByIndex(texId);

            irr::core::stringc texfile = texture->getName().getPath();

            if (!system->existFile(texfile)) ///cannot reload memory textures bc i dunno the filename.
                continue;

            time_t cur = getChangedTime(texfile.c_str());

            irr::core::map<irr::video::ITexture*, time_t>::Node* node = ChangeTimes.find(texture);
            if (!node) ///Continue if the file is new and therefor freshly loaded
            {
                ChangeTimes[texture] = cur;
                continue;
            }

            if (cur != ChangeTimes[texture])
            {
                ChangeTimes[texture] = cur;

                irr::io::IReadFile* file = system->createAndOpenFile(texfile.c_str());
                irr::video::IImage* image = driver->createImageFromFile(file);
                file->drop();

                irr::video::ITexture* texdummy = driver->addTexture("#dummyTextureDataForReloading", image);
                image->drop();

                if (texture->getSize() == texdummy->getSize() && texture->getPitch() == texdummy->getPitch() && texture->getColorFormat() == texdummy->getColorFormat())
                {
                    void* target = texture->lock();
                    const void* source = texdummy->lock(true);
                    memcpy(target, source, texture->getSize().Height*texture->getPitch());
                    texture->unlock();
                    texdummy->unlock();
                    driver->removeTexture(texdummy);
                    texture->regenerateMipMapLevels();
                }
            }
        }
    }

    time_t getChangedTime(const char* filename)
    {
        struct stat buf;
        int result = stat(filename, &buf);
        if (result >= 0)
            return buf.st_mtime;
        return 0;
    }
protected:
    irr::video::IVideoDriver* driver;
    irr::io::IFileSystem* system;
    irr::core::map<irr::video::ITexture*, time_t> ChangeTimes;
};

int main(void)
{
    irr::IrrlichtDevice* device = irr::createDevice(irr::video::EDT_OPENGL);

    irr::video::IVideoDriver* driver = device->getVideoDriver();
    irr::scene::ISceneManager* smgr = device->getSceneManager();

    irr::scene::ISceneNode* box = smgr->addCubeSceneNode();
    box->setMaterialFlag(irr::video::EMF_LIGHTING, false);
    box->setMaterialTexture(0, driver->getTexture("tex.png"));

    TextureReloader reloader(driver, device->getFileSystem());

    smgr->addCameraSceneNode(0, irr::core::vector3df(10), irr::core::vector3df(0));

    irr::u32 time = device->getTimer()->getTime();
    while (device->run())
    {
        irr::u32 curtime = device->getTimer()->getTime();
        if (time < curtime)
        {
            time = curtime+1000;
            reloader.reloadTexturesOnChange();
        }
        driver->beginScene();
        smgr->drawAll();
        driver->endScene();
    }
    device->drop();
    return 0;
}
We're programmers. Programmers are, in their hearts, architects, and the first thing they want to do when they get to a site is to bulldoze the place flat and build something grand. We're not excited by renovation:tinkering,improving,planting flower beds.
cobra
Posts: 371
Joined: Fri Jan 23, 2009 2:56 am
Location: United States
Contact:

Post by cobra »

Great idea, Sudi!

I'm bookmarking this for sure. Thanks for sharing.
Josiah Hartzell
Image
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Post by REDDemon »

Would be nice adding to the engine an expansion of the SpriteBank class. Allowing driver auto-downloading/auto-reloading of big sprites in memory.
very usefull for editors.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

REDDemon wrote:Would be nice adding to the engine an expansion of the SpriteBank class. Allowing driver auto-downloading/auto-reloading of big sprites in memory.
very usefull for editors.
For editors, yeah, but irrlicht is not focused on any particular usage of engine, so I think this should stay as a snippet :)
Working on game: Marrbles (Currently stopped).
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: Automatic Texture reload

Post by smso »

user
lolgamegd01
is a spammer
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: Automatic Texture reload

Post by Nadro »

smso wrote:user
lolgamegd01
is a spammer
Thanks for info, I already removed this account.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
netpipe
Posts: 669
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Re: Automatic Texture reload

Post by netpipe »

i cant see this working anymore, any thoughts ?
Live long and phosphor!
-- https://github.com/netpipe/Luna Game Engine Status 95%
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Automatic Texture reload

Post by CuteAlien »

Still works here. Only change I needed was to replace the bool in locking. For example with:

Code: Select all

const void* source = texdummy->lock(irr::video::ETLM_READ_ONLY);
Well - and you need to have the texture it loads "tex.png" or replace it with one of your own.
Tested on Windows with Irrlicht trunk.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
netpipe
Posts: 669
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Re: Automatic Texture reload

Post by netpipe »

aha yes i see why, i was trying with jpg instead of png.
Live long and phosphor!
-- https://github.com/netpipe/Luna Game Engine Status 95%
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Automatic Texture reload

Post by CuteAlien »

Any format works as long as the getTexture call is changed correspondingly to load the corect texture (I tested with .jpg).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply