Page 1 of 1

Drawing an image onto a texture

Posted: Sat Jun 16, 2007 3:39 pm
by xDan
Hi,

I can see I *could* do this with the lock() functions and making my own drawing function but before I try it are there any functions hidden away to do this? Or has anyone already wrote code to do it?

This sort of thing:
drawOnTexture(texture, image, position, rotation, scale)

Thanks

Posted: Sat Jun 16, 2007 8:16 pm
by LLDD
Look at the RTT (render to texture) example.

Basically you have to do:

1) Create a render texture:

Code: Select all

ITexture *RT = driver->createRenderTargetTexture(dimension2d<s32>(X,Y));
2) Set the texture as render target:

Code: Select all

driver->setRenderTarget(RT, true, true, SColor(0,0,0,0)); 
3) Draw calls.
________
NEVADA MARIJUANA DISPENSARIES

Posted: Sun Jun 17, 2007 8:47 am
by hybrid
If you want to use the 2d or 3d drawing method of Irrlicht you have to use the render target textures. If you just want to do some bitmap copying you should look into CColorConvert. There are routines to copy portions of images into others. So you have to lock both images/textures and call those methods until all lines (typically used, otherwise you need the same pitch in both images) are copied. The next release will have a method where you can specify the source and destination image formats to get the correct basic method automatically.

Posted: Mon Jun 18, 2007 7:44 pm
by xDan
Render to texture looks like the thing I need. Thanks!

Posted: Sat Jun 23, 2007 5:17 pm
by xDan
Hi again!

I call this code every time I click the mouse:

Code: Select all

            driver->setRenderTarget(rt);
            driver->beginScene(false, false, video::SColor(0,0,0,0));
            driver->draw2DImage(texture, core::position2d<s32>(rand()%512,rand()%512));
            driver->endScene();
            driver->setRenderTarget(0);
The desired behaviour is that the drawn texture remains after each click (for a decal sort of effect). But instead the render target texture is cleared to black before each rendering (so just the most recent decal is shown).

I thought setting the "clear the backBuffer" to false is what I needed but seems not. How can I fix this?

Posted: Sat Jun 23, 2007 9:59 pm
by xDan
OK so I've done this by having two RTTs and swapping them:

initialisation

Code: Select all

    wallRTT1 = driver->createRenderTargetTexture(core::dimension2d<s32>(512,512));
    wallRTT2 = driver->createRenderTargetTexture(core::dimension2d<s32>(512,512));
    driver->setRenderTarget(wallRTT1);
    driver->beginScene(true, true, video::SColor(0,0,0,0));
    // render original texture to RTT1
    driver->draw2DImage(wallsSceneNode->getMaterial(0).Textures[0], core::position2d<s32>(0,0));
    driver->endScene();
    driver->setRenderTarget(0);
    // set wall texture to RTT
    wallsSceneNode->getMaterial(0).Textures[0] = wallRTT1;
drawing onto it

Code: Select all

    // swap RTTs
    video::ITexture *tempRTT = wallRTT1;
    wallRTT1 = wallRTT2;
    wallRTT2 = tempRTT;
    // rendering
    driver->setRenderTarget(wallRTT1);
    driver->beginScene(false, false, video::SColor(0,0,0,0));
    // draw old render
    driver->draw2DImage(wallRTT2, core::position2d<s32>(0,0));
    // render blood splat with transparency
    int w = texture->getOriginalSize().Width;
    int h = texture->getOriginalSize().Height;
    int x = rand()%512;
    int y = rand()%512;
    driver->draw2DImage(texture,
        core::rect<s32>(x,y,x+w,y+h),
        core::rect<s32>(0,0,w,h),
        0,0,true);
    driver->endScene();
    driver->setRenderTarget(0);
    // set to new RTT
    wallsSceneNode->getMaterial(0).Textures[0] = wallRTT1;
EDIT: Note, there should only be one begin/endScene pair called per frame. So put any rendering to textures within the same block you do the rest of your drawing.