📄 water.cpp
字号:
V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE,
L"Arial", &g_pFont ) );
// Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the
// shader debugger. Debugging vertex shaders requires either REF or software vertex
// processing, and debugging pixel shaders requires REF. The
// D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug experience in the
// shader debugger. It enables source level debugging, prevents instruction
// reordering, prevents dead code elimination, and forces the compiler to compile
// against the next higher available software target, which ensures that the
// unoptimized shaders do not exceed the shader model limitations. Setting these
// flags will cause slower rendering since the shaders will be unoptimized and
// forced into software. See the DirectX documentation for more information about
// using the shader debugger.
DWORD dwShaderFlags = 0;
#ifdef DEBUG_VS
dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
#endif
#ifdef DEBUG_PS
dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
#endif
// Setup the camera's view parameters
D3DXVECTOR3 vecEye(0.0f, 0.0f, -5.0f);
D3DXVECTOR3 vecAt (0.0f, 0.0f, -0.0f);
g_Camera.SetViewParams( &vecEye, &vecAt );
return S_OK;
}
//--------------------------------------------------------------------------------------
// This callback function will be called immediately after the Direct3D device has been
// reset, which will happen after a lost device scenario. This is the best location to
// create D3DPOOL_DEFAULT resources since these resources need to be reloaded whenever
// the device is lost. Resources created here should be released in the OnLostDevice
// callback.
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice,
const D3DSURFACE_DESC* pBackBufferSurfaceDesc )
{
HRESULT hr;
// kick out managed resources to make sure they are uploaded after the default data is loaded to the GPU
pd3dDevice->EvictManagedResources();
g_fDt = 1.0f; g_fDX = 1.0f; g_fDY = 1.0f;
/*
Initialization of conjugate gradients objects
*/
clClass::StartupCLFrameWork(pd3dDevice);
// The pre-order code reserves memory on the GPU thus making texture
// storage more efficiente on some GPUs This code is optional,
// if omitted memory is allocated when needed
#ifdef optNVIDIA
clUnpackedVector::preOrder(g_iGridSizeX,g_iGridSizeY,4+2); // reserve code for 4 unpacked vectors of size g_iGridSizeX*g_iGridSizeY + two for temp purposes
clCrNiMatrix::preOrder(g_iGridSizeX,g_iGridSizeY,1);
clCGSolver::preOrder(g_iGridSizeX,g_iGridSizeY,CL_UNPACKED,1);
clFloat::preOrder(1);
clClass::ms_memoryMananger->createOrders(false);
#else
clUnpackedVector::preOrder(g_iGridSizeX,g_iGridSizeY,3+1);
clPackedVector::preOrder(g_iGridSizeX,g_iGridSizeY,3+2);
clPackedCrNiMatrix::preOrder(g_iGridSizeX,g_iGridSizeY,1);
clCGSolver::preOrder(g_iGridSizeX,g_iGridSizeY,CL_PACKED,1);
clFloat::preOrder(1);
clClass::ms_memoryMananger->createOrders(true);
#endif
// END Pre-Order
g_cluRHS = new clCrNiVector(pd3dDevice,g_iGridSizeX,g_iGridSizeY);
g_cluRHS->setSimulParam(g_fDt,g_fC,g_fDX,g_fDY);
#ifdef useUpacked
clCrNiMatrix *cnMatrix = new clCrNiMatrix(pd3dDevice,g_iGridSizeX,g_iGridSizeY,g_fDt,g_fC,g_fDX,g_fDY);
g_cluUNext = new clUnpackedVector(pd3dDevice,g_iGridSizeX,g_iGridSizeY); g_cluUNext->clear();
g_pCGSolver = new clCGSolver(cnMatrix,g_cluUNext,g_cluRHS,CL_UNPACKED);
#else
clPackedCrNiMatrix *cnMatrix = new clPackedCrNiMatrix(pd3dDevice,g_iGridSizeX,g_iGridSizeY,g_fDt,g_fC,g_fDX,g_fDY);
g_clUNext = new clPackedVector(pd3dDevice,g_iGridSizeX,g_iGridSizeY); g_clUNext->clear();
g_clRHS = new clPackedVector(pd3dDevice,g_iGridSizeX,g_iGridSizeY);
g_pCGSolver = new clCGSolver(cnMatrix,g_clUNext,g_clRHS,CL_PACKED);
#endif
g_cluULast = new clUnpackedVector(pd3dDevice,g_iGridSizeX,g_iGridSizeY); g_cluULast->clear();
g_cluUCurrent = new clUnpackedVector(pd3dDevice,g_iGridSizeX,g_iGridSizeY); g_cluUCurrent->clear();
g_iViewWidth = pBackBufferSurfaceDesc->Width;
g_iViewHeight = pBackBufferSurfaceDesc->Height;
if( g_pFont ) V_RETURN( g_pFont->OnResetDevice() );
// Create a sprite to help batch calls when drawing many lines of text
V_RETURN( D3DXCreateSprite( pd3dDevice, &g_pTextSprite ) );
// Setup the camera's projection parameters
float fAspectRatio = pBackBufferSurfaceDesc->Width / (FLOAT)pBackBufferSurfaceDesc->Height;
g_Camera.SetProjParams( D3DX_PI/4, fAspectRatio, 0.1f, 1000.0f );
g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
g_HUD.SetLocation( pBackBufferSurfaceDesc->Width-170, 0 );
g_HUD.SetSize( 170, 170 );
g_WaterUI.SetLocation( pBackBufferSurfaceDesc->Width-170, pBackBufferSurfaceDesc->Height-150 );
g_WaterUI.SetSize( 170, 150 );
if FAILED(createCubeMap(pd3dDevice, pBackBufferSurfaceDesc, _T("pool.png"))) exit(-1);
// Set up the textures
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Set miscellaneous render states
pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE );
pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x000F0F0F );
// Set the world matrix
D3DXMATRIX matIdentity;
D3DXMatrixIdentity( &matIdentity );
pd3dDevice->SetTransform( D3DTS_WORLD, &matIdentity );
// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 0.0f, -5.0f );
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &g_matView, &vFromPt, &vLookatPt, &vUpVec );
pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView );
// Set the projection matrix
D3DXMatrixOrthoLH( &g_matProj, 2, 2, 1.0f, 100.0f );
pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj );
g_mModelViewProj = g_matView * g_matProj;
// Create the single quad vertex buffer.
V_RETURN(DirectXUtils::createFilledVertexBuffer(pd3dDevice,g_hMainQuad,sizeof(g_hMainQuad),TEXVERTEX2D::FVF,D3DPOOL_DEFAULT,g_pVB));
// create shader
#ifdef optNVIDIA
#define PS_PROFILE "ps_2_a"
#else
#define PS_PROFILE "ps_2_0"
#endif
LPCSTR profile[4] = {"PS_PROFILE", PS_PROFILE, 0, 0};
V_RETURN(DirectXUtils::checkLoadShader(_T("main.fx"), g_pMainShader, pd3dDevice,_T("shader/"), 0, (D3DXMACRO*)profile));
// do another check on the assembly technique
D3DXHANDLE hDisplaceTechnique = g_pMainShader->GetTechniqueByName("tDisplacePass");
V_RETURN( g_pMainShader->ValidateTechnique(hDisplaceTechnique));
// create render surface for indirect result display with linear filtering
V_RETURN(DirectXUtils::createRenderTexture( g_pBufferRenderSurface, g_pBufferTexture, g_pBufferTextureSurface, pd3dDevice, g_mBufferModelViewProj, g_iGridSizeX, g_iGridSizeY, D3DFMT_A8R8G8B8));
return S_OK;
}
void setDrop(IDirect3DDevice9* pd3dDevice, float x, float y) {
g_cluUCurrent->BeginScene();
D3DXVECTOR4 vPosition = D3DXVECTOR4(x,1-y,0,0);
g_pMainShader->SetTechnique("tInsertDrop");
g_pMainShader->SetVector("f4Position",&vPosition);
g_pMainShader->SetTexture("tHeightMap", g_cluUCurrent->m_pVectorTexture);
pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(TEXVERTEX2D) );
pd3dDevice->SetFVF( TEXVERTEX2D::FVF );
UINT cPasses;
g_pMainShader->Begin(&cPasses, 0);
g_pMainShader->BeginPass(0);
pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pMainShader->EndPass();
g_pMainShader->End();
g_cluUCurrent->EndScene();
}
//--------------------------------------------------------------------------------------
// This callback function will be called once at the beginning of every frame. This is the
// best location for your application to handle updates to the scene, but is not
// intended to contain actual rendering calls, which should instead be placed in the
// OnFrameRender callback.
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
{
// Update the camera's position based on user input
g_Camera.FrameMove( fElapsedTime );
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID );
pd3dDevice->BeginScene();
if (g_bMouseLDown && ! g_bIsGUIEvent) setDrop(pd3dDevice,g_fMouseX,g_fMouseY);
if (g_bRainMode) {
if (g_iRainCounter) {
g_iRainCounter--;
} else {
g_iRainCounter = g_iRainDelay;
setDrop(pd3dDevice,(float)rand()/RAND_MAX,(float)rand()/RAND_MAX);
}
}
#ifdef useUpacked
g_cluRHS->computeRHS(g_cluULast, g_cluUCurrent);
g_iSteps = g_pCGSolver->solveNT(2);
g_cluULast->copyVector(g_cluUCurrent);
g_cluUCurrent->copyVector(g_cluUNext);
#else
g_cluRHS->computeRHS(g_cluULast, g_cluUCurrent);
g_clRHS->repack(g_cluRHS);
g_iSteps = g_pCGSolver->solveNT(2);
g_cluULast->copyVector(g_cluUCurrent);
g_clUNext->unpack(g_cluUCurrent);
#endif
pd3dDevice->EndScene();
}
//--------------------------------------------------------------------------------------
// This callback function will be called at the end of every frame to perform all the
// rendering calls for the scene, and it will also be called if the window needs to be
// repainted. After this function has returned, the sample framework will call
// IDirect3DDevice9::Present to display the contents of the next buffer in the swap chain
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime )
{
HRESULT hr;
if (g_bTimeclPerformance) {
pd3dDevice->BeginScene();
clFloat timeFloat(pd3dDevice);
double dStartTime = DXUTGetGlobalTimer()->GetTime();
for (int i = 0; i<1000;i++) timeVec1->reduceAdd(&timeFloat);
double dReduceTime = DXUTGetGlobalTimer()->GetTime()-dStartTime;
dStartTime = DXUTGetGlobalTimer()->GetTime();
for (int i = 0; i<1000;i++) timeVec1->addVector(timeVec2,timeVec2);
double dVectorOpTime = DXUTGetGlobalTimer()->GetTime()-dStartTime;
TCHAR strTimings[1000];
_stprintf(strTimings,_T("vector size %i %i\na vector reduce takes %gms\na vector-vector add takes %gms"),g_iGridSizeX,g_iGridSizeY,dReduceTime,dVectorOpTime);
MessageBox(NULL,strTimings,_T("Timings"), MB_OK);
g_bTimeclPerformance = false;
ClearSimulation();
pd3dDevice->EndScene();
return;
}
// render the water surface to a temp buffer
g_pBufferRenderSurface->BeginScene( g_pBufferTextureSurface, NULL);
pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0,0,0,0), 1.0f, 0L );
g_pMainShader->SetTechnique("tMainPass");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -