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?
ITexture::lock() and update too slow?
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
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.
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.
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)
}
}
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);
}
}