📄 ca_water.cpp
字号:
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");
}
int tmp;
switch( m_nFlipState )
{
case 0:
m_nThreshCnt = 0;
m_pTex_HeightSrc = m_pInitialStateTexture->GetTexture();
m_nTex_HeightTarg = 0;
m_nTex_HeightSrc = 4;
m_pTex_HeightTarg = mpFilterTarget[m_nTex_HeightTarg];
m_nTex_VelSrc = 1;
m_nTex_VelTarg = 2;
m_pTex_VelTarg = mpFilterTarget[m_nTex_VelTarg];
m_pTex_VelCurSrc = mpTextureFiltered[m_nTex_VelTarg];
m_pTex_VelPrevSrc = mpTextureFiltered[m_nTex_VelSrc];
m_pIntermediateTarg = mpFilterTarget[3];
m_pIntermediateSrc = mpTextureFiltered[3];
m_pInt_FinalTarg = mpFilterTarget[5];
m_pInt_FinalSrc = mpTextureFiltered[5];
// use old ht src as temp place to render normals
m_nTex_NrmlAccum = m_nTex_HeightSrc;
m_nTex_NrmlTarg = 3; // use force tex as place to keep em
// Clear initial velocity texture to 0 == gray
hr = m_pD3DDev->SetRenderTarget( mpFilterTarget[1], NULL);
ASSERT_IF_FAILED( hr );
hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0x80, 0x80, 0x80 ), 1.0, 0);
break;
case 1:
// Both to 2 as we never read & write height simultaneously so this is ok
tmp = m_nTex_HeightTarg;
m_nTex_HeightTarg = m_nTex_HeightSrc;
m_nTex_HeightSrc = tmp;
m_pTex_HeightTarg = mpFilterTarget[m_nTex_HeightTarg];
m_pTex_HeightSrc = mpTextureFiltered[m_nTex_HeightSrc];
m_nTex_VelSrc = 2;
m_nTex_VelTarg = 1;
m_pTex_VelTarg = mpFilterTarget[m_nTex_VelTarg];
m_pTex_VelCurSrc = mpTextureFiltered[m_nTex_VelTarg];
m_pTex_VelPrevSrc = mpTextureFiltered[m_nTex_VelSrc];
m_pIntermediateTarg = mpFilterTarget[3];
m_pIntermediateSrc = mpTextureFiltered[3];
m_pInt_FinalTarg = mpFilterTarget[5];
m_pInt_FinalSrc = mpTextureFiltered[5];
// use old ht src as temp place to render normals
m_nTex_NrmlAccum = m_nTex_HeightSrc;
m_nTex_NrmlTarg = 3; // use force tex as place to keep em
break;
case 2:
tmp = m_nTex_HeightTarg;
m_nTex_HeightTarg = m_nTex_HeightSrc;
m_nTex_HeightSrc = tmp;
m_pTex_HeightTarg = mpFilterTarget[m_nTex_HeightTarg];
m_pTex_HeightSrc = mpTextureFiltered[m_nTex_HeightSrc];
m_nTex_VelSrc = 1;
m_nTex_VelTarg = 2;
m_pTex_VelTarg = mpFilterTarget[m_nTex_VelTarg];
m_pTex_VelCurSrc = mpTextureFiltered[m_nTex_VelTarg];
m_pTex_VelPrevSrc = mpTextureFiltered[m_nTex_VelSrc];
m_pIntermediateTarg = mpFilterTarget[3];
m_pIntermediateSrc = mpTextureFiltered[3];
m_pInt_FinalTarg = mpFilterTarget[5];
m_pInt_FinalSrc = mpTextureFiltered[5];
// use old ht src as temp place to render normals
m_nTex_NrmlAccum = m_nTex_HeightSrc;
m_nTex_NrmlTarg = 3; // use force tex as place to keep em
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(50);
}
if( m_bSlow )
{
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 );
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
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 );
}
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_NrmlTarg] );
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, m_pTex_VelCurSrc );
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, m_pInitialStateTexture->GetTexture()); // upper left corner
//m_pD3DDev->SetTexture(0, m_pTex_VelPrevSrc ); // upper left corner
m_pD3DDev->SetTexture(0, m_pTex_VelCurSrc ); // upper left corner
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( m_bFarther )
{
if( j==1 )
{
pSrcTex = m_pInt_FinalSrc; // low right corner
pSrcTex = mpTextureFiltered[3];
}
else if( j==2 )
{
pSrcTex = m_pTex_VelCurSrc; // low left corner
}
}
else
{
if( j==1 )
{
pSrcTex = mpTextureFiltered[3];
}
else if( j==2 )
{
pSrcTex = m_pTex_VelCurSrc;
}
}
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++;
}
return( hr );
}
HRESULT CA_Water::SetStep_Average_4_Nearest( IDirect3DSurface8 * pTarget,
IDirect3DTexture8 * pSrcTex )
{
HRESULT hr;
assert( pTarget != NULL );
assert( pSrcTex != NULL );
hr = m_pD3DDev->SetRenderTarget( pTarget, NULL );
ASSERT_IF_FAILED(hr);
// Render 1st using offset set 1 - for nearest neighbor pixels
const D3DXVECTOR4 offset( 1.0f, 0.0f, 0.0f, 0.0f );
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
m_pD3DDev->SetTexture(0, pSrcTex );
m_pD3DDev->SetTexture(1, pSrcTex );
m_pD3DDev->SetTexture(2, pSrcTex );
m_pD3DDev->SetTexture(3, pSrcTex );
return hr;
}
HRESULT CA_Water::SetStep_Average_4_Diagonal( IDirect3DSurface8 * pTarget,
IDirect3DTexture8 * pSrcTex )
{
HRESULT hr;
assert( pTarget != NULL );
assert( pSrcTex != NULL );
hr = m_pD3DDev->SetRenderTarget( pTarget, NULL );
ASSERT_IF_FAILED(hr);
// Render 1st using offset set 1 - for nearest neighbor pixels
const D3DXVECTOR4 offset( 2.0f, 0.0f, 0.0f, 0.0f );
m_pD3DDev->SetVertexShaderConstant(CV_UV_OFFSET_TO_USE, &offset, 1);
m_pD3DDev->SetTexture(0, pSrcTex );
m_pD3DDev->SetTexture(1, pSrcTex );
m_pD3DDev->SetTexture(2, pSrcTex );
m_pD3DDev->SetTexture(3, pSrcTex );
return hr;
}
void CA_Water::UpdateBlurVertOffset()
{
float woff, hoff;
woff = m_fPerTexelWidth / 2.0f;
hoff = m_fPerTexelHeight / 2.0f;
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 };
float interp_x, interp_y;
for (int i = 0; i < 4; ++i)
{
interp_x = m_fBlurDist * ( type3OffsetX[i] - woff ) + woff;
interp_y = m_fBlurDist * ( type3OffsetY[i] - hoff ) + hoff;
D3DXVECTOR4 vec_type3Offset( interp_x, interp_y, 0.0f, 0.0f);
m_pD3DDev->SetVertexShaderConstant(CV_UV_T0_TYPE3 + 5*i, &vec_type3Offset, 1);
}
}
void CA_Water::DrawInteriorBoundaryObjects()
{
bool bInlineDroplet = true;
HRESULT hr;
assert( m_pD3DDev != NULL );
int i;
IDirect3DSurface8 *pBack_Color;
IDirect3DSurface8 *pBack_Depth;
/////////////////////////////
const int numobjects = 1;
int ind = 0;
float xmin[numobjects];
float xmax[numobjects];
float ymin[numobjects];
float ymax[numobjects];
DWORD color = 0x00000000; // ARGB
xmin[ind] = 0.0f;
xmax[ind] = 1.0f;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -