[no bug]RTT's on D3D9 without drawing something first

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

[no bug]RTT's on D3D9 without drawing something first

Post by CuteAlien »

When using rendertarget textures with the EDT_DIRECT3D9 driver I have to draw something (anything) first with the driver. If I try to use them before having drawn anything I get just black textures as result.

Problem is reproducible in Irrlicht trunk and Irrlicht 1.8. It works correct with OpenGL.
I stepped through my test-code below while having 2 Visual Studio versions parallel open - one with working and one with failing version. But I couldn't find any place where the runtime behaviour was different aside from the failing version returning a black texture.

If anyone has a clue what could be the problem I'd be glad to hear about it.

To enable the bug set the place with "#if 1" to "#if 0".

Code: Select all

 
// TEST to debug a problem with rtt and d3d9
 
#include <irrlicht.h>
 
using namespace irr;
 
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif
 
// Create a rtt, draw something into it and copy resulting image to a newly created texture
irr::video::ITexture* drawIntoTexture(irr::video::IVideoDriver * driver)
{
    irr::core::dimension2d<irr::u32> texdim(64, 64);
 
    // set rt
    irr::video::ITexture * rtTex = driver->addRenderTargetTexture(texdim, "rtTxt", irr::video::ECF_A8R8G8B8);
    driver->setRenderTarget(rtTex, irr::video::ECBF_COLOR|irr::video::ECBF_DEPTH, irr::video::SColor(0,0,0,0));
 
    // draw some X into the texture
    driver->draw2DLine( irr::core::vector2di(0,0), irr::core::vector2di(texdim.Width,texdim.Height), irr::video::SColor(255,127,127,255));
    driver->draw2DLine( irr::core::vector2di(texdim.Width,0), irr::core::vector2di(0,texdim.Height), irr::video::SColor(255,127,127,255));
 
    // reset rt
    driver->setRenderTarget((irr::video::ITexture *)nullptr, irr::video::ECBF_COLOR|irr::video::ECBF_DEPTH);
 
    // Don't use rt directly as rtt's are reset on resize
    // But that part doesn't matter - the rtt is already getting a black texture (have debugged memory directly)
    irr::video::IImage * img = driver->createImage (rtTex, irr::core::position2di(0,0), rtTex->getSize());
    driver->removeTexture(rtTex);
    irr::video::ITexture*  result = driver->addTexture("texture", img);
 
    img->drop();
 
    return result;
}
 
int main()
{
    video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9; // works with opengl
    IrrlichtDevice *device = createDevice(driverType, core::dimension2d<u32>(640, 480), 16, false, false);
    if (device == 0)
        return 1; // could not create selected driver.
 
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();
 
    // add camera
    scene::ICameraSceneNode* cam = smgr->addCameraSceneNode();
    cam->setPosition(core::vector3df(-50,50,-150));
 
    // create test cube
    scene::ISceneNode* test = smgr->addCubeSceneNode(60);
    test->setPosition(core::vector3df(-10,0,-10));
    test->setMaterialFlag(video::EMF_LIGHTING, false); // disable dynamic lighting
 
#if 1   // BUG: when set to 0 the rtt no longer works
    // We have to draw something once to get rtt working on D3D9 
    driver->beginScene(true, true, irr::video::SColor(0x00FFFFFF));
    driver->draw3DLine( core::vector3df(0,0,0), core::vector3df(1,1,1));    // 2d or 3d doesn't matter
    //driver->draw2DLine( irr::core::vector2di(0,0), irr::core::vector2di(10,10), irr::video::SColor(255,127,127,255));
    driver->endScene();
#endif
 
    // set cube texture to texture created from rtt
    test->setMaterialTexture(0, drawIntoTexture(driver));
 
    // just draw the cube
    while(device->run())
    {
        driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0));
        smgr->drawAll();
        driver->endScene();
        device->sleep(10);
    }
 
    device->drop(); // drop device
    return 0;
}
 
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
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Can't use RTT's on D3D9 without drawing something first

Post by hendu »

RTT drawing, just like any drawing, must be inside beginScene and endScene, no? That GL happens to work without is just coincidence.
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Can't use RTT's on D3D9 without drawing something first

Post by CuteAlien »

Hm, probably you are right. It always seemed to work without beginScene/endScene, so I thought maybe setRenderTarget would replace it as it has similar parameters to beginScene(). Have to investigate this a little bit next week. If that's the case I'll have to check if beginScene()/endScene() can be nested, otherwise some of my code might become more complicated.
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
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Re: Can't use RTT's on D3D9 without drawing something first

Post by hendu »

I don't think they can be nested. Any wrappers just need to document that their draw calls must also be inside that.
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Can't use RTT's on D3D9 without drawing something first

Post by CuteAlien »

Yeah, but sometimes not so nice. Maybe we need a function to tell if we are currently inside beginScene/endScene.
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
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [no bug]RTT's on D3D9 without drawing something first

Post by CuteAlien »

*sigh* - guess in the end caching stuff with rtt's while loading is simply a bad idea.
So yeah - beginScene/endScene pair should never be avoided. The reason it sometimes still worked... doesn't really matter, just shouldn't be done.
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
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: [no bug]RTT's on D3D9 without drawing something first

Post by Mel »

But if for any obscure reason we wanted to lock the RTT to write them directly, would that still be possible? I am aware of the performance penalty, but just out of curiosity
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [no bug]RTT's on D3D9 without drawing something first

Post by CuteAlien »

Sorry, I don't know details about locking - Nadro just rewrote that part, he would know more about it...
But I think beginScene/endScene is only for drawing.
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
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: [no bug]RTT's on D3D9 without drawing something first

Post by Nadro »

AFAIK CuteAlien is right, begin/end scene is just for drawing, so you can still lock/unlock RT textures.
guess in the end caching stuff with rtt's while loading is simply a bad idea.
In OpenGL we use RTT (FBO) to download texture from GPU to CPU (in OpenGL ES 2.0 it's the only possible way), so this is similar situation.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: [no bug]RTT's on D3D9 without drawing something first

Post by CuteAlien »

@Nadro: So the new lock() on OpenGL has to be inside beginscene/endscene?
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
Nadro
Posts: 1648
Joined: Sun Feb 19, 2006 9:08 am
Location: Warsaw, Poland

Re: [no bug]RTT's on D3D9 without drawing something first

Post by Nadro »

No, in OpenGL we don't need anything like a begin/end scene, thats why it works in all cases.
Library helping with network requests, tasks management, logger etc in desktop and mobile apps: https://github.com/GrupaPracuj/hermes
Post Reply