ITexture::lock() and update too slow?

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
Imbrondir
Posts: 6
Joined: Fri Jun 29, 2007 1:36 pm

ITexture::lock() and update too slow?

Post by Imbrondir »

Hey.

I've drawn some graphics to an ITexture, and mapped it to cube. Now I want to update the graphics to the texture, but suddenly I get like 5fps. First I thought it was the 2D library (cairo), but I isolated it down to only (ITexture*)texture->lock()
and later unlocking it.

Why is this slow? And is there any other way of doing it?
Nox
Posts: 304
Joined: Wed Jan 14, 2009 6:23 pm

Post by Nox »

What kind of texture do you use? Do you use a dynamic/rendertargettexture? Because normal textures are not optimizied for frequently locks/unlocks.
Imbrondir
Posts: 6
Joined: Fri Jun 29, 2007 1:36 pm

Post by Imbrondir »

Nox wrote:What kind of texture do you use? Do you use a dynamic/rendertargettexture? Because normal textures are not optimizied for frequently locks/unlocks.
I changed the addTexture to addRenderTargetTexture, and it certainly did the trick! Thank you for the tip.
Imbrondir
Posts: 6
Joined: Fri Jun 29, 2007 1:36 pm

Post by Imbrondir »

One thing though. With this change, suddenly my texture got mirrored. Why is this? Well both the actual image _and_ a mirrored copy beneath.

[EDIT: If i don't update it (only draw it the first time, I only get the mirrored one).]
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

What's your code and driver?
Imbrondir
Posts: 6
Joined: Fri Jun 29, 2007 1:36 pm

Post by Imbrondir »

Using OpenGL as driver and Irrlicht 1.5. Slowing down the framerate I can see what is happening. The frames are instead of:

Original -> Orignal -> Original -> etc...

I get:

Blank -> Original -> Blank -> etc...
Mirror Org -> Blank -> Mirror Org

I tested it with Direct3d 8 and 9 driver, but then I only get some weird stuff on the screen. With burning video software rasterizer I also get a strange result. I suppose I'm doing something very wrong possibly with appling the texture to the cube I'm using. Anyway here's the code

Code: Select all

#pragma once;
#include <iostream>
#include <windows.h>
#define WIN32_LEAN_AND_MEAN
#include <irrlicht.h>
//locals
#include "ModelSource/cairotest.h"

using namespace irr; 
using namespace core; 
using namespace scene; 
using namespace video; 
using namespace gui;

//starting off easy
int main()
{
	CairoParty painter;
	//setup
	IrrlichtDevice* device = createDevice(EDT_OPENGL, core::dimension2d<s32>(640,480));
	IVideoDriver* video = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();

	//include stash
	gui::IGUIFont* font = device->getGUIEnvironment()->getBuiltInFont();
	ICameraSceneNode* camera = smgr->addCameraSceneNode();
	camera->setPosition(core::vector3df(0, 0, -895));
	camera->setTarget(core::vector3df(0, 0, 0));
	camera->setFOV(core::PI/6); //30 degrees

	video->setTextureCreationFlag(ETCF_ALWAYS_32_BIT, true);
	//ITexture* drawable = video->getTexture("test.bmp");
	ITexture* drawable = video->addRenderTargetTexture(dimension2d<s32>(640,480), "test");
	painter.updateTestSurface(drawable);

	ISceneNode* cube = smgr->addCubeSceneNode();
	cube->setMaterialFlag(EMF_LIGHTING, false);
	cube->setMaterialTexture(0, drawable);
	cube->setMaterialType(EMT_SOLID);
	cube->setPosition(vector3df(0,0,5));
	cube->setScale(vector3df(64,48,1));


	//runtime
	bool runningAway = true;
	while(device->run() && device)
	{
		video->beginScene(true, true, video::SColor(255,0,0,250)); 
		smgr->drawAll();
		video->endScene();

		painter.update();
		Sleep(20); //offload GPU, and run at 'only' 50fps (hate that fan)
	}
}
And the code in the CairoParty class of interest is in
void CairoParty::updateTestSurface(irr::video::ITexture* texture);
void CairoParty::update();
updateTestSurface despite the name only draws the first picture. And update for now only locks and unlocks the texture sent through updateTestSurface.

Code: Select all

void CairoParty::updateTestSurface(irr::video::ITexture* texture)
{
	irr::core::dimension2d<irr::s32> tex_size = texture->getSize();
	if(texture && texture->getColorFormat() == irr::video::ECF_A8R8G8B8)	
	{
		this->texture = texture;
		int stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, tex_size.Width);
		//surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, tex_size.Width, tex_size.Height);
		surface = cairo_image_surface_create_for_data((irr::u8*)texture->lock(), CAIRO_FORMAT_ARGB32, tex_size.Width, tex_size.Height, stride);
		cr = cairo_create (surface);


		cairo_set_line_width (cr, 6);

		//background
		cairo_rectangle(cr, 0, 0, tex_size.Width, tex_size.Height);
		cairo_set_source_rgb(cr, 1, 1, 1); cairo_fill(cr);

		cairo_rectangle (cr, 12, 12, 232, 70);
		cairo_new_sub_path (cr); cairo_arc (cr, 64, 64, 40, 0, 2*M_PI);
		cairo_new_sub_path (cr); cairo_arc_negative (cr, 192, 64, 40, 0, -2*M_PI);

		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
		cairo_set_source_rgb (cr, 0, 0.7, 0); cairo_fill_preserve (cr);
		cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr);

		cairo_translate (cr, 0, 128);
		cairo_rectangle (cr, 12, 12, 232, 70);
		cairo_new_sub_path (cr); cairo_arc (cr, 64, 64, 40, 0, 2*M_PI);
		cairo_new_sub_path (cr); cairo_arc_negative (cr, 192, 64, 40, 0, -2*M_PI);

		cairo_set_fill_rule (cr, CAIRO_FILL_RULE_WINDING);
		cairo_set_source_rgb (cr, 0, 0, 0.9); cairo_fill_preserve (cr);
		cairo_set_source_rgb (cr, 0, 0, 0); cairo_stroke (cr);


		cairo_select_font_face(cr, "serif", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
		cairo_set_font_size(cr, 32.0);
		cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
		cairo_move_to(cr, 400.0, 50.0);
		cairo_show_text(cr, "Hello, world");

		//cairo_image_surface_blur(surface, 5);

		//must context and surface be destroyed upon each update?

		//cairo_destroy (cr);
		//cairo_surface_write_to_png (surface, "hello.png");
		//unsigned char* src = cairo_image_surface_get_data(surface);
		//unsigned char* dest = (irr::u8*)texture->lock();
		//if(dest)
//			memcpy(dest, src, tex_size.Height*tex_size.Width*4);
		texture->unlock();
		//cairo_surface_destroy (surface);
	}
}
The cairo code is basically copy and paste from the cairographics website. Basically the easiest way to integrate cairo with irrlicht, though probably not the most efficient.
Post Reply