📄 water.cpp
字号:
D3DXVECTOR4 f4StepSize = D3DXVECTOR4(1.0f/(float)g_iGridSizeX, 1.0f/(float)g_iGridSizeY,0,0);
UINT cPasses;
g_pMainShader->Begin(&cPasses, 0);
g_pMainShader->SetTexture("tHeightMap",g_cluUCurrent->m_pVectorTexture);
g_pMainShader->SetTexture("tRefractMap", g_pCubePoolView);
g_pMainShader->SetVector("f4StepSize", &f4StepSize);
pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(TEXVERTEX2D) );
pd3dDevice->SetFVF( TEXVERTEX2D::FVF );
g_pMainShader->BeginPass(0);
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pMainShader->EndPass();
g_pMainShader->End();
g_pBufferRenderSurface->EndScene( 0 );
if (g_bWireFrame) pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME );
// Begin the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) ) {
// Clear the viewport
pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0,0,0,0), 1.0f, 0L );
pd3dDevice->SetTexture( 0, g_pBufferTexture );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(TEXVERTEX2D) );
pd3dDevice->SetFVF( TEXVERTEX2D::FVF );
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
RenderText(fElapsedTime);
RenderUI(fElapsedTime);
V( pd3dDevice->EndScene() );
}
}
//--------------------------------------------------------------------------------------
// Render the UI elements such as sliders buttons etc.
//--------------------------------------------------------------------------------------
HRESULT RenderUI(float fElapsedTime)
{
HRESULT hr;
if (!g_bShowUI) return S_OK;
V( g_HUD.OnRender( fElapsedTime ) );
V( g_WaterUI.OnRender( fElapsedTime ) );
return S_OK;
}
//--------------------------------------------------------------------------------------
// Render the help and statistics text. This function uses the ID3DXFont interface for
// efficient text rendering.
//--------------------------------------------------------------------------------------
void RenderText(float fElapsedTime)
{
if (!g_bShowText) return;
// The helper object simply helps keep track of text position, and color
// and then it calls pFont->DrawText( g_pSprite, strMsg, -1, &rc, DT_NOCLIP, g_clr );
// If NULL is passed in as the sprite object, then it will work however the
// pFont->DrawText() will not be batched together. Batching calls will improves performance.
const D3DSURFACE_DESC* pd3dsdBackBuffer = DXUTGetBackBufferSurfaceDesc();
CDXUTTextHelper txtHelper( g_pFont, g_pTextSprite, 15 );
// Output statistics
txtHelper.Begin();
txtHelper.SetInsertionPos( 5, 5 );
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );
txtHelper.DrawTextLine( DXUTGetFrameStats() );
txtHelper.DrawTextLine( DXUTGetDeviceStats() );
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
TCHAR test[100];
_sntprintf(test,99,_T("Gridsize %i x %i"),g_iGridSizeX,g_iGridSizeY);
txtHelper.DrawTextLine(test);
// Draw help
if( g_bShowHelp )
{
txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*6 );
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );
txtHelper.DrawTextLine( L"Controls (F1 to hide):" );
txtHelper.SetInsertionPos( 40, pd3dsdBackBuffer->Height-15*5 );
txtHelper.DrawTextLine( L"Toggle UI Display: u\n"
L"Toggle Text Display: t\n"
L"Toggle Rain: SPACE\n"
L"Quit: ESC" );
}
else
{
txtHelper.SetInsertionPos( 10, pd3dsdBackBuffer->Height-15*2 );
txtHelper.SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );
txtHelper.DrawTextLine( L"Press F1 for help" );
}
txtHelper.End();
}
//--------------------------------------------------------------------------------------
// Before handling window messages, the sample framework passes incoming windows
// messages to the application through this callback function. If the application sets
// *pbNoFurtherProcessing to TRUE, then the sample framework will not process this message.
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing )
{
g_bIsGUIEvent = true;
// Give the dialogs a chance to handle the message first
*pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );
if( *pbNoFurtherProcessing ) return 0;
*pbNoFurtherProcessing = g_WaterUI.MsgProc( hWnd, uMsg, wParam, lParam );
if( *pbNoFurtherProcessing ) return 0;
g_bIsGUIEvent = false;
// Pass all remaining windows messages to camera so it can respond to user input
g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
return 0;
}
//--------------------------------------------------------------------------------------
// As a convenience, the sample framework inspects the incoming windows messages for
// keystroke messages and decodes the message parameters to pass relevant keyboard
// messages to the application. The framework does not remove the underlying keystroke
// messages, which are still passed to the application's MsgProc callback.
//--------------------------------------------------------------------------------------
void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown )
{
if( bKeyDown )
{
switch( nChar )
{
case VK_F1 : g_bShowHelp = !g_bShowHelp; break;
case 'W' : g_bWireFrame = !g_bWireFrame; break;
case ' ' : g_WaterUI.EnableNonUserEvents(true);
g_WaterUI.GetCheckBox(IDC_CBOX_RAIN)->SetChecked(!g_bRainMode);
g_WaterUI.EnableNonUserEvents(false);
break;
case 'U' : g_bShowUI = !g_bShowUI; break;
case 'T' : g_bShowText = !g_bShowText; break;
case 'X' : g_iGridSizeX = (bAltDown) ? g_iGridSizeX*2 : g_iGridSizeX/2; ResizeGrid();break;
case 'Y' : g_iGridSizeY = (bAltDown) ? g_iGridSizeY*2 : g_iGridSizeY/2; ResizeGrid();break;
case VK_DOWN : g_iRainDelay = MIN(g_iRainDelay+1,100); g_WaterUI.GetSlider( IDC_SLIDER_RAIN )->SetValue(100/g_iRainDelay); break;
case VK_UP : g_iRainDelay = MAX(g_iRainDelay-1,1); g_WaterUI.GetSlider( IDC_SLIDER_RAIN )->SetValue(100/g_iRainDelay); break;
case VK_RIGHT : g_fC = MIN(g_fC*1.1f,1); ChangeViscosity(int(g_fC*100)); g_WaterUI.GetSlider( IDC_SLIDER_VIS )->SetValue(int(g_fC*100)); break;
case VK_LEFT : g_fC = MAX(g_fC/1.1f,0.1f); ChangeViscosity(int(g_fC*100)); g_WaterUI.GetSlider( IDC_SLIDER_VIS )->SetValue(int(g_fC*100)); break;
case 'P' : g_bTimeclPerformance = true;
}
}
}
void ResizeGrid() {
OnLostDevice();
OnDestroyDevice();
OnCreateDevice(g_pd3dDevice, g_pBackBufferSurfaceDesc);
OnResetDevice(g_pd3dDevice, g_pBackBufferSurfaceDesc);
}
void ChangeViscosity(int iValue) {
g_fC = iValue / 100.0f;
#ifdef useUpacked
clCrNiMatrix *cnMatrix = static_cast<clCrNiMatrix*>(g_pCGSolver->getMatrix());
#else
clPackedCrNiMatrix *cnMatrix = static_cast<clPackedCrNiMatrix*>(g_pCGSolver->getMatrix());
#endif
cnMatrix->setC(g_fC);
g_cluRHS->setC(g_fC);
}
void ChangeRain(int iValue) {
g_iRainDelay = int(100/iValue);
}
void ToggleRain(bool bIsRain) {
g_bRainMode = bIsRain;
g_WaterUI.GetSlider( IDC_SLIDER_RAIN )->SetEnabled(bIsRain);
}
//--------------------------------------------------------------------------------------
// Handles the GUI events
//--------------------------------------------------------------------------------------
void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl )
{
switch( nControlID )
{
case IDC_TOGGLEFULLSCREEN: DXUTToggleFullScreen(); break;
case IDC_TOGGLEREF: DXUTToggleREF(); break;
case IDC_CHANGEDEVICE: DXUTSetShowSettingsDialog( !DXUTGetShowSettingsDialog() ); break;
case IDC_TOGGLEUI: g_bShowUI = !g_bShowUI;break;
case IDC_CBOX_RAIN: ToggleRain(g_WaterUI.GetCheckBox(IDC_CBOX_RAIN)->GetChecked() );break;
case IDC_SLIDER_VIS: ChangeViscosity(g_WaterUI.GetSlider( IDC_SLIDER_VIS )->GetValue());
case IDC_SLIDER_RAIN: ChangeRain(g_WaterUI.GetSlider( IDC_SLIDER_RAIN )->GetValue());
}
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has
// entered a lost state and before IDirect3DDevice9::Reset is called. Resources created
// in the OnResetDevice callback should be released here, which generally includes all
// D3DPOOL_DEFAULT resources. See the "Lost Devices" section of the documentation for
// information about lost devices.
//--------------------------------------------------------------------------------------
void CALLBACK OnLostDevice()
{
if( g_pFont ) g_pFont->OnLostDevice();
SAFE_RELEASE( g_pTextSprite );
SAFE_RELEASE( g_pVB );
SAFE_RELEASE( g_pVBGrid );
SAFE_RELEASE( g_pIBGrid );
SAFE_RELEASE( g_pMainShader );
SAFE_RELEASE( g_pBufferRenderSurface );
SAFE_RELEASE( g_pBufferTexture );
SAFE_RELEASE( g_pBufferTextureSurface );
SAFE_DELETE( g_pCGSolver ); // deleting the solver implitly deletes "g_clUNext" and "g_clRHS"
#ifndef useUpacked
SAFE_DELETE( g_cluRHS );
#endif
SAFE_DELETE( g_cluUCurrent );
SAFE_DELETE( g_cluULast );
SAFE_RELEASE( g_pCubePoolView );
clClass::ShutdownCLFrameWork();
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has
// been destroyed, which generally happens as a result of application termination or
// windowed/full screen toggles. Resources created in the OnCreateDevice callback
// should be released here, which generally includes all D3DPOOL_MANAGED resources.
//--------------------------------------------------------------------------------------
void CALLBACK OnDestroyDevice()
{
SAFE_RELEASE( g_pFont );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -