This is how to modify the engine (0.14.0) so that you can use ITexture::lock() on textures created with IVideoDriver::createRenderTargetTexture().
Direct3D9
CD3D9Texture.h <-- URL to updated file
In the class definition, add a protected IDirect3DSurface9 member
Code: Select all
IImage* Image;
IDirect3DDevice9* Device;
IDirect3DTexture9* Texture;
IDirect3DSurface9* RTTSurface;
core::dimension2d<s32> TextureSize;
core::dimension2d<s32> ImageSize;
s32 Pitch;
ECOLOR_FORMAT ColorFormat;
In both constructors add
Code: Select all
RTTSurface = NULL;
Code: Select all
//! rendertarget constructor
CD3D9Texture::CD3D9Texture(IDirect3DDevice9* device, core::dimension2d<s32> size)
: Image(0), Device(device), TextureSize(size),
Texture(0), Pitch(0), ImageSize(size), HasMipMaps(0), HardwareMipMaps(0),
IsRenderTarget(true)
{
RTTSurface = NULL;
#ifdef _DEBUG
setDebugName("CD3D9Texture");
#endif
if (Device)
Device->AddRef();
createRenderTarget();
}
//! constructor
CD3D9Texture::CD3D9Texture(IImage* image, IDirect3DDevice9* device,
u32 flags)
: Image(image), Device(device), TextureSize(0,0),
Texture(0), Pitch(0), ImageSize(0,0), HasMipMaps(false), HardwareMipMaps(false),
IsRenderTarget(false)
{
RTTSurface = NULL;
#ifdef _DEBUG
setDebugName("CD3D9Texture");
#endif
...
Code: Select all
//! destructor
CD3D9Texture::~CD3D9Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
Code: Select all
//! lock function
void* CD3D9Texture::lock()
{
if (!Texture)
return 0;
HRESULT hr;
D3DLOCKED_RECT rect;
if(!IsRenderTarget)
{
hr = Texture->LockRect(0, &rect, 0, 0);
}
else
{
D3DSURFACE_DESC desc;
Texture->GetLevelDesc(0, &desc);
if (RTTSurface == NULL)
{
hr = Device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &RTTSurface, NULL);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0;
}
}
IDirect3DSurface9 *surface = NULL;
hr = Texture->GetSurfaceLevel(0, &surface);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0;
}
hr = Device->GetRenderTargetData(surface, RTTSurface);
if(FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0;
}
hr = RTTSurface->LockRect(&rect, NULL, 0);
if(FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0;
}
return rect.pBits;
}
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR);
return 0;
}
return rect.pBits;
}
Code: Select all
//! unlock function
void CD3D9Texture::unlock()
{
if (!Texture)
return;
if (!IsRenderTarget)
Texture->UnlockRect(0);
else if (RTTSurface)
RTTSurface->UnlockRect();
return NULL;
}
Direct3D8
Updating the Direct3D8 texture is the same but some functions are different and of course you need to use an 8 instead of 9 in interfaces.
CD3D8Texture.h <-- URL to updated file
In the class definition, add a protected IDirect3DSurface8 member
Code: Select all
IImage* Image;
IDirect3DDevice8* Device;
IDirect3DTexture8* Texture;
IDirect3DSurface8* RTTSurface;
core::dimension2d<s32> TextureSize;
core::dimension2d<s32> ImageSize;
s32 Pitch;
ECOLOR_FORMAT ColorFormat;
In both constructors add
Code: Select all
RTTSurface = NULL;
Code: Select all
//! rendertarget constructor
CD3D8Texture::CD3D8Texture(IDirect3DDevice8* device, core::dimension2d<s32> size)
: Image(0), Device(device), TextureSize(size),
Texture(0), Pitch(0), ImageSize(size), HasMipMaps(0),
IsRenderTarget(true)
{
RTTSurface = NULL;
#ifdef _DEBUG
setDebugName("CD3D8Texture");
#endif
if (Device)
Device->AddRef();
createRenderTarget();
}
//! constructor
CD3D8Texture::CD3D8Texture(IImage* image, IDirect3DDevice8* device,
u32 flags)
: Image(image), Device(device), TextureSize(0,0),
Texture(0), Pitch(0), ImageSize(0,0), HasMipMaps(false), IsRenderTarget(false)
{
RTTSurface = NULL;
#ifdef _DEBUG
setDebugName("CD3D8Texture");
#endif
...
Code: Select all
//! destructor
CD3D8Texture::~CD3D8Texture()
{
if (Device)
Device->Release();
if (Image)
Image->drop();
if (Texture)
Texture->Release();
if (RTTSurface)
RTTSurface->Release();
}
Code: Select all
//! lock function
void* CD3D8Texture::lock()
{
if (!Texture)
return 0;
HRESULT hr;
D3DLOCKED_RECT rect;
if(!IsRenderTarget)
{
hr = Texture->LockRect(0, &rect, 0, 0);
}
else
{
D3DSURFACE_DESC desc;
Texture->GetLevelDesc(0, &desc);
if (RTTSurface == NULL)
{
hr = Device->CreateImageSurface(desc.Width, desc.Height, desc.Format, &RTTSurface);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
}
IDirect3DSurface8 *surface = NULL;
hr = Texture->GetSurfaceLevel(0, &surface);
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
hr = Device->CopyRects(surface, NULL, 0, RTTSurface, NULL);
if(FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
hr = RTTSurface->LockRect(&rect, NULL, 0);
if(FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
return rect.pBits;
}
if (FAILED(hr))
{
os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR);
return 0;
}
return rect.pBits;
}
Code: Select all
//! unlock function
void CD3D8Texture::unlock()
{
if (!Texture)
return;
if (!IsRenderTarget)
Texture->UnlockRect(0);
else if (RTTSurface)
RTTSurface->UnlockRect();
return NULL;
}
// cheers and good luck!