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

📄 gameoflife.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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 CGameOfLife::Free()
{
	SAFE_RELEASE( m_pVertexBuffer);			// sets pointers to null after delete
	SAFE_DELETE( m_pInitialStateTexture);
	SAFE_DELETE( m_pRulesTexture );
	SAFE_DELETE( m_pOutputMapTexture );
	
	if (m_pD3DDev)
	{
		m_pD3DDev->DeleteVertexShader(m_dwVertexShader);
		m_pD3DDev->DeletePixelShader(m_dwEqualWeightCombineShader);
		m_pD3DDev->DeletePixelShader(m_dwDependentGB );


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

        SAFE_RELEASE(mpBackbufferColor);
		SAFE_RELEASE(mpBackbufferDepth);

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


HRESULT CGameOfLife::Start()
{
	return S_OK;
}




HRESULT CGameOfLife::CreateTextureRenderTarget()
{
    HRESULT         hr;

	_ASSERT( mpBackbufferColor != NULL );
	_ASSERT( mpBackbufferDepth != NULL );

    // get the description for the texture we want to filter
	D3DSURFACE_DESC ddsd;
    m_pInitialStateTexture->GetTexture()->GetLevelDesc(0, &ddsd);

	int i;

	for( i=0; i < kMaxNumPasses; i++ )
	{
		if( mpFilterTarget[i] != NULL )
		{
            SAFE_RELEASE(mpFilterTarget[i]);
			mpFilterTarget[i] = NULL;
		}

		if( mpTextureFiltered[i] != NULL )
		{            
            SAFE_RELEASE(mpTextureFiltered[i]);
			mpTextureFiltered[i] = NULL;
		}
	}


    // create new textures just like the current texture
    for( i = 0; i < kMaxNumPasses; i++ )
    {
        hr = m_pD3DDev->CreateTexture(ddsd.Width, ddsd.Height, 1, 
                                      D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, 
                                      D3DPOOL_DEFAULT, &mpTextureFiltered[i]);
        if (FAILED(hr))
        {
		    m_strLastError = "Can't CreateTexture!\n";
            assert(false);
            return E_FAIL;
        }

        hr = mpTextureFiltered[i]->GetSurfaceLevel(0, &mpFilterTarget[i]);
        if (FAILED(hr))
        {
		    m_strLastError = "Can't Get to top-level texture!\n";
            assert(false);
            return E_FAIL;
        }

        // set our render target to the new and shiny textures without depth
        hr = m_pD3DDev->SetRenderTarget(mpFilterTarget[i], NULL);
        if (FAILED(hr))
        {
		    m_strLastError = "Can't SetRenderTarget to new surface!\n";
            assert(false);
            return E_FAIL;
        }
    }

    // switch back to conventional back-buffer
    hr = m_pD3DDev->SetRenderTarget(mpBackbufferColor, mpBackbufferDepth);
    if (FAILED(hr))
    {
		m_strLastError = "Can't SetRenderTarget to original back-buffer surfaces!\n";
        assert(false);
        return E_FAIL;
    }

    return S_OK;
}



void CGameOfLife::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
	// Note - pressing tidle key will not cause this to be called
	//  until the window is resized - Something happens then to 
	//  trigger the Keyboard function.

    unsigned int option = static_cast<unsigned int>(meDisplayOption); 

	if( bDown )
	{
		// Use only capital letters here - these are VK_ codes!

		switch( dwKey )
		{
		case 'B':
			m_bWrap = !m_bWrap;
			FDebug("Wrap mode:  %d\n", m_bWrap );
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;

		case 'M':
		case '.':
		case '>':
			m_nSkipInterval++;
			FDebug("Skip Interval:  %d\n", m_nSkipInterval );
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;
		case 'N':
		case ',':
		case '<':
			m_nSkipInterval--;
			if( m_nSkipInterval < 0 )
				m_nSkipInterval = 0;
			FDebug("Skip Interval:  %d\n", m_nSkipInterval );
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;
		case '1' :
			m_eRenderMode = FULLSCREEN_NEIGHBOR_CALC;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;

		case '2':
			m_eRenderMode = FULLSCREEN_RESULT;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;

		case '3' :
			m_eRenderMode = ALL_TOGETHER;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;
		case '4':
			m_eRenderMode = FULLSCREEN_FINALOUT;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;

		case 'F':
			m_bFarther = !m_bFarther;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;

		case 'R':
		case '`':
		case '~':
			FDebug("Loading new rules texture map\n");
			LoadRulesAndOtherMaps();
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;
		case 'G':
			// start or stop the animation
			m_bAnimate = !m_bAnimate;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;
		case VK_SPACE:
			m_bSingleStep = !m_bSingleStep;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;
		case 'S':
			m_bSlow = !m_bSlow;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			return;
			break;
		}
	}


	eEBKeyAction Action = TranslateEffectKey(dwKey, nFlags, bDown);
	
    switch ( Action )
    {
		case EB_HELP:
		{
			EBString str;
			str =  " Help : F1 - Help\n\n";
			str += " W    - Wireframe toggle\n\n";

			str += " Home - Restart from initial frame  \n\n";

			str += " R    - Reload \"rules\" and \"output\" maps   \n";
			str += "          from files\n";
			str += " G    - Stop/Go animation toggle\n";
			str += " SPC  - Single frame step when anim stopped   \n";
			str += " B    - Toggle border wrapping\n\n";

			str += " 1    - Draw neighbor accumulation map\n";
			str += " 2    - Draw current generation\n";
			str += " 3    - Draw initial, temp, and output frames\n";
			str += " 4    - Draw color re-map if enabled\n";
			str += " F    - Toggle additional color re-map step\n\n";

			str += " M    - Increase # frames to skip\n";
			str += " N    - Decrease # frames to skip\n";
			str += " S    - Slow updates to ~20 fps\n\n";

			::MessageBoxEx( NULL, str.c_str(),
				   "Help", MB_ICONINFORMATION | MB_TASKMODAL, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) );
		}
		break;

		case EB_WIREFRAME:
        {
            m_bWireframe = !m_bWireframe;
            m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
        }
		break;

		case EB_RESET:
        {
			m_bReset = true;

        }
		break;

        case EB_ADD:
            break;

        case EB_SUBTRACT:
            break;

        default:
            break;
    }
}





// Our properties were updated, set the correct shader to match
void CGameOfLife::PropertyUpdateCallback(const EBProperty* pProperty, bool bWritten)
{
	// If somebody changed the filter we are doing, set the dirty flag and change the 
    // pixel shader enum to reflect this.
	if (pProperty->IsKindOf(EBTYPE_ENUM_PROP))
	{
		if (bWritten)
		{
			if (pProperty->GetOffset() == OBJECT_MEMBER(m_strEffectPixelShader))
			{
				if (m_strEffectPixelShader.compare(GetFilePath("EqualWeightCombine.nvp")) == 0)
				{
					meDisplayOption = GAME_OF_LIFE_EFFECT;
				}
				m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
			}
			else
			{
				switch (meDisplayOption)
				{
					case GAME_OF_LIFE_EFFECT:
						m_strEffectPixelShader = GetFilePath("EqualWeightCombine.nvp");
						break;
					default:
					;
				}

				m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PIXELSHADERS;
			}
		}		
	}
}


HRESULT CGameOfLife::Tick(EBTimer* pTimer)
{	
	// Render a new frame

	HRESULT hr;



	D3DXMATRIX matWorld;
	D3DXMATRIX matView;
	D3DXMATRIX matProj;
	D3DXMATRIX matViewProj;
	D3DXMATRIX matWorldViewProj;

    // write to constant memory which uv-offsets to use to accumulate neighbor information
    D3DXVECTOR4     offset(0.0f, 0.0f, 0.0f, 0.0f);
	m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);


	// Disable culling
	m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

    // set render state 
	m_pD3DDev->SetVertexShader(m_dwVertexShader);
	m_pD3DDev->SetStreamSource(0, m_pVertexBuffer, sizeof(QuadVertex));


	D3DXVECTOR3 const vEyePt    = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
	D3DXVECTOR3 const vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3 const vUp       = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );

	// Set World, View, Projection, and combination matrices.
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUp);
	D3DXMatrixOrthoLH(&matProj, 4.0f, 4.0f, 0.2f, 20.0f);

    D3DXMatrixMultiply(&matViewProj, &matView, &matProj);

    // draw a single quad to texture:
    // the quad covers the whole "screen" exactly

	D3DXMatrixScaling(&matWorld, 2.0f, 2.0f, 1.0f);
	D3DXMatrixMultiply(&matWorldViewProj, &matWorld, &matViewProj);
    D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
	m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);



	if( m_bAnimate == true  )
	{
		// Update the textures for one step of the 
		//   game or cellular automata 

		//DoSingleTimeStep();
		DoSingleTimeStep_3Pass();

	}
	else if( m_bSingleStep == true )
	{
		//DoSingleTimeStep();
		DoSingleTimeStep_3Pass();

		m_bSingleStep = false;

		m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
	}
	else
	{
		// slow down the rendering and give any other apps a chance
		Sleep(50);
	}

	if( m_bSlow )
	{
		Sleep(50);
	}




	static int nSkip = 0;

	if( nSkip >= m_nSkipInterval )
	{
		nSkip = 0;

		// Switch back to normal rendering to display the results of 
		//   the rendering to texture

		m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, false );


		hr = m_pD3DDev->SetRenderTarget(mpBackbufferColor, mpBackbufferDepth);
		ASSERT_IF_FAILED( hr );

		hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0,0,0 ), 1.0, 0);
		ASSERT_IF_FAILED(hr);


		// turn off pixel shading
		m_pD3DDev->SetPixelShader(0);	

		

		if( m_bWireframe )
		{
			m_pD3DDev->SetRenderState(D3DRS_FILLMODE,	D3DFILL_WIREFRAME );

⌨️ 快捷键说明

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