#ifdef USE_D3D9
D3D9Texture::D3D9Texture()
{
_SurfaceTopLevel = NULL;
_Texture = NULL;
_SurfacePlain = NULL;
_Device = NULL;
_Width = 0;
_Height = 0;
_RenderTarget = false;
}
D3D9Texture::~D3D9Texture()
{
FreeMemory();
}
void D3D9Texture::FreeMemory()
{
ReleaseMemory();
if(_SurfacePlain != NULL)
{
D3DValidateRelease(_SurfacePlain);
_SurfacePlain = NULL;
}
_RenderTarget = false;
}
void D3D9Texture::ReleaseMemory()
{
if(_Texture != NULL)
{
ULONG References = _Texture->Release();
_Texture = NULL;
}
if(_SurfaceTopLevel != NULL)
{
D3DValidateRelease(_SurfaceTopLevel);
_SurfaceTopLevel = NULL;
}
_Width = 0;
_Height = 0;
}
void D3D9Texture::Init(GraphicsDevice &graphics)
{
_Device = graphics.CastD3D9().GetDevice();
}
void D3D9Texture::Reset(GraphicsDevice &graphics)
{
_Device = graphics.CastD3D9().GetDevice();
}
void D3D9Texture::UpdateMipMapLevels()
{
}
void D3D9Texture::Allocate(D3DFORMAT Format, UINT Width, UINT Height, bool RenderTarget, UINT MipmapLevels)
{
if(_Width != Width || _Height != Height || _Format != Format || _RenderTarget != RenderTarget)
{
FreeMemory();
PersistentAssert(_Device != NULL, "D3D9Texture not associated");
DWORD Usage = 0;
if(MipmapLevels != 1)
{
Usage |= D3DUSAGE_AUTOGENMIPMAP;
}
D3DPOOL Pool = D3DPOOL_MANAGED;
if(RenderTarget)
{
Usage |= D3DUSAGE_RENDERTARGET;
Pool = D3DPOOL_DEFAULT;
D3DAlwaysValidate(_Device->CreateOffscreenPlainSurface(Width, Height, Format, D3DPOOL_SYSTEMMEM, &_SurfacePlain, NULL), "CreateOffscreenPlainSurface");
}
D3DAlwaysValidate(_Device->CreateTexture(Width, Height, MipmapLevels, Usage, Format, Pool, &_Texture, NULL), "CreateTexture");
D3DValidate(_Texture->GetSurfaceLevel(0, &_SurfaceTopLevel), "GetSurfaceLevel");
_Width = Width;
_Height = Height;
_Format = Format;
_RenderTarget = RenderTarget;
}
}
void D3D9Texture::Clear()
{
_Device->ColorFill(_SurfaceTopLevel, NULL, D3DCOLOR_ARGB(0, 0, 0, 0));
}
void D3D9Texture::Load(const Bitmap &Bmp)
{
Allocate(D3DFMT_A8R8G8B8, Bmp.Width(), Bmp.Height(), false, 0);
D3DLOCKED_RECT Rect;
D3DValidate(_Texture->LockRect(0, &Rect, NULL, 0), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
RGBColor *CurRow = (RGBColor *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
RGBColor Color = Bmp[y][x];
CurRow[x] = RGBColor(Color.b, Color.g, Color.r, Color.a);
}
}
D3DValidate(_Texture->UnlockRect(0), "UnlockRect");
UpdateMipMapLevels();
}
void D3D9Texture::LoadFromFile(const String &filename, D3DFORMAT format)
{
FreeMemory();
D3DValidate(D3DXCreateTextureFromFileEx(_Device, filename.CString(), 0, 0, 0, 0, format, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &_Texture), "D3DXCreateTextureFromFileEx");
_Width = 1;
_Height = 1;
_Format = format;
_RenderTarget = false;
}
void D3D9Texture::Load(const Grid<float> &Data)
{
Allocate(D3DFMT_R32F, Data.Cols(), Data.Rows(), false, 0);
D3DLOCKED_RECT Rect;
D3DValidate(_Texture->LockRect(0, &Rect, NULL, 0), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
float *CurRow = (float *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
CurRow[x] = Data(y, x);
}
}
D3DValidate(_Texture->UnlockRect(0), "UnlockRect");
}
void D3D9Texture::Load(const Grid<Vec2f> &Data)
{
Allocate(D3DFMT_G32R32F, Data.Cols(), Data.Rows(), false, 0);
D3DLOCKED_RECT Rect;
D3DValidate(_Texture->LockRect(0, &Rect, NULL, 0), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
Vec2f *CurRow = (Vec2f *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
CurRow[x] = Data(y, x);
}
}
D3DValidate(_Texture->UnlockRect(0), "UnlockRect");
}
void D3D9Texture::Load(const Grid<Vec3f> &Data)
{
Allocate(D3DFMT_A32B32G32R32F, Data.Cols(), Data.Rows(), false, 0);
D3DLOCKED_RECT Rect;
D3DValidate(_Texture->LockRect(0, &Rect, NULL, 0), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
Vec4f *CurRow = (Vec4f *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
CurRow[x] = Vec4f(Data(y, x), 0.0f);
}
}
D3DValidate(_Texture->UnlockRect(0), "UnlockRect");
}
void D3D9Texture::Load(const Grid<Vec4f> &Data)
{
Allocate(D3DFMT_A32B32G32R32F, Data.Cols(), Data.Rows(), false, 0);
D3DLOCKED_RECT Rect;
D3DValidate(_Texture->LockRect(0, &Rect, NULL, 0), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
Vec4f *CurRow = (Vec4f *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
CurRow[x] = Data(y, x);
}
}
D3DValidate(_Texture->UnlockRect(0), "UnlockRect");
}
void D3D9Texture::Load(D3D9Texture &Tex)
{
D3DAlwaysValidate(_Device->StretchRect(Tex.SurfaceTopLevel(), NULL, _SurfaceTopLevel, NULL, D3DTEXF_POINT), "StretchRect");
}
void D3D9Texture::ReadData(Bitmap &Bmp)
{
PersistentAssert(_Width != 0 && _Height != 0 && _Format == D3DFMT_A8R8G8B8 && _RenderTarget, "ReadData called on invalid surface");
Bmp.Allocate(_Width, _Height);
D3DLOCKED_RECT Rect;
D3DAlwaysValidate(_Device->GetRenderTargetData(_SurfaceTopLevel, _SurfacePlain), "GetRenderTargetData");
D3DAlwaysValidate(_SurfacePlain->LockRect(&Rect, NULL, D3DLOCK_READONLY), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
RGBColor *CurRow = (RGBColor *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
Bmp[y][x] = CurRow[x];
}
}
D3DValidate(_SurfacePlain->UnlockRect(), "UnlockRect");
}
void D3D9Texture::ReadData(Grid<float> &Data)
{
PersistentAssert(_Width != 0 && _Height != 0 && _Format == D3DFMT_R32F, "ReadData called on invalid surface");
Data.Allocate(_Height, _Width);
D3DLOCKED_RECT Rect;
if(_RenderTarget)
{
D3DAlwaysValidate(_Device->GetRenderTargetData(_SurfaceTopLevel, _SurfacePlain), "GetRenderTargetData");
D3DAlwaysValidate(_SurfacePlain->LockRect(&Rect, NULL, D3DLOCK_READONLY), "LockRect");
}
else
{
D3DAlwaysValidate(_SurfaceTopLevel->LockRect(&Rect, NULL, D3DLOCK_READONLY), "LockRect");
}
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
float *CurRow = (float *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
Data(y, x) = CurRow[x];
}
}
if(_RenderTarget)
{
D3DValidate(_SurfacePlain->UnlockRect(), "UnlockRect");
}
else
{
D3DValidate(_SurfaceTopLevel->UnlockRect(), "UnlockRect");
}
}
void D3D9Texture::ReadData(Grid<Vec2f> &Data)
{
PersistentAssert(_Width != 0 && _Height != 0 && _Format == D3DFMT_G32R32F && _RenderTarget, "ReadData called on invalid surface");
Data.Allocate(_Height, _Width);
D3DLOCKED_RECT Rect;
D3DAlwaysValidate(_Device->GetRenderTargetData(_SurfaceTopLevel, _SurfacePlain), "GetRenderTargetData");
D3DAlwaysValidate(_SurfacePlain->LockRect(&Rect, NULL, D3DLOCK_READONLY), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
Vec2f *CurRow = (Vec2f *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
Data(y, x) = CurRow[x];
}
}
D3DValidate(_SurfacePlain->UnlockRect(), "UnlockRect");
}
void D3D9Texture::ReadData(Grid<Vec3f> &Data)
{
PersistentAssert(_Width != 0 && _Height != 0 && _Format == D3DFMT_A32B32G32R32F && _RenderTarget, "ReadData called on invalid surface");
Data.Allocate(_Height, _Width);
D3DLOCKED_RECT Rect;
D3DAlwaysValidate(_Device->GetRenderTargetData(_SurfaceTopLevel, _SurfacePlain), "GetRenderTargetData");
D3DAlwaysValidate(_SurfacePlain->LockRect(&Rect, NULL, D3DLOCK_READONLY), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
Vec4f *CurRow = (Vec4f *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
Data(y, x) = Vec3f(CurRow[x].x, CurRow[x].y, CurRow[x].z);
}
}
D3DValidate(_SurfacePlain->UnlockRect(), "UnlockRect");
}
void D3D9Texture::ReadData(Grid<Vec4f> &Data)
{
PersistentAssert(_Width != 0 && _Height != 0 && _Format == D3DFMT_A32B32G32R32F && _RenderTarget, "ReadData called on invalid surface");
Data.Allocate(_Height, _Width);
D3DLOCKED_RECT Rect;
D3DAlwaysValidate(_Device->GetRenderTargetData(_SurfaceTopLevel, _SurfacePlain), "GetRenderTargetData");
D3DAlwaysValidate(_SurfacePlain->LockRect(&Rect, NULL, D3DLOCK_READONLY), "LockRect");
BYTE *Bytes = (BYTE *)Rect.pBits;
for(UINT y = 0; y < _Height; y++)
{
Vec4f *CurRow = (Vec4f *)(Bytes + y * Rect.Pitch);
for(UINT x = 0; x < _Width; x++)
{
Data(y, x) = CurRow[x];
}
}
D3DValidate(_SurfacePlain->UnlockRect(), "UnlockRect");
}
void D3D9Texture::Flush()
{
PersistentAssert(_Width != 0 && _Height != 0 && _Format == D3DFMT_A32B32G32R32F && _RenderTarget, "ReadData called on invalid surface");
D3DLOCKED_RECT Rect;
D3DAlwaysValidate(_Device->GetRenderTargetData(_SurfaceTopLevel, _SurfacePlain), "GetRenderTargetData");
D3DAlwaysValidate(_SurfacePlain->LockRect(&Rect, NULL, D3DLOCK_READONLY), "LockRect");
D3DValidate(_SurfacePlain->UnlockRect(), "UnlockRect");
}
void D3D9Texture::Set(int Index)
{
Assert(_Texture != NULL, "SetTexture called on empty texture");
_Device->SetTexture(Index, _Texture);
}
void D3D9Texture::SetAsRenderTarget(int Index)
{
Assert(_Texture != NULL && _RenderTarget, "SetAsRenderTarget on invalid texture");
D3DValidate(_Device->SetRenderTarget(Index, _SurfaceTopLevel), "SetRenderTarget");
}
void D3D9Texture::SetNull(int Index)
{
_Device->SetTexture(Index, NULL);
}
#endif