Saving Output to file.

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
elektrikboy
Posts: 17
Joined: Wed Dec 22, 2021 2:30 am

Saving Output to file.

Post by elektrikboy »

Hi guys.
im using the irwizard model with the gamestates, gamemanager etc etc.
ive made a simple CGameCanvas class to draw some nodes and now I need to save the output to a file at least 3000x3000 or more. I used 1024x1024 just to test.
when i finished with the make nodes function i call this SaveImage funcion which saves a .tga file but the result is allways a completly black image...

void CGameCanvas::SaveImage()
{
m_pRendertarget = m_pGameManager->getDriver()->addRenderTargetTexture(core::dimension2d<u32>(1024, 1024), "RTT1", ECF_A8R8G8B8);
IImage* finalrender = m_pGameManager->getDriver()->createImage(m_pRendertarget, position2di(0, 0), m_pRendertarget->getSize());
IWriteFile* f = m_pGameManager->getDevice()->getFileSystem()->createAndWriteFile("media/finalrender.tga",false);
int numloaders = m_pGameManager->getDriver()->getImageWriterCount();
for (int j = 0; j < numloaders; j++)
{
IImageWriter* writer = m_pGameManager->getDriver()->getImageWriter(j);
if (!writer->isAWriteableFileExtension("media/finalrender.tga"))
continue;
writer->writeImage(f, finalrender, 0);
f->drop();
writer->drop();
finalrender->drop();
}
}

in the CGamePlayState:

void CGamePlayState::Update(CGameManager* pManager)
{
// overide in child class
pManager->getDriver()->beginScene(true, true, video::SColor(0, 255, 100, 100));
//I've also tried putting setRenderTarget here but no nodes are rendered.
pManager->getSceneManager()->drawAll();
pManager->getGUIEnvironment()->drawAll();
pManager->getDriver()->setRenderTarget(pManager->getCanvas()->GetRenderTexture()); //m_pRendertarget
pManager->getDriver()->endScene();
}

what am I doing wrong here?
thx in advance
CuteAlien
Admin
Posts: 9670
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Saving Output to file.

Post by CuteAlien »

Basic idea:
Render target really means - where do you want to render stuff to. You draw into your render target. The default render target is your screen (or the memory which is then display to the screen to be exact).
Creating a render-target means creating (or reserving) memory and then you can tell Irrlicht to render to that memory instead.

So the steps you need is: Create a rendertarget first. beginScene(). Then set it active (setRenderTarget). Then draw (drawAll calls). Then you can reset it again if you want (and for example render it all once more to screen so you can also see it instead of just having it in some texture memory). Then endScene. And that rendertarget (and not a new one which will just be empty again) can be saved .

As for writing a texture to file you can use this code (works for rendertargettextures just as well as for others... unless you render to floating point formats in which case things get a bit more complicated):

Code: Select all

bool writeTextureToFile(irr::video::IVideoDriver* driver, irr::video::ITexture* texture, const irr::core::stringw& name, bool openInViewer)
{
	if (!texture)
		return false;

	void* data = texture->lock(irr::video::ETLM_READ_ONLY);
	if (!data)
		return false;

	irr::video::IImage* image = driver->createImageFromData(texture->getColorFormat(), texture->getSize(), data, false);
	texture->unlock();

	if (!image)
		return false;

	driver->writeImageToFile(image, name.c_str(), 99);

#if defined(_WIN32)
	if (openInViewer)
	{
		ShellExecute(NULL, L"open", name.c_str(), NULL, NULL, SW_SHOWNORMAL);
	}
#endif
	image->drop();

	return true;
}
Note you don't need the openInViewer parameter and the ShellExecute stuff (and if you keep it in you have to #include "shellapi.h"), but sometimes it's rather useful for quick testing on Windows (it will open the image in the default-viewer in Windows which you set for the corresponding file-ending).

edit: Also your way of calling createImage might also be fine. I was just too lazy to check. Maybe that one does the lock()'ing etc already. Important part is just writing the texture you rendered to before.
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
elektrikboy
Posts: 17
Joined: Wed Dec 22, 2021 2:30 am

Re: Saving Output to file.

Post by elektrikboy »

ok...so maybe it's better to abandon this framework and try to write all in one main function. like for example using and modifying the tutorial 13...this because for me at my level which is noob lol its kinda hard to where should i call "stuff" whithin this IrrWizard framework. I will try it simpler than if any more doubts arise I'll come here.
thx man. happy new year
elektrikboy
Posts: 17
Joined: Wed Dec 22, 2021 2:30 am

Re: Saving Output to file.

Post by elektrikboy »

Working like a charm bro!! thank you!

//Render Scene
while (device->run())
if (device->isWindowActive())
{
driver->beginScene(true, true, 0);
driver->setRenderTarget(m_pRendertarget, true, true, video::SColor(0, 0, 0, 0));
smgr->drawAll();
env->drawAll();
driver->setRenderTarget(0, true, true, 0);
smgr->drawAll();
env->drawAll();
driver->endScene();
}

//Save Image
writeTextureToFile(driver, m_pRendertarget, "media/finalrender.jpg", false);

device->drop(); // drop device
return 0;
Post Reply