📄 ca_water.cpp
字号:
float eqinc = 0.05f;
float blurinc = 0.01f;
float normalinc = 0.01f;
if( bDown )
{
// Use only capital letters here - these are VK_ codes!
switch( dwKey )
{
case VK_RIGHT:
if( m_dwSleepDelay < 500 )
m_dwSleepDelay += 2;
m_bSlow = true;
FDebug("m_dwSleepDelay: %d\n", m_dwSleepDelay );
return(true);
break;
case VK_LEFT:
if( m_dwSleepDelay > 1 )
m_dwSleepDelay -= 2;
m_bSlow = true;
FDebug("m_dwSleepDelay: %d\n", m_dwSleepDelay );
return(true);
break;
case VK_UP:
m_fDropletFreq += 0.05f;
if( m_fDropletFreq > 1.0f )
m_fDropletFreq = 1.0f;
FDebug("Droplet Frequency: %f\n", m_fDropletFreq );
return(true);
break;
case VK_DOWN:
m_fDropletFreq -= 0.05f;
if( m_fDropletFreq < 0.0f )
m_fDropletFreq = 0.0f;
FDebug("Droplet Frequency: %f\n", m_fDropletFreq );
return(true);
break;
case VK_RETURN:
// single step
m_bAnimate = false;
m_bSingleStep = !m_bSingleStep;
return(true);
break;
case VK_SPACE:
// start or stop the animation
m_bAnimate = !m_bAnimate;
return(true);
break;
case 'I':
case 'L':
m_bApplyInteriorBoundaries = !m_bApplyInteriorBoundaries;
FDebug("Apply interior boundaries: %s\n", m_bApplyInteriorBoundaries ? "TRUE" : "FALSE");
return(true);
break;
//@@ Difference from standard CA_Water class
case 'M':
break;
case 'Z':
if( m_fEqRestore_factor >= eqinc )
m_fEqRestore_factor -= eqinc;
else
m_fEqRestore_factor = 0.0f;
FDebug("m_fEqRestore_factor: %f\n", m_fEqRestore_factor );
return(true);
break;
case 'X':
if( m_fEqRestore_factor <= 1.0f - eqinc )
m_fEqRestore_factor += eqinc;
else
m_fEqRestore_factor = 1.0f;
FDebug("m_fEqRestore_factor: %f\n", m_fEqRestore_factor );
return(true);
break;
case 'C':
if( m_fBlurDist >= blurinc )
m_fBlurDist -= blurinc;
FDebug("m_fBlurDist: %f\n", m_fBlurDist );
UpdateBlurVertOffset();
return(true);
break;
case 'V':
if( m_fBlurDist <= 1.0f - blurinc )
m_fBlurDist += blurinc;
FDebug("m_fBlurDist: %f\n", m_fBlurDist );
UpdateBlurVertOffset();
return(true);
break;
case 'B':
m_bWrap = !m_bWrap;
FDebug("Wrap mode: %d\n", m_bWrap );
return(true);
break;
case 'Y':
if( m_fNrmlSTScale >= normalinc )
m_fNrmlSTScale -= normalinc;
FDebug("Normal ST scale for red & green: %f\n", m_fNrmlSTScale );
return(true);
break;
case 'U':
if( m_fNrmlSTScale <= 1.0f - normalinc )
m_fNrmlSTScale += normalinc;
FDebug("Normal ST scale for red & green: %f\n", m_fNrmlSTScale );
return(true);
break;
case '1' :
m_eRenderMode = FULLSCREEN_NEIGHBOR_CALC;
FDebug("displaying neighbor calc = force texture\n");
return(true);
break;
case '2':
m_eRenderMode = FULLSCREEN_RESULT;
FDebug("displaying result = velocity\n");
return(true);
break;
case '3' :
m_eRenderMode = ALL_TOGETHER;
FDebug("displaying all surfs\n");
return(true);
break;
case '4':
m_eRenderMode = FULLSCREEN_FINALOUT;
FDebug("displaying finalout = height field\n");
return(true);
break;
case 'R':
case '`':
case '~':
FDebug("Loading new droplet and initial maps\n");
LoadRulesAndOtherMaps();
return(true);
break;
case 'S':
m_bSlow = !m_bSlow;
return(true);
break;
case 'W':
m_bWireframe = !m_bWireframe;
return(false);
break;
default:
charcode = MapVirtualKey( dwKey, 2 ); // VK to char code
switch( charcode )
{
case '<':
case ',':
m_fVelFactor *= 0.98f;
FDebug("velocity factor (mass): %f\n", m_fVelFactor );
return(true);
break;
case '>':
case '.':
m_fVelFactor *= 1.02f;
FDebug("velocity factor (mass): %f\n", m_fVelFactor );
return(true);
break;
case '[':
case '{':
m_fBlend *= 0.98f;
FDebug("blend: %f\n", m_fBlend );
return(true);
break;
case ']':
case '}':
m_fBlend *= 1.02f;
FDebug("blend: %f\n", m_fBlend );
return(true);
break;
};
};
}
return( false );
}
void CA_Water::SetInitialRenderStates()
{
int i;
// set up render state: disable all except texture stage 0 (see below)
for(i = 0; i < 4; i++ )
{
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_ZWRITEENABLE, 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 );
}
HRESULT CA_Water::Tick()
{
// Render a new frame
HRESULT hr;
int i;
SetInitialRenderStates();
D3DXMATRIX matWorld;
D3DXMATRIX matView;
D3DXMATRIX matProj;
D3DXMATRIX matViewProj;
// 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
hr = m_pD3DDev->SetVertexShader( m_dwVertexShader );
ASSERT_IF_FAILED(hr);
hr = m_pD3DDev->SetStreamSource(0, m_pVertexBuffer, sizeof(QuadVertex));
ASSERT_IF_FAILED(hr);
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(&m_mWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&m_mWorldViewProj, &m_mWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_mWorldViewProj(0, 0), 4);
if( m_bReset == true )
{
m_bReset = false;
m_nFlipState = 0;
FDebug("Reset water sim to initial conditions\n");
}
if( m_bAnimate == true )
{
// Update the textures for one step of the
// game or cellular automata
DoSingleTimeStep();
}
else if( m_bSingleStep == true )
{
DoSingleTimeStep();
m_bSingleStep = false;
}
if( m_bSlow )
{
// slow down the rendering and give any other apps a chance
Sleep( m_dwSleepDelay );
}
IDirect3DTexture8 * pSrcTex;
static int nSkip = 0;
if( nSkip >= m_nSkipInterval && m_bDrawOutput == true )
{
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 );
// No need to clear - We overdraw the whole backbuffer
// No z test
hr = m_pD3DDev->SetRenderState( D3DRS_ZENABLE, false );
ASSERT_IF_FAILED(hr);
m_pD3DDev->SetRenderState( D3DRS_ZWRITEENABLE, false );
// turn off pixel shading
m_pD3DDev->SetPixelShader( 0 );
//////////////////////////////////////////////////////////
// Render the result of the calculations to the device
// These steps are not needed to run the simulation - for final
// display of the results only
if( m_bWireframe )
{
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0,0,0 ), 1.0, 0);
ASSERT_IF_FAILED(hr);
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 );
}
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(&m_mWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&m_mWorldViewProj, &m_mWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_mWorldViewProj(0, 0), 4);
// reset offsets to 0 (ie no offsets)
offset.x = 0.0f;
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
hr = m_pD3DDev->SetTexture(0, mpTextureFiltered[m_nTex_HeightTarg] );
ASSERT_IF_FAILED(hr);
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
ASSERT_IF_FAILED(hr);
break;
case FULLSCREEN_RESULT :
// Draw quad over full display
D3DXMatrixScaling(&matWorld, 2.0f, 2.0f, 1.0f);
D3DXMatrixMultiply(&m_mWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&m_mWorldViewProj, &m_mWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_mWorldViewProj(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_nTex_VelTarg] );
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(&m_mWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&m_mWorldViewProj, &m_mWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_mWorldViewProj(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[3] );
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(&m_mWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&m_mWorldViewProj, &m_mWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_mWorldViewProj(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_nTex_VelTarg] ); // upper left corner
if( m_SimulationMode == SM_RGB_GLOW ||
m_SimulationMode == SM_HUE_DROPLETS )
{
m_pD3DDev->SetTexture(0, mpTextureFiltered[m_nTex_HeightTarg] );
}
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(&m_mWorldViewProj, &matWorld, &matViewProj);
D3DXMatrixTranspose(&m_mWorldViewProj, &m_mWorldViewProj);
m_pD3DDev->SetVertexShaderConstant(CV_WORLDVIEWPROJ_0, &m_mWorldViewProj(0, 0), 4);
// case for upper right display
pSrcTex = mpTextureFiltered[m_nTex_HeightTarg]; // upper right corner;
if( j==1 )
{
pSrcTex = mpTextureFiltered[3];
}
else if( j==2 )
{
pSrcTex = mpTextureFiltered[m_nTex_VelTarg];
}
// if one of these modes, want to display same texture in all 4
// panes, to show texture wrapping.
if( m_SimulationMode == SM_RGB_GLOW ||
m_SimulationMode == SM_HUE_DROPLETS )
{
pSrcTex = mpTextureFiltered[m_nTex_HeightTarg];
}
if( pSrcTex != 0 )
{
m_pD3DDev->SetTexture(0, pSrcTex );
hr = m_pD3DDev->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, 2);
}
else
{
FDebug("bad texture pointer in result display!!\n");
}
}
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++;
}
// Reset bilinear filtering, as that is most common
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -