⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ca_gameoflife.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*********************************************************************NVMH2****
Path:  C:\Dev\devrel\Nv_sdk_4\Dx8\NVEffectsBrowser\Effects\CA_GameOfLife
File:  CA_GameOfLife.cpp

Copyright (C) 1999, 2000 NVIDIA Corporation
This file is provided without support, instruction, or implied warranty of any
kind.  NVIDIA makes no guarantee of its fitness for a particular purpose and is
not liable under any circumstances for any damages or loss whatsoever arising
from the use or inability to use this file or items derived from it.

Comments:
4/27/01
No longer requires an EBEffect * to be passed in.  Uses global effect_api::
	GetFilePath() and load shader functions.  Joy!
If all .vso, .pso files are in directory of the executable, then the GetFilePath()
	call can be removed --- just use the straight file names.

This class is now more portable to any application wanting to do procedural
    texture animation.
I'd still like to separate the UI into another class, but this will have to wait.


******************************************************************************/


#include <crtdbg.h>


#include "eb_file.h"

#include <vector>
#include "CA_GameOfLife.h"
#include "..\..\..\CommonSrc\NV_Error.h"			// for FDebug

#include "Constants.h"
#include "PixelConstants.h"

#include "ShaderManager.h"


using namespace std;


#define RULE_TABLE_NAME		"RuleTable.bmp"
#define INITIAL_FILENAME	"start.bmp"
#define OUTPUT_MAP_FILENAME	"OutputColors.bmp"


////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////


CA_GameOfLife::CA_GameOfLife()
{

	m_bWireframe			= false;
	m_pInitialStateTexture	= NULL;
	m_pRulesTexture			= NULL ;

	m_SHI_4Offset_VertexShader		= 0;
	m_SHI_EqualWeightCombineShader	= 0;
	m_SHI_DependentGB				= 0;
	m_SHI_TexelsToBlueWithBias		= 0;

	m_pVertexBuffer			= NULL;
	mpBackbufferColor		= 0 ;
	mpBackbufferDepth		= 0 ;

	m_pD3DDev				= NULL;

	for ( int i = 0; i < kMaxNumTargets; ++i )
	{
        mpTextureFiltered[i] = 0;
		mpFilterTarget   [i] = 0;
	}

}

CA_GameOfLife::~CA_GameOfLife()
{
	Free();	
}

/////////////////////////////////////////////////////////


HRESULT CA_GameOfLife::ConfirmDevice(D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format)
{
    // check vertex shading support
    if(D3DSHADER_VERSION_MAJOR(pCaps->VertexShaderVersion) < 1)
	{
		m_strLastError = "Device does not support vertex shaders!";
		return E_FAIL;
	}
    if(D3DSHADER_VERSION_MINOR(pCaps->VertexShaderVersion) < 1)
	{
		m_strLastError = "Device does not support 1.1 vertex shaders!";
		return E_FAIL;
	}

    // check simultaneous texture support
    if(pCaps->MaxSimultaneousTextures < 4)
	{
		m_strLastError = "Device does not support 4 simultaneous textures!";
		return E_FAIL;
	}

    // check pixel shader support
    if(D3DSHADER_VERSION_MAJOR(pCaps->PixelShaderVersion) < 1)
	{
		m_strLastError = "Device does not support pixel shaders!";
		return E_FAIL;
	}
	if(D3DSHADER_VERSION_MINOR(pCaps->PixelShaderVersion) < 1)
	{
		m_strLastError = "Device does not support 1.1 pixel shaders!";
		return E_FAIL;
	}
	if(pCaps->MaxTextureBlendStages < 8)
	{
		m_strLastError = "Device does not support 8 register combiners!";
		return E_FAIL;
	}


	return S_OK;
}


void CA_GameOfLife::UpdateProperties()
{

}


void CA_GameOfLife::LoadRulesAndOtherMaps()
{
	// Load "rules" texture which determines how the neighbor accumulation 
	//  maps to new pixels
	// Also reload output color map 
	// Also reload initial conditions map

	EBString filename;
	HRESULT hr;

	if( m_pRulesTexture != NULL )
	{
		SAFE_RELEASE( m_pRulesTexture );
	}

	if( m_pInitialStateTexture != NULL )
	{
		SAFE_RELEASE( m_pInitialStateTexture );
	}

	////////////////////////////////////////////////

	filename = RULE_TABLE_NAME;

	hr = D3DXCreateTextureFromFile( m_pD3DDev, GetFilePath(filename.c_str()).c_str(),
									&m_pRulesTexture );

	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
	{
		m_strLastError = "Couldn't load texture: ";
		m_strLastError += filename;
		assert( false );
		return;
	}

	////////////////////////////////////////////////

	filename = INITIAL_FILENAME;

	hr = D3DXCreateTextureFromFile( m_pD3DDev, GetFilePath(filename.c_str()).c_str(),
									&m_pInitialStateTexture );

	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
	{
		m_strLastError = "Couldn't load texture: ";
		m_strLastError += filename;
		assert( false );
		return;
	}


	//  Not re-creating render targets.  This could be problem if 
	//   you reload an initial texture with different resolution while
	//   the simulation is running.  The new resolution will not be 
	//   reflected in the render targets

}



HRESULT CA_GameOfLife::Initialize( LPDIRECT3DDEVICE8 pDev, ShaderManager * pManager )
{
	// Called when effect is selected from list in browser
	// Free() is called when effect is de-selected

	assert( pDev != NULL );
	assert( pManager != NULL );

	// Free everything in case we're already initialized
	Free();


    int     i;
	HRESULT hr;


	m_pShaderManager = pManager;


	// get the device
	m_pD3DDev = pDev;
	pDev->AddRef();			// released on Free()



	//initialize mouse UI
	RECT rect;
	rect.left = rect.top = 0;
	D3DVIEWPORT8 viewport;
	m_pD3DDev->GetViewport(&viewport);
	rect.bottom = viewport.Height;
	rect.right  = viewport.Width;


	///////////////////////////////////////////////


	m_bReset		= true;
	m_bAnimate		= true;
	m_bSingleStep	= false;

	m_bSlow			= false;

	m_bWrap			= false;

	m_bOccasionalExcitation	= false;


	m_nSlowDelay = 25;

	m_eRenderMode = FULLSCREEN_NEIGHBOR_CALC;

	m_nSkipInterval = 0;
	m_nFlipState = 0;


	/////////////////////////////////


	// create the vertex and pixel shaders
	vector<DWORD> Declaration;
	Declaration.push_back(D3DVSD_STREAM(0));
	Declaration.push_back(D3DVSD_REG(0, D3DVSDT_FLOAT3));
	Declaration.push_back(D3DVSD_REG(1, D3DVSDT_FLOAT2));
	Declaration.push_back(D3DVSD_END());


	hr = m_pShaderManager->LoadAndCreateShader( GetFilePath("TexCoord_4_Offset.vso"),
							GetFilePath("TexCoord_4_Offset.nvv"), &Declaration[0], 0,
							SM_SHADERTYPE_VERTEX, &m_SHI_4Offset_VertexShader);
	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
		return hr;
	

	// Shader for 1st step in accumulating neighbor information
    hr = m_pShaderManager->LoadAndCreateShader(GetFilePath("TexelsToBlueWithBias.pso"),
							GetFilePath("TexelsToBlueWithBias.nvp"), NULL, 0,
							SM_SHADERTYPE_PIXEL, &( m_SHI_TexelsToBlueWithBias ) );
	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
		return hr;


    hr = m_pShaderManager->LoadAndCreateShader(GetFilePath("EqualWeightCombine.pso"),
							GetFilePath("EqualWeightCombine.nvp"), NULL, 0,
							SM_SHADERTYPE_PIXEL, &(m_SHI_EqualWeightCombineShader));
	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
		return hr;


	// Dependent 2D lookup pixel shader for logic rules:
    hr = m_pShaderManager->LoadAndCreateShader(GetFilePath("DependentGB.pso"),
							GetFilePath("DependentGB.nvp"), NULL, 0,
							SM_SHADERTYPE_PIXEL, &(m_SHI_DependentGB ) );
	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
		return hr;





    // get a pointer to the current back-buffer (so we can restore it later)
	m_pD3DDev->GetRenderTarget(        &mpBackbufferColor );
	m_pD3DDev->GetDepthStencilSurface( &mpBackbufferDepth );



	D3DXVECTOR4  commonconst( 0.0f, 0.5f, 1.0f, 2.0f );
	m_pD3DDev->SetVertexShaderConstant( CV_CONSTS_1, &commonconst,    1);


	/////////////////////////////////


	// load the initial conditions texture map, rules map, and 
	//  optional final color re-mapping map

	// The "rules" texture determines how the neighbor accumulation 
	//  maps to new pixels in the next generation

	LoadRulesAndOtherMaps();

	hr = CreateTextureRenderTarget();
	ASSERT_IF_FAILED(hr);


	////////////////////////////////////////////////////////////////////////////


	D3DSURFACE_DESC ddsd;
    m_pInitialStateTexture->GetLevelDesc(0, &ddsd);

    CreateAndWriteUVOffsets(ddsd.Width, ddsd.Height);


	////////////////////////////////////////////////////////////////////////////
	// create vertex buffer 
	hr = m_pD3DDev->CreateVertexBuffer( 4 * sizeof(QuadVertex), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, 0, D3DPOOL_DEFAULT, &m_pVertexBuffer);
	ASSERT_IF_FAILED(hr);
	if (FAILED(hr))
		return hr;

	QuadVertex      *pBuff;

	if (m_pVertexBuffer)
	{
		hr = m_pVertexBuffer->Lock(0, 4 * sizeof(QuadVertex),(BYTE**)&pBuff, 0);
		ASSERT_IF_FAILED(hr);
		if (FAILED(hr))
		{
			m_strLastError = "Couldn't lock buffer!";
			return hr;
		}


		float uv_base;
		float uv_max;

		uv_base = 0.0f;
		uv_max  = 1.0f; 

        for (i = 0; i < 4; ++i)
        {
            pBuff->Position = D3DXVECTOR3((i==0 || i==3) ? -1.0f : 1.0f,
                                          (i<2)          ? -1.0f : 1.0f,
                                          0.0f);
		    pBuff->Tex      = D3DXVECTOR2((i==0 || i==3) ? uv_base : uv_max , 
                                          (i<2)          ? uv_max : uv_base );
		    pBuff++;
        }
        m_pVertexBuffer->Unlock();
    }


    // set up render state: disable all except texture stage 0 (see below)
    for(i = 0; i < 4; i++ )
    {
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_COLOROP,   D3DTOP_DISABLE);
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_ALPHAOP,   D3DTOP_DISABLE);

	    m_pD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSU,  D3DTADDRESS_CLAMP);
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSV,  D3DTADDRESS_CLAMP);
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSW,  D3DTADDRESS_CLAMP);

        m_pD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_POINT );
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_POINT );
	    m_pD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_NONE  );

		m_pD3DDev->SetTextureStageState(i,D3DTSS_TEXTURETRANSFORMFLAGS,	 D3DTTFF_DISABLE );
		m_pD3DDev->SetTextureStageState(i,D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU | i );

		m_pD3DDev->SetTextureStageState(i, D3DTSS_RESULTARG, D3DTA_CURRENT );
    }

	// Set wrap to zero - It will wrap anyway and avoid the problems of
	//   setting cylindrical wrapping (D3DRS_WRAP0, D3DWRAP_U == cylindrical)
	//   for texture coords > 1.0f

	// For wrapped textures, you should use only the D3DTSS_ADDRESSU/V/W
	//   states, unless you are doing cube environment mapping.

    m_pD3DDev->SetRenderState(D3DRS_WRAP0, 0);
    m_pD3DDev->SetRenderState(D3DRS_WRAP1, 0);
    m_pD3DDev->SetRenderState(D3DRS_WRAP2, 0);
    m_pD3DDev->SetRenderState(D3DRS_WRAP3, 0);
    m_pD3DDev->SetRenderState(D3DRS_WRAP4, 0);
    m_pD3DDev->SetRenderState(D3DRS_WRAP5, 0);
    m_pD3DDev->SetRenderState(D3DRS_WRAP6, 0);
    m_pD3DDev->SetRenderState(D3DRS_WRAP7, 0);


    m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);

    m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE,	FALSE );
    m_pD3DDev->SetRenderState(D3DRS_ZENABLE,			FALSE );

	m_pD3DDev->SetRenderState(D3DRS_FOGENABLE,			FALSE );
	m_pD3DDev->SetRenderState(D3DRS_DITHERENABLE,		FALSE );
	m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE,	FALSE );
	m_pD3DDev->SetRenderState(D3DRS_SRCBLEND,			D3DBLEND_ONE  );
	m_pD3DDev->SetRenderState(D3DRS_DESTBLEND,			D3DBLEND_ZERO );

	m_pD3DDev->SetRenderState(D3DRS_ZWRITEENABLE,		FALSE );

	m_pD3DDev->SetRenderState(D3DRS_SPECULARENABLE,		FALSE );
	m_pD3DDev->SetRenderState(D3DRS_STENCILENABLE,		FALSE );
	m_pD3DDev->SetRenderState(D3DRS_LIGHTING,			FALSE );

	m_pD3DDev->SetRenderState(D3DRS_COLORVERTEX,		FALSE );

	m_pD3DDev->SetRenderState(D3DRS_FILLMODE,			D3DFILL_SOLID );
	m_pD3DDev->SetRenderState(D3DRS_CULLMODE,			D3DCULL_NONE );


    return hr;
}


HRESULT CA_GameOfLife::Free()
{
	SAFE_RELEASE( m_pVertexBuffer );			// sets pointers to null after delete
	SAFE_RELEASE( m_pInitialStateTexture );
	SAFE_RELEASE( m_pRulesTexture );


	if (m_pD3DDev)
	{
		m_SHI_4Offset_VertexShader = 0;
		m_SHI_EqualWeightCombineShader = 0;
		m_SHI_DependentGB = 0;
		m_SHI_TexelsToBlueWithBias = 0;

        for (int i = 0; i < kMaxNumTargets; ++i)
        {            
            SAFE_RELEASE(mpFilterTarget[i]);
            SAFE_RELEASE(mpTextureFiltered[i]);
        }

        SAFE_RELEASE(mpBackbufferColor);
		SAFE_RELEASE(mpBackbufferDepth);

        SAFE_RELEASE(m_pD3DDev);		// we AddRef()'d in Initialize

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -