📄 ca_fire.cpp
字号:
hr = 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);
m_pD3DDev->SetTexture(0, m_pIntermediateSrc );
m_pD3DDev->SetTexture(1, m_pRulesTexture->GetTexture() );
ASSERT_IF_FAILED( hr );
// draw the fan with displaced texture coordinates
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
ASSERT_IF_FAILED(hr);
*/
//////////
// /*
// /*
D3DXMATRIX matWorld;
D3DXMATRIX matView;
D3DXMATRIX matProj;
D3DXMATRIX matTemp;
D3DXMATRIX matViewProj;
D3DXMATRIX matWorldViewProj;
float height = 0.45f;
D3DXVECTOR3 vNEWEyePt = D3DXVECTOR3( 0.0f, height, -2.5f );
D3DXVECTOR3 vNEWLookatPt = D3DXVECTOR3( 0.0f, height, 0.0f );
D3DXVECTOR3 vNEWUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
// Set World, View, Projection, and combination matrices.
D3DXMatrixLookAtLH(&matView, &vNEWEyePt, &vNEWLookatPt, &vNEWUp);
D3DXMatrixPerspectiveFovLH( &matProj, 3.1415f/5.0f, 1.0f, 0.5f, 300.0f );
D3DXMatrixRotationX( &matTemp, 3.14159f * 0.5f );
D3DXMatrixMultiply(&matViewProj, &matView, &matProj);
D3DXMatrixIdentity( &matWorld );
D3DXMatrixMultiply( &matWorld, &m_pUI->GetRotationMatrix(), &m_pUI->GetTranslationMatrix() );
// Apply mouse UI rotation after initial X axis rotation in matTemp
D3DXMatrixMultiply( &matWorld, &matTemp, &matWorld );
D3DXMatrixMultiply(&matWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &matWorldViewProj(0, 0), 4);
////////////////////////////////////////////////////
wrapval = m_bWrap ? D3DTADDRESS_WRAP : D3DTADDRESS_CLAMP;
for( i=0; i < 4 ; i++ )
{
hr = m_pD3DDev->SetTextureStageState(i, D3DTSS_BORDERCOLOR, 0x00000000);
ASSERT_IF_FAILED(hr);
hr = m_pD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSU, wrapval);
ASSERT_IF_FAILED(hr);
hr = m_pD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSV, D3DTADDRESS_BORDER);
ASSERT_IF_FAILED(hr);
}
// Render embers into newly cleared texture, blending old texture
// on top of the embers
hr = SetStep_Average_4_Nearest( mpFilterTarget[m_nTarget3], m_pTexFinalSrc );
ASSERT_IF_FAILED(hr);
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0x0, 0x00, 0x00 ), 1.0, 0);
pix_mult[0] = 0.45f; // red
pix_mult[1] = 0.15f; // green
pix_mult[2] = 0.05f; // blue
pix_mult[3] = 0.0f; // alpha
hr = m_pD3DDev->SetPixelShaderConstant( PCN_MULTFACTOR_1, &pix_mult, 1 );
ASSERT_IF_FAILED(hr);
pix_mult[0] = 0.45f; // red
pix_mult[1] = 0.15f; // green
pix_mult[2] = 0.05f; // blue
pix_mult[3] = 0.0f; // alpha
hr = m_pD3DDev->SetPixelShaderConstant( PCN_MULTFACTOR_2, &pix_mult, 1 );
ASSERT_IF_FAILED(hr);
hr = SetPixelShader( m_dwEqualWeight_PostMultShader );
ASSERT_IF_FAILED( hr );
offset.x = 1.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
// Draws "embers" at bottom of texture
// draw the fan with displaced texture coordinates
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
ASSERT_IF_FAILED(hr);
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
// Set the TC warping on/off
offset.x = 1.0f;
offset.y = 0.0f;
m_pD3DDev->SetVertexShaderConstant( CV_ONOFF_1, &offset, 1);
float hoff, woff;
woff = m_fPerTexelWidth/2.0f;
hoff = m_fPerTexelHeight/2.0f;
hoff += m_fTranslateAmount * m_fPerTexelHeight;
static float xp = 0;
static float yp = 0;
float xlim = m_fPerTexelWidth * 0.5f;
float ylim = m_fPerTexelHeight * 1.0f;
float xdmag;
float ydmag;
xdmag = 0.0001f;
ydmag = 0.005f;
xdmag = 0.005f;
ydmag = 0.005f;
// alter degree of jittering by the translate amount
// so when less translation, you also get less rapid jittering
xdmag *= m_fTranslateAmount / 2.5f;
ydmag *= m_fTranslateAmount / 2.5f;
// Brownian noise motion for texel sampling offset vector
xp += xdmag * ( 1.0f - 2.0f * rand()/((float)RAND_MAX));
yp += ydmag * ( 1.0f - 2.0f * rand()/((float)RAND_MAX));
if( xp > xlim ) xp = xlim;
if( yp > ylim ) yp = ylim;
if( xp < -xlim ) xp = -xlim;
if( yp < -ylim ) yp = -ylim;
hoff += yp;
woff += xp;
float type4OffsetX[4] = { - m_fPerTexelWidth + woff,
m_fPerTexelWidth + woff,
0.0f + woff,
0.0f + woff };
float type4OffsetY[4] = { 0.0f + hoff,
0.0f + hoff,
m_fPerTexelHeight + hoff,
- m_fPerTexelHeight + hoff };
// write all these offsets to constant memory
for ( i = 0; i < 4; ++i)
{
D3DXVECTOR4 type4Offset(type4OffsetX[i], type4OffsetY[i], 0.0f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_UV_T0_TYPE4 + 5*i, &type4Offset, 1);
}
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);
// add blurred previous output texture
// 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 );
for( i=0; i < 4; i++ )
{
m_pD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
m_pD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
}
pix_mult[0] = m_fColorAtten * 1.0; // red
pix_mult[1] = m_fColorAtten * 1.0; // green
pix_mult[2] = m_fColorAtten * 1.0; // green
pix_mult[3] = 0.0f; // alpha
hr = m_pD3DDev->SetPixelShaderConstant( PCN_MULTFACTOR_2, &pix_mult, 1 );
ASSERT_IF_FAILED(hr);
if( m_bMulticolor )
{
pix_mult[0] = m_fColorAtten * 0.95f; // red
pix_mult[1] = m_fColorAtten * 1.05f; // green
pix_mult[2] = m_fColorAtten * 1.09f; // blue
pix_mult[3] = 0.0f; // alpha
}
hr = m_pD3DDev->SetPixelShaderConstant( PCN_MULTFACTOR_1, &pix_mult, 1 );
ASSERT_IF_FAILED(hr);
//@@@@@@@@
hr = SetStep_Average_4_Nearest( mpFilterTarget[m_nTarget3], mpTextureFiltered[m_nTarget4] );
ASSERT_IF_FAILED(hr);
m_pOutputSrc = mpTextureFiltered[m_nTarget3];
offset.x = 4.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
// draw the fan with displaced texture coordinates
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
ASSERT_IF_FAILED(hr);
for( i=0; i < 4; i++ )
{
m_pD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_POINT );
m_pD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_POINT );
}
/////////////////////////////////////////////////////////////////
// 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 = SetPixelShader( m_dwDependentAR );
ASSERT_IF_FAILED( hr );
hr = m_pD3DDev->SetRenderTarget( mpFilterTarget[m_nTarget4], NULL);
ASSERT_IF_FAILED(hr);
m_pOutputSrc = mpTextureFiltered[m_nTarget4];
// Render using offsets of zero
offset.x = 0.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
hr = m_pD3DDev->SetTexture(0, mpTextureFiltered[m_nTarget3] );
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;
}
void CA_Fire::CreateAndWriteUVOffsets(int width, int height)
{
// This sets vertex shader constants used to displace the
// source texture over several additive samples. This is
// used to accumulate neighboring texel information that we
// need to run the game - the 8 surrounding texels, and the
// single source texel which will either spawn or die in the
// next generation.
// Label the texels as follows, for a source texel "e" that
// we want to compute for the next generation:
//
// abc
// def
// ghi:
// first the easy one: no offsets for sampling center
// occupied or unoccupied
// Use index offset value 0.0 to access these in the
// vertex shader.
m_fPerTexelWidth = 1.0f/static_cast<float>(width);
m_fPerTexelHeight = 1.0f/static_cast<float>(height);
HRESULT hr;
// Change the multiplier to 2 or 3 to spread the texel sampling. This
// has the effect of running several independent "games" in neighboring
// texels, which do not affect eachother.
m_fPerTexelWidth *= 1; // 1 = no change - run standard game of life
m_fPerTexelHeight *= 1;
float woff, hoff;
woff = m_fPerTexelWidth/2.0f;
hoff = m_fPerTexelHeight/2.0f;
// Ofset set 0 : center texel sampling
float noOffsetX[4] = { woff,woff,woff,woff };
float noOffsetY[4] = { hoff,hoff,hoff,hoff };
// Offset set 1: Nearest neighbors - b,d,f,h texels
// Use index offset 1.0 to access these
float type1OffsetX[4] = { - m_fPerTexelWidth + woff,
m_fPerTexelWidth + woff,
0.0f + woff,
0.0f + woff };
float type1OffsetY[4] = { 0.0f + hoff,
0.0f + hoff,
m_fPerTexelHeight + hoff,
- m_fPerTexelHeight + hoff };
// These are a,c,g,i texels == diagonal neightbors
// Use index offset 2.0 to use these
float type2OffsetX[4] = { - m_fPerTexelWidth,
- m_fPerTexelWidth,
m_fPerTexelWidth,
m_fPerTexelWidth };
float type2OffsetY[4] = { - m_fPerTexelHeight,
m_fPerTexelHeight,
m_fPerTexelHeight,
- m_fPerTexelHeight };
// These offsets are for use with bilinear filtering
// of the neighbors, to sample all 8 neighbors in
// one pass instead of two. Bilinear averages the
// two bordering texels, but the coordinate must be
// exactly on the texel border to make this work.
// [0] = on the border of the ab texels
// [1] = between cf texels
// [2] = between ih texels
// [3] = between gd texels
float type3OffsetX[4] = { - m_fPerTexelWidth/2.0f + woff,
m_fPerTexelWidth + woff,
m_fPerTexelWidth/2.0f + woff,
- m_fPerTexelWidth + woff };
float type3OffsetY[4] = { - m_fPerTexelHeight + hoff,
- m_fPerTexelHeight/2.0f + hoff,
m_fPerTexelHeight + hoff,
m_fPerTexelHeight/2.0f + hoff };
// drifing uppder
// hoff += -m_fPerTexelHeight;
/*
float type4OffsetX[4] = { - m_fPerTexelWidth + woff,
m_fPerTexelWidth + woff,
0.0f + woff,
0.0f + woff };
float type4OffsetY[4] = { 0.0f + hoff,
0.0f + hoff,
m_fPerTexelHeight + hoff,
- m_fPerTexelHeight + hoff };
*/
hoff += -3.5f * m_fPerTexelHeight;
float type4OffsetX[4] = { - m_fPerTexelWidth + woff,
m_fPerTexelWidth + woff,
0.0f + woff,
0.0f + woff };
float type4OffsetY[4] = { 0.0f + hoff,
0.0f + hoff,
m_fPerTexelHeight + hoff,
- m_fPerTexelHeight + hoff };
// write all these offsets to constant memory
for (int i = 0; i < 4; ++i)
{
D3DXVECTOR4 noOffset( noOffsetX[i], noOffsetY[i], 0.0f, 0.0f);
D3DXVECTOR4 type1Offset(type1OffsetX[i], type1OffsetY[i], 0.0f, 0.0f);
D3DXVECTOR4 type2Offset(type2OffsetX[i], type2OffsetY[i], 0.0f, 0.0f);
D3DXVECTOR4 type3Offset(type3OffsetX[i], type3OffsetY[i], 0.0f, 0.0f);
D3DXVECTOR4 type4Offset(type4OffsetX[i], type4OffsetY[i], 0.0f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_UV_T0_NO_OFFSET + 5*i, &noOffset, 1);
m_pD3DDev->SetVertexShaderConstant(CV_UV_T0_TYPE1 + 5*i, &type1Offset, 1);
m_pD3DDev->SetVertexShaderConstant(CV_UV_T0_TYPE2 + 5*i, &type2Offset, 1);
m_pD3DDev->SetVertexShaderConstant(CV_UV_T0_TYPE3 + 5*i, &type3Offset, 1);
m_pD3DDev->SetVertexShaderConstant(CV_UV_T0_TYPE4 + 5*i, &type4Offset, 1);
}
// Set pixel shader consts:
// This constant is a color mask - It is used to only keep the
// green component for the accumulation of neighbor texel info.
// Mult the source green by 1/8 to get the average of the 8 samples,
// with a max of 1.0f
/// R,G,B,A
float pix_mult[4] = { 0.0f, 0.125f, 0.0f, 0.0f };
hr = m_pD3DDev->SetPixelShaderConstant( PCN_MULTFACTOR_1, &pix_mult, 1 );
ASSERT_IF_FAILED(hr);
hr = m_pD3DDev->SetPixelShaderConstant( PCN_MULTFACTOR_2, &pix_mult, 1 );
ASSERT_IF_FAILED(hr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -