Here is a sample program that shows the problem - it's a modification to the 13.RenderToTexture sample. If I run this and choose the software renderer I see a green background and a blue square with a white diagonal line across it. The white diagonal line is being drawn by directly writing to the render target texture. If I run this and choose DirectX the white diagonal line is missing. However - it's not that the texture failed to be locked - the pointer was generated okay and I'm drawing a white diagonal line to some piece of memory - just not anywhere that the DirectX driver pays attention to. I looked in the Irrlicht code, and there is a separate section for when lock() is called on a render target, which calls the D3D GetRenderTargetData() function - so it seems like it should work. Also, if I do this with an ordinary (non render-target) texture, it does work.
So my questions are:
1. Does anyone else see this behaviour?
2. If yes, is it a bug?
3. If yes is it likely to be fixed?
4. If no is there some other way to access the contents of a render target texture?
Code: Select all
#include <irrlicht.h>
#include <iostream>
using namespace irr;
#pragma comment(lib, "Irrlicht.lib")
int main()
{
video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
printf("Please select the driver you want for this example:\n"\
" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
" (d) Software Renderer\n (e) Burning's Software Renderer\n"\
" (f) NullDevice\n (otherKey) exit\n\n");
char i;
std::cin >> i;
switch(i)
{
case 'a': driverType = video::EDT_DIRECT3D9;break;
case 'b': driverType = video::EDT_DIRECT3D8;break;
case 'c': driverType = video::EDT_OPENGL; break;
case 'd': driverType = video::EDT_SOFTWARE; break;
case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
case 'f': driverType = video::EDT_NULL; break;
default: return 1;
}
IrrlichtDevice *device = createDevice(driverType, core::dimension2d<s32>(640, 480), 32, false, false);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
video::ITexture* rt = driver->createRenderTargetTexture(core::dimension2d<s32>(256,256));
while(device->run())
if (rt && device->isWindowActive())
{
driver->beginScene(true, true, 0);
// set render target texture (in order to change its color to blue)
driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));
// set back old render target (and clear it to green)
driver->setRenderTarget(0, true, true, video::SColor(0,0,255,0));
// draw a diagonal white line across the render target texture
int *ptr = (int *)rt->lock();
if( ptr )
{
printf("editing... " );
for(int i=0; i<255; ++i)
ptr[i + i*rt->getPitch()/4] = 0xFFFFFFFF;
rt->unlock();
}
// draw the render target texture on the screen.
driver->draw2DImage( rt, core::position2d<s32>(50,50), core::rect<s32>(0,0,256,256), 0, video::SColor(255,255,255,255), false );
driver->endScene();
}
if (rt)
rt->drop();
device->drop();
return 0;
}