www.pudn.com > RNL.rar > RNL.CPP


////////////////////////////////////////////////////////////////////// 
// Name		: RNL.cpp 
// Author	: Anirudh S Shastry. Copyright ?2003. 
// Date		: 28-12-2003, Sunday. 
// Desc		: Rendering with Natural Light. 
////////////////////////////////////////////////////////////////////// 
 
#define STRICT 
#define WIN32_LEAN_AND_MEAN 
 
#include  
#include  
#include  
#include  
#include  
#include "rgbe.h" 
 
#define SAFE_RELEASE( x ) { if( x != NULL ) { x->Release(); x = NULL; } } 
 
////////////////////////////////////////////////////////////////////// 
// Global variables 
////////////////////////////////////////////////////////////////////// 
 
HWND					g_hWnd			= NULL; 
LPDIRECT3D9				g_pd3d			= NULL; 
LPDIRECT3DDEVICE9		g_pd3dDevice	= NULL; 
 
LPDIRECT3DVERTEXBUFFER9	g_pQuadBuffer	= NULL; 
LPDIRECT3DVERTEXBUFFER9	g_pHalfBuffer	= NULL; 
LPDIRECT3DVERTEXBUFFER9	g_pFullBuffer	= NULL; 
 
LPDIRECT3DTEXTURE9		g_pQuadTexture	= NULL; 
 
#define FORMAT64		D3DFMT_A16B16G16R16F 
#define FORMAT128		D3DFMT_A32B32G32R32F 
 
LPDIRECT3DSURFACE9		g_pBackBuffer	= NULL; 
LPDIRECT3DTEXTURE9		g_pFullTexture	= NULL; 
LPDIRECT3DSURFACE9		g_pFullSurface	= NULL; 
LPDIRECT3DTEXTURE9		g_pDownSampleTexture	= NULL; 
LPDIRECT3DSURFACE9		g_pDownSampleSurface	= NULL; 
LPDIRECT3DTEXTURE9		g_pBlurXTexture	= NULL; 
LPDIRECT3DSURFACE9		g_pBlurXSurface	= NULL; 
LPDIRECT3DTEXTURE9		g_pBlurYTexture	= NULL; 
LPDIRECT3DSURFACE9		g_pBlurYSurface	= NULL; 
 
LPD3DXEFFECT			g_pDownSample	= NULL; 
LPD3DXEFFECT			g_pBlurX		= NULL; 
LPD3DXEFFECT			g_pBlurY		= NULL; 
LPD3DXEFFECT			g_pToneMapping	= NULL; 
 
LPDIRECT3DSURFACE9 g_pScreenshot = NULL; 
int g_iScreenshot = 0; 
char* g_cScreenshot = new char; 
 
D3DXMATRIX	g_matWorld, g_matView, g_matProj; 
float	g_fSpinX_L	= 0.0f; 
float	g_fSpinY_L	= 0.0f; 
float	g_fSpinX_R	= 0.0f; 
float	g_fSpinY_R	= 0.0f; 
 
DWORD	g_dwFrames		= 0; 
float	g_fStartTime	= 0.0f; 
float	g_fEndTime		= 0.0f; 
 
float	g_fExposureLevel = 2.5f; 
bool	g_bVaryExposure	 = true; 
 
int g_iWidth	= 0; 
int g_iHeight	= 0; 
 
#define D3DFVF_QUADVERTEX ( D3DFVF_XYZ | D3DFVF_TEX1 ) 
 
struct QuadVertex 
{ 
	float x, y, z; 
	float tu, tv; 
}; 
#define D3DFVF_SCREENVERTEX ( D3DFVF_XYZRHW | D3DFVF_TEX1 ) 
 
struct ScreenVertex 
{ 
	float x, y, z, rhw; 
	float tu, tv; 
}; 
 
////////////////////////////////////////////////////////////////////// 
// Prototypes 
////////////////////////////////////////////////////////////////////// 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,  
				   LPSTR lpCmdLine, int nCmdShow); 
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 
void init(void); 
void initTextures( void ); 
void initRTS( void ); 
void initEffects( void ); 
void setEffectParams( void ); 
void shutDown(void); 
void render(void); 
void screenGrab( void ); 
 
////////////////////////////////////////////////////////////////////// 
// Name: WinMain() 
// Desc: The application's entry point 
////////////////////////////////////////////////////////////////////// 
int WINAPI WinMain(	HINSTANCE hInstance, 
					HINSTANCE hPrevInstance, 
					LPSTR     lpCmdLine, 
					int       nCmdShow ) 
{ 
	WNDCLASSEX winClass; 
	MSG        uMsg; 
 
    memset(&uMsg,0,sizeof(uMsg)); 
     
	winClass.lpszClassName = "RNL_WINDOWS_CLASS"; 
	winClass.cbSize        = sizeof(WNDCLASSEX); 
	winClass.style         = CS_HREDRAW | CS_VREDRAW; 
	winClass.lpfnWndProc   = WindowProc; 
	winClass.hInstance     = hInstance; 
	winClass.hIcon	       = LoadIcon(hInstance, NULL); 
    winClass.hIconSm	   = LoadIcon(hInstance, NULL); 
	winClass.hCursor       = LoadCursor(NULL, IDC_ARROW); 
	winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); 
	winClass.lpszMenuName  = NULL; 
	winClass.cbClsExtra    = 0; 
	winClass.cbWndExtra    = 0; 
 
	if(!RegisterClassEx( &winClass) ) 
		return E_FAIL; 
 
	g_hWnd = CreateWindowEx( NULL, "RNL_WINDOWS_CLASS", "Rendering With Natural Light", 
						     WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
					         0, 0, 1024, 768, NULL, NULL, hInstance, NULL ); 
	 
	if( g_hWnd == NULL ) 
		return E_FAIL; 
 
    ShowWindow( g_hWnd, nCmdShow ); 
    UpdateWindow( g_hWnd ); 
 
	init(); 
 
	g_fStartTime = timeGetTime() * 0.001f; 
 
	while( uMsg.message != WM_QUIT ) 
	{ 
		if( PeekMessage( &uMsg, NULL, 0, 0, PM_REMOVE ) ) 
		{  
			TranslateMessage( &uMsg ); 
			DispatchMessage( &uMsg ); 
		} 
        else 
		{ 
			render(); 
			if( ( ( timeGetTime() * 0.001f ) - g_fStartTime ) > 25.0f ) 
				PostQuitMessage( 0 ); 
		} 
	} 
 
	g_fEndTime = timeGetTime() * 0.001f; 
 
	float fFPS = (float)g_dwFrames / ( g_fEndTime - g_fStartTime ); 
	char strFPS[255]; 
	sprintf( strFPS, "FPS : %f", fFPS ); 
	MessageBox( g_hWnd, strFPS, "Hello", MB_OK ); 
 
	shutDown(); 
 
    UnregisterClass( "RNL_WINDOWS_CLASS", winClass.hInstance ); 
 
	return uMsg.wParam; 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: WindowProc() 
// Desc: The window's message handler 
////////////////////////////////////////////////////////////////////// 
LRESULT CALLBACK WindowProc( HWND   hWnd,  
							 UINT   msg,  
							 WPARAM wParam,  
							 LPARAM lParam ) 
{ 
	static POINT ptLastMousePosit_L; 
	static POINT ptCurrentMousePosit_L; 
	static bool  bMousing_L; 
	 
	static POINT ptLastMousePosit_R; 
	static POINT ptCurrentMousePosit_R; 
	static bool  bMousing_R; 
 
    switch( msg ) 
	{ 
        case WM_KEYDOWN: 
		{ 
			switch( wParam ) 
			{ 
				case VK_ESCAPE: 
					PostQuitMessage(0); 
					break; 
				case VK_SPACE: 
					screenGrab(); 
					break; 
			} 
		} 
        break; 
 
		case WM_LBUTTONDOWN: 
		{ 
			ptLastMousePosit_L.x = ptCurrentMousePosit_L.x = LOWORD (lParam); 
            ptLastMousePosit_L.y = ptCurrentMousePosit_L.y = HIWORD (lParam); 
			bMousing_L = true; 
		} 
		break; 
 
		case WM_LBUTTONUP: 
		{ 
			bMousing_L = false; 
		} 
		break; 
 
		case WM_RBUTTONDOWN: 
		{ 
			ptLastMousePosit_R.x = ptCurrentMousePosit_R.x = LOWORD (lParam); 
            ptLastMousePosit_R.y = ptCurrentMousePosit_R.y = HIWORD (lParam); 
			bMousing_R = true; 
		} 
		break; 
 
		case WM_RBUTTONUP: 
		{ 
			bMousing_R = false; 
		} 
		break; 
 
		case WM_MOUSEMOVE: 
		{ 
			ptCurrentMousePosit_L.x = LOWORD (lParam); 
			ptCurrentMousePosit_L.y = HIWORD (lParam); 
			ptCurrentMousePosit_R.x = LOWORD (lParam); 
			ptCurrentMousePosit_R.y = HIWORD (lParam); 
 
			if( bMousing_L ) 
			{ 
				g_fSpinX_L -= (ptCurrentMousePosit_L.x - ptLastMousePosit_L.x); 
				g_fSpinY_L -= (ptCurrentMousePosit_L.y - ptLastMousePosit_L.y); 
			} 
			 
			if( bMousing_R ) 
			{ 
				g_fSpinX_R -= (ptCurrentMousePosit_R.x - ptLastMousePosit_R.x); 
				g_fSpinY_R -= (ptCurrentMousePosit_R.y - ptLastMousePosit_R.y); 
			} 
 
			ptLastMousePosit_L.x = ptCurrentMousePosit_L.x; 
            ptLastMousePosit_L.y = ptCurrentMousePosit_L.y; 
			ptLastMousePosit_R.x = ptCurrentMousePosit_R.x; 
            ptLastMousePosit_R.y = ptCurrentMousePosit_R.y; 
		} 
		break; 
		 
		case WM_CLOSE: 
		{ 
			PostQuitMessage(0);	 
		} 
		break; 
 
        case WM_DESTROY: 
		{ 
            PostQuitMessage(0); 
		} 
        break; 
		 
		default: 
		{ 
			return DefWindowProc( hWnd, msg, wParam, lParam ); 
		} 
		break; 
	} 
 
	return 0; 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: init() 
// Desc: Initializes D3D 
////////////////////////////////////////////////////////////////////// 
 
void init( void ) 
{ 
    g_pd3d = Direct3DCreate9( D3D_SDK_VERSION ); 
 
    D3DDISPLAYMODE d3ddm; 
 
    g_pd3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ); 
 
    D3DPRESENT_PARAMETERS d3dpp; 
    ZeroMemory( &d3dpp, sizeof(d3dpp) ); 
 
    d3dpp.Windowed               = TRUE; 
    d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD; 
    d3dpp.BackBufferFormat       = d3ddm.Format; 
    d3dpp.EnableAutoDepthStencil = TRUE; 
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
 
    g_pd3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, 
		D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, 
                          &d3dpp, &g_pd3dDevice ); 
 
	QuadVertex g_QuadVertices[] =  
	{ 
		{ -1.5f,  1.5f,  0.0f,  0.0f,  0.0f, }, 
		{  1.5f,  1.5f,  0.0f,  1.0f,  0.0f, }, 
		{ -1.5f, -1.5f,  0.0f,  0.0f,  1.0f, }, 
		{  1.5f, -1.5f,  0.0f,  1.0f,  1.0f, }, 
	}; 
 
	g_pd3dDevice->CreateVertexBuffer( 4 * sizeof(QuadVertex),0, D3DFVF_QUADVERTEX, 
                                      D3DPOOL_DEFAULT, &g_pQuadBuffer, NULL ); 
	void *pVertices = NULL; 
 
    g_pQuadBuffer->Lock( 0, sizeof(g_QuadVertices), (void**)&pVertices, 0 ); 
    memcpy( pVertices, g_QuadVertices, sizeof(g_QuadVertices) ); 
    g_pQuadBuffer->Unlock(); 
 
	initTextures(); 
 
	ScreenVertex g_HalfVertices[] =  
	{ 
		{   0.0f,    0.0f,   0.0f,  1.0f,   0.0f,   0.0f }, 
		{   0.0f,  384.0f,   0.0f,  1.0f,   0.0f,   1.0f }, 
		{ 512.0f,    0.0f,   0.0f,  1.0f,   1.0f,   0.0f }, 
		{ 512.0f,  384.0f,   0.0f,  1.0f,   1.0f,   1.0f }, 
	}; 
 
	g_pd3dDevice->CreateVertexBuffer( 4 * sizeof( ScreenVertex ),0, D3DFVF_SCREENVERTEX, 
                                      D3DPOOL_DEFAULT, &g_pHalfBuffer, NULL ); 
 
    g_pHalfBuffer->Lock( 0, sizeof(g_HalfVertices), (void**)&pVertices, 0 ); 
    memcpy( pVertices, g_HalfVertices, sizeof(g_HalfVertices) ); 
    g_pHalfBuffer->Unlock(); 
 
	ScreenVertex g_FullVertices[] =  
	{ 
		{    0.0f,    0.0f,   0.0f,  1.0f,   0.0f,   0.0f }, 
		{    0.0f,  768.0f,   0.0f,  1.0f,   0.0f,   1.0f }, 
		{ 1024.0f,    0.0f,   0.0f,  1.0f,   1.0f,   0.0f }, 
		{ 1024.0f,  768.0f,   0.0f,  1.0f,   1.0f,   1.0f }, 
	}; 
 
	g_pd3dDevice->CreateVertexBuffer( 4 * sizeof( ScreenVertex ),0, D3DFVF_SCREENVERTEX, 
                                      D3DPOOL_DEFAULT, &g_pFullBuffer, NULL ); 
 
    g_pFullBuffer->Lock( 0, sizeof(g_FullVertices), (void**)&pVertices, 0 ); 
    memcpy( pVertices, g_FullVertices, sizeof(g_FullVertices) ); 
    g_pFullBuffer->Unlock(); 
 
	initRTS(); 
	initEffects(); 
	 
    g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); 
    g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE ); 
	g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: initTextures() 
// Desc: Initializes textures. 
////////////////////////////////////////////////////////////////////// 
 
void initTextures( void ) 
{ 
	// Read in the HDR light probe. 
	FILE* fp = fopen( "RNL.hdr", "rb" ); 
	 
	rgbe_header_info info; 
	RGBE_ReadHeader( fp, &g_iWidth, &g_iHeight, &info ); 
 
	float fExposure = info.exposure; 
	float fGamma	= info.gamma; 
 
	float* m_fHDRPixels = new float[3 * g_iWidth * g_iHeight]; 
	memset( m_fHDRPixels, 0, 3 * g_iWidth * g_iHeight * sizeof( float ) ); 
 
    RGBE_ReadPixels_RLE( fp, m_fHDRPixels, g_iWidth, g_iHeight ); 
 
	if( FAILED( D3DXCreateTexture( g_pd3dDevice, g_iWidth, g_iHeight, 1, D3DUSAGE_DYNAMIC,  
								   FORMAT64, D3DPOOL_DEFAULT, &g_pQuadTexture ) ) ) 
	{ 
		MessageBox( g_hWnd, "Unable to create texture", "Error", MB_ICONINFORMATION ); 
	} 
 
	D3DXFLOAT16* m_fHDR = new D3DXFLOAT16[4 * g_iWidth * g_iHeight]; 
 
	int j = 0; 
	for( int i = 0; i < 4 * g_iWidth * g_iHeight; i += 4 ) 
	{ 
		m_fHDR[i] = m_fHDRPixels[i - j]; 
		m_fHDR[i + 1] = m_fHDRPixels[i + 1 - j]; 
		m_fHDR[i + 2] = m_fHDRPixels[i + 2 - j]; 
		m_fHDR[i + 3] = 0.0f; 
		j++; 
	} 
 
	D3DLOCKED_RECT lr; 
	g_pQuadTexture->LockRect( 0, &lr, NULL, 0 ); 
	memcpy( (D3DXFLOAT16*)lr.pBits, m_fHDR, 4 * g_iWidth * g_iHeight * sizeof( D3DXFLOAT16 ) ); 
 
	g_pQuadTexture->UnlockRect( 0 ); 
 
	delete[] m_fHDRPixels; 
	delete[] m_fHDR; 
 
	g_pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); 
	g_pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: initRTS() 
// Desc: Initializes render targets 
////////////////////////////////////////////////////////////////////// 
 
void initRTS( void ) 
{ 
  	// 
	// Initialize the render targets 
	// 
 
	D3DXCreateTexture( g_pd3dDevice, 1024, 768, 1, D3DUSAGE_RENDERTARGET, FORMAT64, D3DPOOL_DEFAULT, &g_pFullTexture ); 
	g_pFullTexture->GetSurfaceLevel( 0, &g_pFullSurface ); 
 
	D3DXCreateTexture( g_pd3dDevice, 512, 384, 1, D3DUSAGE_RENDERTARGET, FORMAT64, D3DPOOL_DEFAULT, &g_pDownSampleTexture ); 
	g_pDownSampleTexture->GetSurfaceLevel( 0, &g_pDownSampleSurface ); 
 
	D3DXCreateTexture( g_pd3dDevice, 512, 384, 1, D3DUSAGE_RENDERTARGET, FORMAT64, D3DPOOL_DEFAULT, &g_pBlurXTexture ); 
	g_pBlurXTexture->GetSurfaceLevel( 0, &g_pBlurXSurface ); 
 
	D3DXCreateTexture( g_pd3dDevice, 512, 384, 1, D3DUSAGE_RENDERTARGET, FORMAT64, D3DPOOL_DEFAULT, &g_pBlurYTexture ); 
	g_pBlurYTexture->GetSurfaceLevel( 0, &g_pBlurYSurface ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: initEffects() 
// Desc: Initializes effects 
////////////////////////////////////////////////////////////////////// 
 
void initEffects( void ) 
{ 
  	// 
	// Initialize the effects 
	// 
	 
	LPD3DXBUFFER pBuffer; 
 
	if( FAILED( D3DXCreateEffectFromFile( g_pd3dDevice, "DownSample.fx", NULL, NULL, 0, NULL, &g_pDownSample, &pBuffer ) ) ) 
	{ 
		LPVOID pCompileErrors = pBuffer->GetBufferPointer(); 
		MessageBox(NULL, (const char*)pCompileErrors, "Compile Error", 
			MB_OK|MB_ICONEXCLAMATION); 
		PostQuitMessage( 0 ); 
	} 
 
	if( FAILED( D3DXCreateEffectFromFile( g_pd3dDevice, "BlurX.fx", NULL, NULL, 0, NULL, &g_pBlurX, &pBuffer ) ) ) 
	{ 
		LPVOID pCompileErrors = pBuffer->GetBufferPointer(); 
		MessageBox(NULL, (const char*)pCompileErrors, "Compile Error", 
			MB_OK|MB_ICONEXCLAMATION); 
		PostQuitMessage( 0 ); 
	} 
 
	if( FAILED( D3DXCreateEffectFromFile( g_pd3dDevice, "BlurY.fx", NULL, NULL, 0, NULL, &g_pBlurY, &pBuffer ) ) ) 
	{ 
		LPVOID pCompileErrors = pBuffer->GetBufferPointer(); 
		MessageBox(NULL, (const char*)pCompileErrors, "Compile Error", 
			MB_OK|MB_ICONEXCLAMATION); 
		PostQuitMessage( 0 ); 
	} 
 
	if( FAILED( D3DXCreateEffectFromFile( g_pd3dDevice, "ToneMapping.fx", NULL, NULL, 0, NULL, &g_pToneMapping, &pBuffer ) ) ) 
	{ 
		LPVOID pCompileErrors = pBuffer->GetBufferPointer(); 
		MessageBox(NULL, (const char*)pCompileErrors, "Compile Error", 
			MB_OK|MB_ICONEXCLAMATION); 
		PostQuitMessage( 0 ); 
	} 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: setEffectParams() 
// Desc: Initializes effects 
////////////////////////////////////////////////////////////////////// 
 
void setEffectParams( void ) 
{ 
  	// 
	// Setup the effect parameters 
	// 
	 
	D3DXMATRIX matMVP = g_matWorld * g_matView * g_matProj; 
	D3DXMatrixTranspose( &matMVP, &matMVP ); 
 
	g_pDownSample->SetMatrix( "matMVP", &matMVP ); 
	g_pDownSample->SetTexture( "tDownSample", g_pFullTexture ); 
 
	g_pBlurX->SetMatrix( "matMVP", &matMVP ); 
	g_pBlurX->SetTexture( "tBlurX", g_pDownSampleTexture ); 
 
	g_pBlurY->SetMatrix( "matMVP", &matMVP ); 
	g_pBlurY->SetTexture( "tBlurY", g_pBlurXTexture ); 
 
	g_pToneMapping->SetMatrix( "matMVP", &matMVP ); 
	g_pToneMapping->SetTexture( "tFull", g_pFullTexture ); 
	g_pToneMapping->SetTexture( "tBlur", g_pBlurYTexture ); 
 
	if( g_bVaryExposure ) 
	{ 
		if( g_fExposureLevel < 0.0f ) 
			g_fExposureLevel += 0.01f; 
		else if( g_fExposureLevel > 0.0f && g_fExposureLevel <= 10.0f ) 
			g_fExposureLevel += 0.01f; 
		else if( g_fExposureLevel > 10.0f ) 
			g_fExposureLevel = 0.01f; 
	} 
 
	g_pToneMapping->SetFloat( "fExposureLevel", g_fExposureLevel ); 
 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: render() 
// Desc: Renders the scene 
////////////////////////////////////////////////////////////////////// 
 
void render( void ) 
{ 
  	// 
	// Clear the render target and begin the scene 
	// 
	int uPass; 
 
	g_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pBackBuffer ); 
	g_pd3dDevice->SetRenderTarget( 0, g_pFullSurface ); 
 
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                         D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0 ); 
 
	g_pd3dDevice->BeginScene(); 
	 
	// 
	// Setup the matrices 
	// 
 
	D3DXMatrixRotationYawPitchRoll( &g_matWorld,  
		                            D3DXToRadian( g_fSpinX_R ), 
		                            D3DXToRadian( g_fSpinY_R ), 
		                            0.0f ); 
    D3DXMatrixTranslation( &g_matWorld, 0.0f, 0.0f, 4.0f ); 
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld ); 
 
 
	D3DXMatrixLookAtLH( &g_matView, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) ); 
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView ); 
 
	D3DXMatrixPerspectiveFovLH( &g_matProj, 45.0f, 1024.0f / 768.0f, 0.1f, 100.0f ); 
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj ); 
 
    // 
	// Now the render the quad to the off-screen surface 
	// 
 
    g_pd3dDevice->SetTexture( 0, g_pQuadTexture ); 
    g_pd3dDevice->SetStreamSource( 0, g_pQuadBuffer, 0, sizeof( QuadVertex ) ); 
    g_pd3dDevice->SetFVF( D3DFVF_QUADVERTEX ); 
	g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,  0, 2 ); 
 
	g_pd3dDevice->EndScene(); 
 
 
	// 
	// Begin the scene and render to the down sample RT 
	// 
	 
	g_pd3dDevice->SetRenderTarget( 0, g_pDownSampleSurface ); //DownSampleSurface 
 
	// 
	// Setup the effect parameters 
	// 
 
	g_pDownSample->SetTechnique( "Technique0" ); 
	setEffectParams(); 
 
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                         D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0 ); 
 
	g_pd3dDevice->BeginScene(); 
 
	D3DXMatrixIdentity( &g_matWorld ); 
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld ); 
 
	D3DXMatrixLookAtLH( &g_matView, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) ); 
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView ); 
 
	D3DXMatrixPerspectiveFovLH( &g_matProj, 45.0f, 512.0f / 384.0f, 0.1f, 100.0f ); 
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj ); 
 
	UINT uPasses; 
	g_pDownSample->Begin( &uPasses, 0 ); 
 
	for( UINT uPass = 0; uPass < uPasses; ++uPass ) 
	{ 
		g_pDownSample->Pass( uPass ); 
		g_pd3dDevice->SetStreamSource( 0, g_pHalfBuffer, 0, sizeof( ScreenVertex ) ); 
		g_pd3dDevice->SetFVF( D3DFVF_SCREENVERTEX ); 
		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,  0, 2 ); 
	} 
 
	g_pDownSample->End(); 
 
	g_pd3dDevice->EndScene(); 
 
	// 
	// Begin the scene and render to the BlurX RT 
	// 
	 
	g_pd3dDevice->SetRenderTarget( 0, g_pBlurXSurface ); 
 
	// 
	// Setup the effect parameters 
	// 
 
	g_pBlurX->SetTechnique( "Technique0" ); 
	setEffectParams(); 
 
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                         D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0 ); 
 
	g_pd3dDevice->BeginScene(); 
 
	D3DXMatrixIdentity( &g_matWorld ); 
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld ); 
 
	D3DXMatrixLookAtLH( &g_matView, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) ); 
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView ); 
 
	D3DXMatrixPerspectiveFovLH( &g_matProj, 45.0f, 512.0f / 384.0f, 0.1f, 100.0f ); 
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj ); 
 
	g_pBlurX->Begin( &uPasses, 0 ); 
 
	for( uPass = 0; uPass < uPasses; ++uPass ) 
	{ 
		g_pBlurX->Pass( uPass ); 
		g_pd3dDevice->SetStreamSource( 0, g_pHalfBuffer, 0, sizeof( ScreenVertex ) ); 
		g_pd3dDevice->SetFVF( D3DFVF_SCREENVERTEX ); 
		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,  0, 2 ); 
	} 
 
	g_pBlurX->End(); 
 
	g_pd3dDevice->EndScene(); 
 
	// 
	// Begin the scene and render to the BlurY RT 
	// 
	 
	g_pd3dDevice->SetRenderTarget( 0, g_pBlurYSurface ); 
 
	// 
	// Setup the effect parameters 
	// 
 
	g_pBlurY->SetTechnique( "Technique0" ); 
	setEffectParams(); 
 
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                         D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0 ); 
 
	g_pd3dDevice->BeginScene(); 
 
	D3DXMatrixIdentity( &g_matWorld ); 
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld ); 
 
	D3DXMatrixLookAtLH( &g_matView, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) ); 
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView ); 
 
	D3DXMatrixPerspectiveFovLH( &g_matProj, 45.0f, 512.0f / 384.0f, 0.1f, 100.0f ); 
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj ); 
 
	g_pBlurY->Begin( &uPasses, 0 ); 
 
	for( uPass = 0; uPass < uPasses; ++uPass ) 
	{ 
		g_pBlurY->Pass( uPass ); 
		g_pd3dDevice->SetStreamSource( 0, g_pHalfBuffer, 0, sizeof( ScreenVertex ) ); 
		g_pd3dDevice->SetFVF( D3DFVF_SCREENVERTEX ); 
		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,  0, 2 ); 
	} 
 
	g_pBlurY->End(); 
 
	g_pd3dDevice->EndScene(); 
 
	// 
	// Begin the scene and render to the backbuffer 
	// 
 
	g_pd3dDevice->SetRenderTarget( 0, g_pBackBuffer ); 
 
	// 
	// Setup the effect parameters 
	// 
 
	g_pToneMapping->SetTechnique( "Technique0" ); 
	setEffectParams(); 
 
    g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                         D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.0f), 1.0f, 0 ); 
 
	g_pd3dDevice->BeginScene(); 
 
	D3DXMatrixIdentity( &g_matWorld ); 
    g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld ); 
 
	D3DXMatrixLookAtLH( &g_matView, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 0.0f, 1.0f ),  &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) ); 
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView ); 
 
	D3DXMatrixPerspectiveFovLH( &g_matProj, 45.0f, 512.0f / 384.0f, 0.1f, 100.0f ); 
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj ); 
 
	g_pToneMapping->Begin( &uPasses, 0 ); 
 
	for( uPass = 0; uPass < uPasses; ++uPass ) 
	{ 
		g_pToneMapping->Pass( uPass ); 
		g_pd3dDevice->SetStreamSource( 0, g_pFullBuffer, 0, sizeof( ScreenVertex ) ); 
		g_pd3dDevice->SetFVF( D3DFVF_SCREENVERTEX ); 
		g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP,  0, 2 ); 
	} 
 
	g_pToneMapping->End(); 
 
	g_pd3dDevice->EndScene(); 
 
    g_pd3dDevice->Present( NULL, NULL, NULL, NULL ); 
 
	// 
	// Update the number of rendered frames 
	// 
 
	g_dwFrames++; 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: screenGrab() 
// Desc: Takes a screenshot 
////////////////////////////////////////////////////////////////////// 
 
void screenGrab( void ) 
{ 
	D3DDISPLAYMODE d3ddm; 
	g_pd3dDevice->GetDisplayMode( 0, &d3ddm ); 
 
	g_pd3dDevice->CreateOffscreenPlainSurface( d3ddm.Width, d3ddm.Height, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &g_pScreenshot, NULL ); 
	g_pd3dDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &g_pScreenshot ); 
	 
	sprintf( g_cScreenshot, "Screenshot%d.bmp", g_iScreenshot++ ); 
	D3DXSaveSurfaceToFile( g_cScreenshot, D3DXIFF_BMP, g_pScreenshot, NULL, NULL ); 
} 
 
////////////////////////////////////////////////////////////////////// 
// Name: shutDown() 
// Desc: Shuts down D3D 
////////////////////////////////////////////////////////////////////// 
 
void shutDown( void ) 
{ 
	 
	SAFE_RELEASE( g_pd3d ); 
	SAFE_RELEASE( g_pd3dDevice ); 
 
	SAFE_RELEASE( g_pQuadBuffer	); 
	SAFE_RELEASE( g_pHalfBuffer	); 
	SAFE_RELEASE( g_pFullBuffer	); 
 
	SAFE_RELEASE( g_pQuadTexture ); 
	SAFE_RELEASE( g_pBackBuffer	); 
	SAFE_RELEASE( g_pFullTexture ); 
	SAFE_RELEASE( g_pFullSurface ); 
	SAFE_RELEASE( g_pDownSampleTexture ); 
	SAFE_RELEASE( g_pDownSampleSurface ); 
	SAFE_RELEASE( g_pBlurXTexture ); 
	SAFE_RELEASE( g_pBlurXSurface ); 
	SAFE_RELEASE( g_pBlurYTexture ); 
	SAFE_RELEASE( g_pBlurYSurface ); 
 
	SAFE_RELEASE( g_pDownSample ); 
	SAFE_RELEASE( g_pBlurX ); 
	SAFE_RELEASE( g_pBlurY ); 
	SAFE_RELEASE( g_pToneMapping ); 
 
	SAFE_RELEASE( g_pScreenshot ); 
}