📄 ca_water.cpp
字号:
{
return S_OK;
}
HRESULT CA_Water::CreateTextureRenderTarget()
{
HRESULT hr;
_ASSERT( mpBackbufferColor != NULL );
_ASSERT( mpBackbufferDepth != NULL );
// get the description for the texture we want to filter
D3DSURFACE_DESC ddsd;
m_pInitialStateTexture->GetTexture()->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;
}
// set our render target to the new and shiny textures without depth
hr = m_pD3DDev->SetRenderTarget(mpFilterTarget[i], NULL);
if (FAILED(hr))
{
m_strLastError = "Can't SetRenderTarget to new surface!\n";
assert(false);
return E_FAIL;
}
}
// 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_Water::SetPixelShader( DWORD dwHandle )
{
HRESULT hr = S_OK;
assert( m_pD3DDev != NULL );
hr = m_pD3DDev->SetPixelShader( dwHandle );
ASSERT_IF_FAILED(hr);
m_dwCurrentPixelShader = dwHandle;
return hr;
}
HRESULT CA_Water::SetVertexShader( DWORD dwHandle )
{
HRESULT hr = S_OK;
assert( m_pD3DDev != NULL );
hr = m_pD3DDev->SetVertexShader( dwHandle );
ASSERT_IF_FAILED(hr);
m_dwCurrentVertexShader = dwHandle;
return hr;
}
bool CA_Water::Keyboard(DWORD dwKey, UINT nFlags, bool bDown)
{
// Return true if keyboard key handled.
// Note - pressing tidle key will not cause this to be called
// until the window is resized - Something happens then to
// trigger the Keyboard function.
char charcode;
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;
FDebug("m_dwSleepDelay: %d\n", m_dwSleepDelay );
return(true);
break;
case VK_LEFT:
if( m_dwSleepDelay > 1 )
m_dwSleepDelay -= 2;
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 'I':
case 'L':
m_bApplyInteriorBoundaries = !m_bApplyInteriorBoundaries;
FDebug("Apply interior boundaries: %s\n", m_bApplyInteriorBoundaries ? "TRUE" : "FALSE");
return(true);
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 'M':
// m_bUseNormalMapMethod2 = !m_bUseNormalMapMethod2;
// FDebug("Use normal map method 2 = %s\n", m_bUseNormalMapMethod2 ? "TRUE" : "FALSE" );
FDebug("you hit M!\n");
m_SimulationMode ++;
if( m_SimulationMode >= SM_LAST )
{
m_SimulationMode = NORMAL_GRAY;
}
FDebug("Sim mode == %d\n", m_SimulationMode );
SetSimMode( m_SimulationMode );
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_CURRENT_POSITION;
FDebug("displaying finalout = height field\n");
return(true);
break;
case 'F':
m_bFarther = !m_bFarther;
return(true);
break;
case 'R':
case '`':
case '~':
FDebug("Loading new droplet and initial maps\n");
LoadRulesAndOtherMaps();
return(true);
break;
case 'G':
// start or stop the animation
m_bAnimate = !m_bAnimate;
return(true);
break;
case VK_SPACE:
m_bSingleStep = !m_bSingleStep;
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 '7':
m_nLowThresh--;
FDebug("low thresh %d\n", m_nLowThresh );
return(true);
break;
case '8':
m_nLowThresh++;
FDebug("low thresh %d\n", m_nLowThresh );
return(true);
break;
case '9':
m_fhalfoff *= 0.9999f;
m_nThresh--;
FDebug("half offset value %f\n", m_fhalfoff );
FDebug("thresh %d\n", m_nThresh );
return(true);
break;
case '0':
m_fhalfoff *= 1.0001f;
m_nThresh++;
FDebug("half offset value %f\n", m_fhalfoff );
FDebug("thresh %d\n", m_nThresh );
return(true);
break;
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_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;
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
SetVertexShader( m_dwVertexShader );
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");
}
int tmp;
switch( m_nFlipState )
{
case 0:
m_nThreshCnt = 0;
m_pTex_HeightSrc = m_pInitialStateTexture->GetTexture();
m_nTex_HeightTarg = 0;
m_nTex_HeightSrc = 4;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -