⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 water.cpp

📁 在GPU上实现数值模拟技术(线性方程组)的通用架构
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    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 + -