📄 gameoflife.cpp
字号:
// 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 );
}
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, m_pOutputSrc );
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);
m_pD3DDev->SetTexture(0, m_pTexSrc );
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
break;
case FULLSCREEN_NEIGHBOR_CALC:
// 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, m_pIntermediateSrc );
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
break;
case ALL_TOGETHER :
// draw quad in upper left corner: original texture
D3DXMatrixTranslation(&matWorld, -1.0f, 1.0f, 0.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, m_pInitialStateTexture->GetTexture());
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
// draw quads in the other corners, use generated textures
for (int j = 0; j < 3; ++j)
{
D3DXMatrixTranslation(&matWorld, (j == 2) ? -1.0f : 1.0f,
(j == 0) ? 1.0f : -1.0,
0.0f);
D3DXMatrixMultiply(&matWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
m_pD3DDev->SetTexture(0, mpTextureFiltered[j]);
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
}
break;
}; // switch for display config
}
else
{
// skip rendering this frame
// Set normal render target in case the app is doing more rendering
// to the window
hr = m_pD3DDev->SetRenderTarget(mpBackbufferColor, mpBackbufferDepth);
nSkip++;
}
return( hr );
}
HRESULT CGameOfLife::DoSingleTimeStep()
{
HRESULT hr;
// write to constant memory which uv-offsets to use
D3DXVECTOR4 offset(0.0f, 0.0f, 0.0f, 0.0f);
if( m_bReset == true )
{
m_bReset = false;
m_nFlipState = 0;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
float pix_mult[4] = { 0.0f, 0.125f, 0.0f, 0.0f };
hr = m_pD3DDev->SetPixelShaderConstant( PCN_MULTFACTOR, &pix_mult, 1 );
ASSERT_IF_FAILED(hr);
// select source texture:
// targ ind 0 = neighbor calc
// targ ind 1 = result storage #1
// targ ind 2 = result storage #2
// targ ind 3 = result with re-mapped colors for display only
switch( m_nFlipState )
{
case 0:
m_pTexSrc = m_pInitialStateTexture->GetTexture();
m_pTexFinalTarg = mpFilterTarget[1];
m_pIntermediateTarg = mpFilterTarget[0];
m_pIntermediateSrc = mpTextureFiltered[0];
m_pOutputSrc = mpTextureFiltered[3];
m_pOutputTarg = mpFilterTarget[3];
break;
case 1:
m_pTexSrc = mpTextureFiltered[1];
m_pTexFinalTarg = mpFilterTarget[2];
m_pIntermediateTarg = mpFilterTarget[0];
m_pIntermediateSrc = mpTextureFiltered[0];
m_pOutputSrc = mpTextureFiltered[3];
m_pOutputTarg = mpFilterTarget[3];
break;
case 2:
m_pTexSrc = mpTextureFiltered[2];
m_pTexFinalTarg = mpFilterTarget[1];
m_pIntermediateTarg = mpFilterTarget[0];
m_pIntermediateSrc = mpTextureFiltered[0];
m_pOutputSrc = mpTextureFiltered[3];
m_pOutputTarg = mpFilterTarget[3];
break;
}
// Clear intermediate target
hr = m_pD3DDev->SetRenderTarget( m_pIntermediateTarg, NULL);
ASSERT_IF_FAILED( hr );
// Clear 1st target to small fraction of green and blue to offset the
// dependent lookup to the proper values
// 0xff / 16 = 0x10
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0x0, 0x04, 0x02 ), 1.0, 0);
// even if wireframe mode, render to texture as solid
m_pD3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
/////////////////////////////////////////////////////////
// First, write the source texture into the blue channel
// I do this in preparation for a 2D dependent green-blue lookup
// into a "rules" texture which governs how old pixels spawn
// or die into new pixels.
// The logic for the game of life depends on 9 pixels: the source
// pixel and it's 8 neightbors. These are accumulated in three
// passes.
hr = m_pD3DDev->SetRenderTarget( m_pIntermediateTarg, NULL);
m_pD3DDev->SetPixelShader( 0 ); // no pixel shader
// Add into dest texture - texture cleared to small fraction of
// green and blue to offset the dependent lookup to the proper values
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
// Setup traditional pipeline to copy the white source pixels
// into just the blue of the dest:
m_pD3DDev->SetTexture(0, m_pTexSrc );
m_pD3DDev->SetRenderState( D3DRS_TEXTUREFACTOR, 0x000000FF ); // ARGB
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_TFACTOR ); // blue only
m_pD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
m_pD3DDev->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE );
// Render using offsets of zero
offset.x = 0.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
// draw the fan with normal texture coords
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
/////////////////////////////////////////////////////////////////
// Setup neighbor blending modes:
hr = m_pD3DDev->SetPixelShader( m_dwEqualWeightCombineShader );
ASSERT_IF_FAILED( hr );
DWORD wrapval = m_bWrap ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, wrapval);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, wrapval);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, wrapval);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, wrapval);
m_pD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSU, wrapval);
m_pD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSV, wrapval);
m_pD3DDev->SetTextureStageState(3, D3DTSS_ADDRESSU, wrapval);
m_pD3DDev->SetTextureStageState(3, D3DTSS_ADDRESSV, wrapval);
/////////////////////////////////////////////////////////////////
// Render 1st set of neighbors
// Add in nearest neighbors
hr = m_pD3DDev->SetRenderTarget( m_pIntermediateTarg, NULL);
ASSERT_IF_FAILED(hr);
// Add result of pixel operations into the dest texture:
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
m_pD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
m_pD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
// Render 1st using offset set 1 - for nearest neighbor pixels
offset.x = 1.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
m_pD3DDev->SetTexture(0, m_pTexSrc );
m_pD3DDev->SetTexture(1, m_pTexSrc );
m_pD3DDev->SetTexture(2, m_pTexSrc );
m_pD3DDev->SetTexture(3, m_pTexSrc );
// draw the fan with displaced texture coordinates
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
/////////////////////////////////////////////////////////////////
// Render 2nd set of neighbors
// Add diagonal neighbors
hr = m_pD3DDev->SetRenderTarget( m_pIntermediateTarg, NULL);
ASSERT_IF_FAILED(hr);
// Don't clear - we're still adding the 8 neighbors
// Render 2nd using offsets set 2 - for diagonal pixels
offset.x = 2.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
m_pD3DDev->SetTexture(0, m_pTexSrc );
m_pD3DDev->SetTexture(1, m_pTexSrc );
m_pD3DDev->SetTexture(2, m_pTexSrc );
m_pD3DDev->SetTexture(3, m_pTexSrc );
// draw the fan with displaced texture coordinates
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
ASSERT_IF_FAILED(hr);
// If wrapping was on, reset to clamp now for the rest of the
// rendering
if( m_bWrap )
{
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
m_pD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
m_pD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
m_pD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
m_pD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
m_pD3DDev->SetTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
m_pD3DDev->SetTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
}
/////////////////////////////////////////////////////////////////
// Now do dependent 2D lookup into rules texture to set new
// source pixels;
hr = m_pD3DDev->SetPixelShader( m_dwDependentGB );
ASSERT_IF_FAILED( hr );
hr = m_pD3DDev->SetRenderTarget( m_pTexFinalTarg, NULL);
ASSERT_IF_FAILED(hr);
// Render using offsets of zero
offset.x = 0.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
m_pD3DDev->SetTexture(0, m_pIntermediateSrc );
m_pD3DDev->SetTexture(1, m_pRulesTexture->GetTexture() );
ASSERT_IF_FAILED( hr );
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, false );
// draw the fan with displaced texture coordinates
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
ASSERT_IF_FAILED(hr);
/////////////////////////////////////////////////////////////////
// If further processing is requested, do 1 more dependent
// lookup into a colormap for display to the user only.
// This remapping doesn't affect the logic at all, it's only
// a prettier version for the user to see.
if( m_bFarther )
{
hr = m_pD3DDev->SetPixelShader( m_dwDependentGB );
ASSERT_IF_FAILED( hr );
hr = m_pD3DDev->SetRenderTarget( m_pOutputTarg, NULL);
ASSERT_IF_FAILED(hr);
// Render using offsets of zero
offset.x = 0.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
hr = m_pD3DDev->SetTexture(0, m_pIntermediateSrc );
hr = m_pD3DDev->SetTexture(1, m_pOutputMapTexture->GetTexture() );
ASSERT_IF_FAILED( hr );
m_pD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, false );
// draw the fan with displaced texture coordinates
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
ASSERT_IF_FAILED(hr);
}
// Flip the state variable for the next round of rendering
switch( m_nFlipState )
{
case 0:
m_nFlipState = 1;
break;
case 1:
m_nFlipState = 2;
break;
case 2:
m_nFlipState = 1;
break;
}
return hr;
}
HRESULT CGameOfLife::DoSingleTimeStep_3Pass()
{
HRESULT hr;
int i;
// write to constant memory which uv-offsets to use
D3DXVECTOR4 offset(0.0f, 0.0f, 0.0f, 0.0f);
if( m_bReset == true )
{
m_bReset = false;
m_nFlipState = 0;
m_dwEffectDirtyFlags |= EBEFFECT_DIRTY_PUBLICSTATE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -