📄 ca_gameoflife.cpp
字号:
}
m_pShaderManager = NULL;
return S_OK;
}
HRESULT CA_GameOfLife::Start()
{
return S_OK;
}
std::string CA_GameOfLife::GetFilePath( const std::string& strFileName )
{
return( effect_api::GetFilePath( strFileName ) );
}
HRESULT CA_GameOfLife::CreateTextureRenderTarget()
{
HRESULT hr;
_ASSERT( mpBackbufferColor != NULL );
_ASSERT( mpBackbufferDepth != NULL );
// get the description for the texture we want to filter
D3DSURFACE_DESC ddsd;
m_pInitialStateTexture->GetLevelDesc(0, &ddsd);
int i;
for( i=0; i < kMaxNumTargets; 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 < kMaxNumTargets; 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;
}
hr = m_pD3DDev->SetRenderTarget(mpFilterTarget[i], NULL);
if (FAILED(hr))
{
m_strLastError = "Can't SetRenderTarget to new surface!\n";
assert(false);
return E_FAIL;
}
m_pTexFinalSrc = mpTextureFiltered[i];
}
// 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;
}
HRESULT CA_GameOfLife::SetPixelShader( SHADER_INDEX dwIndex )
{
HRESULT hr = S_OK;
hr = m_pD3DDev->SetPixelShader( m_pShaderManager->GetShaderHandle( dwIndex ) );
ASSERT_IF_FAILED(hr);
return hr;
}
HRESULT CA_GameOfLife::SetVertexShader( SHADER_INDEX dwIndex )
{
HRESULT hr = S_OK;
hr = m_pD3DDev->SetVertexShader( m_pShaderManager->GetShaderHandle( dwIndex ) );
ASSERT_IF_FAILED(hr);
return hr;
}
bool CA_GameOfLife::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
// Returns true if keyboard command was processed
char charcode;
if( bDown )
{
// Use only capital letters here - these are VK_ codes!
switch( dwKey )
{
case VK_LEFT:
if( m_nSlowDelay > 0 )
m_nSlowDelay--;
m_bSlow = true;
FDebug("frame rate slow delay: %d\n", m_nSlowDelay );
return( true ); // keyboard command was processed
break;
case VK_RIGHT:
if( m_nSlowDelay < 500 )
m_nSlowDelay++;
m_bSlow = true;
FDebug("frame rate slow delay: %d\n", m_nSlowDelay );
return( true );
break;
case 'B':
m_bWrap = !m_bWrap;
FDebug("Wrap mode: %d\n", m_bWrap );
return( true );
break;
case 'M':
m_nSkipInterval++;
FDebug("Skip Interval: %d\n", m_nSkipInterval );
return( true );
break;
case 'N':
m_nSkipInterval--;
if( m_nSkipInterval < 0 )
m_nSkipInterval = 0;
FDebug("Skip Interval: %d\n", m_nSkipInterval );
return( true );
break;
case '1' :
m_eRenderMode = FULLSCREEN_NEIGHBOR_CALC;
return( true );
break;
case '2':
m_eRenderMode = FULLSCREEN_RESULT;
return( true );
break;
case '3' :
m_eRenderMode = ALL_TOGETHER;
return( true );
break;
case '4':
m_eRenderMode = FULLSCREEN_FINALOUT;
return( true );
break;
case 'R':
case '`':
case '~':
FDebug("Loading new rules texture map\n");
LoadRulesAndOtherMaps();
return( true );
break;
case VK_SPACE:
// start or stop the animation
m_bAnimate = !m_bAnimate;
return( true );
break;
case VK_RETURN:
m_bAnimate = false;
m_bSingleStep = !m_bSingleStep;
return( true );
break;
case 'S':
m_bSlow = !m_bSlow;
return( true );
break;
default:
charcode = MapVirtualKey( dwKey, 2 ); // VK to char code
switch( charcode )
{
case '[':
case '{':
break;
case ']':
case '}':
break;
case '-':
break;
case '=':
break;
};
};
}
return( false ); // keyboard wasn't processed
}
IDirect3DTexture8 * CA_GameOfLife::GetOutputTexture()
{
assert( m_pTexFinalSrc != NULL );
return( m_pTexFinalSrc );
}
HRESULT CA_GameOfLife::Tick()
{
// Render a new frame
HRESULT hr;
m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE );
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
SetVertexShader(m_SHI_4Offset_VertexShader);
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_bReset == true )
{
m_bReset = false;
m_nFlipState = 0;
m_bSingleStep = true; // if animation stopped, render a single step
// after reseting
}
if( m_nFlipState == 0 )
{
m_pTexSrc = m_pInitialStateTexture;
m_nTargetIntermediate = 0;
m_nTargetCellField = 1;
m_pTexFinalSrc = mpTextureFiltered[1];
}
else if( m_bAnimate == true || m_bSingleStep == true )
{
switch( m_nFlipState )
{
case 1:
// Here, over a single time step, rendering goes
// from source field to intermediate texture,
// then back to source field (new generation)
// So there is only one flipstate besides the
// initial one of "0" which uses the initial
// conditions texture.
m_nTargetIntermediate = 0;
m_nTargetCellField = 1;
m_pTexSrc = mpTextureFiltered[m_nTargetCellField];
m_pTexFinalSrc = mpTextureFiltered[1];
break;
}
}
if( m_bAnimate == true )
{
// Update the textures for one step of the
// game or cellular automata
DoSingleTimeStep_3Pass();
}
else if( m_bSingleStep == true )
{
DoSingleTimeStep_3Pass();
m_bSingleStep = false;
}
else
{
// slow down the rendering and give any other apps a chance
Sleep(70);
}
if( m_bSlow && (m_nSlowDelay > 0) )
{
Sleep(m_nSlowDelay);
}
IDirect3DTexture8 * pSrcTex;
static int nSkip = 0;
if( nSkip >= m_nSkipInterval && (m_eRenderMode != DO_NOT_RENDER) )
{
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 );
// turn off pixel shading
SetPixelShader(0);
if( m_bWireframe )
{
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME );
// chances are the texture will be all dark, so render in solid color
m_pD3DDev->SetRenderState( D3DRS_TEXTUREFACTOR, 0xFFFFFFFF );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TFACTOR );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0x0, 0x00, 0x00 ), 1.0, 0);
ASSERT_IF_FAILED(hr);
}
else
{
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
}
switch( m_eRenderMode )
{
case FULLSCREEN_FINALOUT :
// Draw quad over full display
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);
// reset offsets to 0 (ie no offsets)
offset.x = 0.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
m_pD3DDev->SetTexture(0, mpTextureFiltered[m_nTargetCellField] );
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
break;
case FULLSCREEN_RESULT :
// Draw quad over full display
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);
// reset offsets to 0 (ie no offsets)
offset.x = 0.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -