// TextureRenderer.cpp: implementation of the CTextureRenderer class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TextureRenderer.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CTextureRenderer::CTextureRenderer( PDIRECT3DDEVICE8 pDevice, BOOL useZBuffer, DWORD width, DWORD height, D3DFORMAT format, D3DFORMAT zformat )
{
	if( !pDevice )
		throw CSystemException( DEMO_EXCEPTION_NULLPOINTER, "CTextureRenderer: null pointer device" );

	m_ptextTarget = NULL;
	m_psurfTargetZbuffer = NULL;
	m_psurfPrevTarget = NULL;
	m_psurfPrevZbuffer = NULL;

	if( FAILED( pDevice->CreateTexture( width, height, 1, D3DUSAGE_RENDERTARGET, format, D3DPOOL_DEFAULT, &m_ptextTarget ) ) )
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "CTextureRenderer: unable to create texture target" );

	if( useZBuffer )
	{		
		if( FAILED( pDevice->CreateDepthStencilSurface( width, height, zformat, D3DMULTISAMPLE_NONE, &m_psurfTargetZbuffer ) ) )
			throw CSystemException( DEMO_EXCEPTION_D3DERROR, "CTextureRenderer: unable to create zbuffer for target surface" );
	}

	m_bSet = FALSE;
}

CTextureRenderer::~CTextureRenderer()
{
	if( m_bSet )	
		throw CSystemException( DEMO_EXCEPTION_D3DERROR, "CTextureRenderer: trying to free target texture when still assigned to device" );

	if( m_ptextTarget )
		m_ptextTarget->Release();
	
	if( m_psurfTargetZbuffer )
		m_psurfTargetZbuffer->Release();		
}

BOOL CTextureRenderer::SetTarget( PDIRECT3DDEVICE8 pDevice )
{	
	if( m_bSet )
		return TRUE;

	LPDIRECT3DSURFACE8		psurf;

	if( FAILED( m_ptextTarget->GetSurfaceLevel( 0, &psurf ) ) )
		return FALSE;

	if( FAILED( pDevice->GetRenderTarget( &m_psurfPrevTarget ) ) )
		return FALSE;

	if( FAILED( pDevice->GetDepthStencilSurface( &m_psurfPrevZbuffer ) ) )
		return FALSE;

	if( FAILED( pDevice->SetRenderTarget( psurf, m_psurfTargetZbuffer ) ) )
		return FALSE;
	
	if( m_psurfPrevTarget )
		m_psurfPrevTarget->Release();

	if( m_psurfPrevZbuffer )
		m_psurfPrevZbuffer->Release();

	psurf->Release();
	
	m_bSet = TRUE;

	return TRUE;
}

BOOL CTextureRenderer::RestoreTarget( PDIRECT3DDEVICE8 pDevice )
{
	if( !m_bSet )
		return TRUE;	

	if( FAILED( pDevice->SetRenderTarget( m_psurfPrevTarget, m_psurfPrevZbuffer ) ) )
		return FALSE;	

	m_bSet = FALSE;

	return TRUE;
}

PDIRECT3DTEXTURE8 CTextureRenderer::GetTargetTexture()
{
	return m_ptextTarget;
}
