#include "dxstdafx.h"
#include "TargetableTexture.h"

#pragma once


//------------------------------------------------------------------------------------------
// Constructor
//------------------------------------------------------------------------------------------
TargetableTexture::TargetableTexture()
{
	// Just setting the pointers to null
	m_pRTTexture = NULL;
	m_pRTSurface = NULL;
	m_bMultisampled = false;
}


//--------------------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------------------
TargetableTexture::~TargetableTexture()
{
	ReleaseAll();
}


//--------------------------------------------------------------------------------------
// Init a texture and its surface pointer
//--------------------------------------------------------------------------------------
HRESULT TargetableTexture::Init(const UINT Width, const UINT Height, const D3DFORMAT Format)
{
	HRESULT hr;

	// Device cheking
	LPDIRECT3DDEVICE9 pd3dDevice = DXUTGetD3DDevice();
	if(!pd3dDevice) return D3DERR_INVALIDDEVICE;
	
	// Retrieve the current present parameters
	D3DPRESENT_PARAMETERS PresentParams = DXUTGetPresentParameters();
	m_bMultisampled = (PresentParams.MultiSampleType)? true:false;
	
	// Release the current texture if exists
	if(m_pRTTexture) SAFE_RELEASE(m_pRTTexture);

	// Creating the new render target
	V_RETURN(pd3dDevice->CreateTexture(Width, Height, 1, D3DUSAGE_RENDERTARGET , Format, D3DPOOL_DEFAULT, &(m_pRTTexture), NULL));
	
	// Depending on the Multisample type...
	if(!m_bMultisampled)
	{
		// No multisampling we can directly retrieve a pointer on the Render Target Usage texture surface
		return m_pRTTexture->GetSurfaceLevel(0, &(m_pRTSurface));
	}
	else
	{
		// Multisampling, We create a DYNAMIC texture and we must create another render target with the current multisample settings
		return pd3dDevice->CreateRenderTarget(Width, Height, Format, PresentParams.MultiSampleType, PresentParams.MultiSampleQuality, FALSE, &m_pRTSurface, NULL);
	}
}


//--------------------------------------------------------------------------------------
// Release the surface and the texture
//--------------------------------------------------------------------------------------
void TargetableTexture::ReleaseAll()
{
	SAFE_RELEASE(m_pRTSurface);
	SAFE_RELEASE(m_pRTTexture);	
}


//--------------------------------------------------------------------------------------
// Un-multisample the texture surface by copying it with stretchrect
//--------------------------------------------------------------------------------------
HRESULT TargetableTexture::CopyNonMultisampledSurfacetToTexture()
{
	HRESULT hr;

	// Checking first if we really need to excute this function
	if(!m_bMultisampled) return D3D_OK;	// We return OK since it's a normal event

	// Device cheking
	LPDIRECT3DDEVICE9 pd3dDevice = DXUTGetD3DDevice();
	if(!pd3dDevice) return D3DERR_INVALIDDEVICE;

	// We retrieve the texture surface (which is in fact our multisampled RT)
	LPDIRECT3DSURFACE9 pTextureSurface;
	V_RETURN(m_pRTTexture->GetSurfaceLevel(0, &pTextureSurface));

	// Fill it with a non multisampled version of m_pRTSurface thanks to the power of StretchRect
	V_RETURN(pd3dDevice->StretchRect(m_pRTSurface, NULL, pTextureSurface, NULL, D3DTEXF_POINT));

	//D3DXSaveSurfaceToFile(L"test.dds", D3DXIFF_DDS, pTextureSurface, NULL, NULL);

	// Release our temporary surface pointer
	return pTextureSurface->Release();
}


















































