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

📄 ca_water.cpp

📁 游戏编程精华02-含有几十个游戏编程例子
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	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;
			m_bSlow = true;
			FDebug("m_dwSleepDelay: %d\n", m_dwSleepDelay );
			return(true);
			break;

		case VK_LEFT:
			if( m_dwSleepDelay > 1 )
				m_dwSleepDelay -= 2;
			m_bSlow = true;
			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 VK_RETURN:
			// single step
			m_bAnimate = false;
			m_bSingleStep = !m_bSingleStep;
			return(true);
			break;

		case VK_SPACE:
			// start or stop the animation
			m_bAnimate = !m_bAnimate;
			return(true);
			break;

		case 'I':
		case 'L':
			m_bApplyInteriorBoundaries = !m_bApplyInteriorBoundaries;
			FDebug("Apply interior boundaries: %s\n", m_bApplyInteriorBoundaries ? "TRUE" : "FALSE");
			return(true);
			break;

		//@@ Difference from standard CA_Water class
		case 'M':
			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 '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_FINALOUT;
			FDebug("displaying finalout = height field\n");
			return(true);
			break;


		case 'R':
		case '`':
		case '~':
			FDebug("Loading new droplet and initial maps\n");
			LoadRulesAndOtherMaps();
			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 '<':
			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_ZWRITEENABLE,		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;
	int i;

	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 
	hr = m_pD3DDev->SetVertexShader( m_dwVertexShader );
	ASSERT_IF_FAILED(hr);

	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");

	}



	if( m_bAnimate == true  )
	{
		// Update the textures for one step of the 
		//   game or cellular automata 

		DoSingleTimeStep();

	}
	else if( m_bSingleStep == true )
	{
		DoSingleTimeStep();

		m_bSingleStep = false;

	}

	if( m_bSlow )
	{
		// slow down the rendering and give any other apps a chance
		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 );

		// No need to clear - We overdraw the whole backbuffer
		// No z test

		hr = m_pD3DDev->SetRenderState( D3DRS_ZENABLE, false ); 
		ASSERT_IF_FAILED(hr);
		m_pD3DDev->SetRenderState( D3DRS_ZWRITEENABLE,	false );

		// turn off pixel shading
		m_pD3DDev->SetPixelShader( 0 );


		//////////////////////////////////////////////////////////		
		// Render the result of the calculations to the device
		// These steps are not needed to run the simulation - for final
		//  display of the results only

		if( m_bWireframe )
		{
			hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0,0,0 ), 1.0, 0);
			ASSERT_IF_FAILED(hr);

			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_HeightTarg] );
			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, mpTextureFiltered[m_nTex_VelTarg] );

			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, mpTextureFiltered[m_nTex_VelTarg] );	// upper left corner


			if( m_SimulationMode == SM_RGB_GLOW ||
				m_SimulationMode == SM_HUE_DROPLETS )
			{
				m_pD3DDev->SetTexture(0, mpTextureFiltered[m_nTex_HeightTarg] );
			}


			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( j==1 )
				{
					pSrcTex = mpTextureFiltered[3];

				}
				else if( j==2 )
				{
					pSrcTex = mpTextureFiltered[m_nTex_VelTarg];
				}



				// if one of these modes, want to display same texture in all 4
				//  panes, to show texture wrapping.
				if( m_SimulationMode == SM_RGB_GLOW ||
					m_SimulationMode == SM_HUE_DROPLETS )
				{
					pSrcTex = mpTextureFiltered[m_nTex_HeightTarg];
				}


				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++;
	}


	// Reset bilinear filtering, as that is most common

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -