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

📄 blois.cpp

📁 著名的GPU Gems中的自然效果模拟-水效果的演示程序及全部实现源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:

	for( i = 0; i < nFaces; i++ )
	{
		oIdx[i].m_Idx[0] = m_WaterIndices[m_WaterSortData[i].m_Idx].m_Idx[0];
		oIdx[i].m_Idx[1] = m_WaterIndices[m_WaterSortData[i].m_Idx].m_Idx[1];
		oIdx[i].m_Idx[2] = m_WaterIndices[m_WaterSortData[i].m_Idx].m_Idx[2];
	}

	m_WaterMesh->UnlockIndexBuffer();
}

HRESULT CMyD3DApplication::CreateClearBuffer()
{
	HRESULT hr;
	if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( 4 * kVSize,
												D3DUSAGE_WRITEONLY, 
												0,
												D3DPOOL_MANAGED, 
												&m_BumpVBuffer,
												NULL) ) )
	{
		return hr;
	}


	ClearVert* ptr;
	if( FAILED( hr = m_BumpVBuffer->Lock( 0, 0, (void **)&ptr, 0 ) ) )
		return hr;

	ptr[2].m_Pos.x = -1.f;
	ptr[2].m_Pos.y = -1.f;
	ptr[2].m_Pos.z = 0.5f;

	ptr[2].m_Uv.x = 0.5f / kBumpTexSize;
	ptr[1].m_Uv.y = 0.5f / kBumpTexSize;

	ptr[0] = ptr[2];
	ptr[0].m_Pos.y += 2.f;
	ptr[0].m_Uv.y += 1.f;

	ptr[1] = ptr[2];
	ptr[1].m_Pos.x += 2.f;
	ptr[1].m_Pos.y += 2.f;
	ptr[1].m_Uv.x += 1.f;
	ptr[1].m_Uv.y += 1.f;

	ptr[3] = ptr[2];
	ptr[3].m_Pos.x += 2.f;
	ptr[3].m_Uv.x += 1.f;

	m_BumpVBuffer->Unlock();

	return S_OK;
}


//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Paired with InvalidateDeviceObjects()
//       The device exists, but may have just been Reset().  Resources in
//       D3DPOOL_DEFAULT and any other device state that persists during
//       rendering should be set here.  Render states, matrices, textures,
//       etc., that don't change during rendering can be set once here to
//       avoid redundant state setting during Render() or FrameMove().
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
    // TODO: setup render states

    // Setup a material
    D3DMATERIAL9 mtrl;
    D3DUtil_InitMaterial( mtrl, 1.0f, 1.0f, 1.0f );
    m_pd3dDevice->SetMaterial( &mtrl );

    // Set up the textures
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
    m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
    m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );

    // Set miscellaneous render states
	m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
    m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_ZENABLE,        TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_AMBIENT,        0x000F0F0F );
	m_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

    // Set the world matrix
    D3DXMATRIX matIdentity;
    D3DXMatrixIdentity( &matIdentity );
    m_pd3dDevice->SetTransform( D3DTS_WORLD,  &matIdentity );


    // Set the projection matrix
    FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
    D3DXMatrixPerspectiveFovLH( &m_matProjection, D3DX_PI/4, fAspect, 1.0f, 10000.0f );
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_matProjection);

    // Set up lighting states
    D3DLIGHT9 light;
    D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, -1.0f, -1.0f, -2.0f );
    m_pd3dDevice->SetLight( 0, &light );
    m_pd3dDevice->LightEnable( 0, TRUE );
    m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

    // Restore the font
    m_pFont->RestoreDeviceObjects();

	HRESULT hr;
	// Create our bump map. We'll composite the normals of our texture waves into this with renders.
    if(FAILED(hr = D3DXCreateTexture(m_pd3dDevice, kBumpTexSize, kBumpTexSize, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_BumpTex)) &&
       FAILED(hr = D3DXCreateTexture(m_pd3dDevice, kBumpTexSize, kBumpTexSize, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_BumpTex)))
    {
        return hr;
    }

    D3DSURFACE_DESC desc;
    m_BumpTex->GetSurfaceLevel(0, &m_BumpSurf);
    m_BumpSurf->GetDesc(&desc);

    if(FAILED(hr = D3DXCreateRenderToSurface(m_pd3dDevice, desc.Width, desc.Height, 
									        desc.Format, FALSE, D3DFMT_UNKNOWN, &m_BumpRender)))
        return hr;

    m_CompCosinesEff->OnResetDevice();
	m_WaterEff->OnResetDevice();

    return S_OK;
}

static void Clamp(float& val, float lo, float hi)
{
	if( val < lo )
		val = lo;
	else if( val > hi )
		val = hi;
}

void CMyD3DApplication::MoveOnInput()
{
    //
    // Process keyboard input
    //

    D3DXVECTOR3 vecT(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vecR(0.0f, 0.0f, 0.0f);
    D3DXVECTOR3 vecZ(0.0f, 0.0f, 0.0f);

    if(m_bKey[VK_NUMPAD1] || m_bKey[VK_LEFT])  vecT.x -= 1.0f; // Slide Left
    if(m_bKey[VK_NUMPAD3] || m_bKey[VK_RIGHT]) vecT.x += 1.0f; // Slide Right
    if(m_bKey[VK_DOWN])                        vecT.y -= 1.0f; // Slide Down
    if(m_bKey[VK_UP])                          vecT.y += 1.0f; // Slide Up
    if(m_bKey['W'])                            vecT.z += 2.0f; // Move Forward
    if(m_bKey['S'])                            vecT.z -= 2.0f; // Move Backward
    if(m_bKey['A'] || m_bKey[VK_NUMPAD8])      vecR.x -= 1.0f; // Pitch Down
    if(m_bKey['Z'] || m_bKey[VK_NUMPAD2])      vecR.x += 1.0f; // Pitch Up
    if(m_bKey['E'] || m_bKey[VK_NUMPAD6])      vecZ.z -= 1.0f; // Turn Right
    if(m_bKey['Q'] || m_bKey[VK_NUMPAD4])      vecZ.z += 1.0f; // Turn Left
    if(m_bKey[VK_NUMPAD9])                     vecR.z -= 2.0f; // Roll CW
    if(m_bKey[VK_NUMPAD7])                     vecR.z += 2.0f; // Roll CCW

	const float speed = 10.f;
	const float angSpeed = D3DX_PI / 5.f;
	vecT *= speed * m_fElapsedTime;
	vecR *= angSpeed * m_fElapsedTime;
	vecZ *= angSpeed * m_fElapsedTime;

	if(m_bKey[VK_SHIFT])
	{
		vecT *= 4.f;
		vecR *= 4.f;
		vecZ *= 4.f;
	}

    //
    // Update position and view matricies
    //

    D3DXMATRIXA16 matT, matR, matZ;
    D3DXQUATERNION qR;
    D3DXQUATERNION qZ;


    D3DXMatrixTranslation(&matT, vecT.x, vecT.y, vecT.z);
    D3DXMatrixMultiply(&m_matPosition, &matT, &m_matPosition);

    D3DXQuaternionRotationYawPitchRoll(&qR, vecR.y, vecR.x, vecR.z);
    D3DXMatrixRotationQuaternion(&matR, &qR);

    D3DXQuaternionRotationYawPitchRoll(&qZ, vecZ.y, vecZ.x, vecZ.z);
    D3DXMatrixRotationQuaternion(&matZ, &qZ);

    D3DXMatrixMultiply(&m_matPosition, &matR, &m_matPosition);
    D3DXMatrixMultiply(&m_matPosition, &m_matPosition, &matZ);

    D3DXMatrixInverse(&m_matView, NULL, &m_matPosition);

	float timeScale = m_bKey[VK_SHIFT] ? m_fElapsedTime : -m_fElapsedTime;
	// MoreOptions
	// Debounce the toggles
	const float kMinToggle = 0.5f;
	if( m_fTime - m_LastToggle > kMinToggle )
	{
		// Reset
		if(m_bKey['R'])
		{
			if( m_bKey[VK_SHIFT] )
				ResetWater();
			else
				InitWaves();
			m_LastToggle = m_fTime;
		}
		// Show bump
		if(m_bKey['B'])
		{
			m_bDrawBump = !m_bDrawBump;
			m_LastToggle = m_fTime;
		}

		if(m_bKey[VK_SPACE])
		{
			m_bShowHelp = !m_bShowHelp;
			m_LastToggle = m_fTime;
		}
	}
	// Water Height
	if(m_bKey['H'])
		m_GeoState.m_WaterLevel += timeScale * 3.f;
	// Geo Wave Height
	if(m_bKey['J'])
	{
		m_GeoState.m_AmpOverLen += timeScale * 0.05f;
		Clamp(m_GeoState.m_AmpOverLen, 0.f, 0.1f);
	}
	// Geo Chop
	if(m_bKey['K'])
	{
		m_GeoState.m_Chop += timeScale * 0.5f;
		Clamp(m_GeoState.m_Chop, 0.f, 4.f);
	}
	// Tex Wave Height
	if(m_bKey['U'])
	{
		m_TexState.m_AmpOverLen += timeScale * 0.05f;
		Clamp(m_TexState.m_AmpOverLen, 0.f, 0.5f);
	}
	// Tex scale
	if(m_bKey['Y'])
	{
		m_TexState.m_RippleScale += timeScale * 1.f;
		Clamp(m_TexState.m_RippleScale, 5.f, 50.f);
	}
	if(m_bKey['N'])
	{
		m_TexState.m_Noise += timeScale * 0.1f;
		Clamp(m_TexState.m_Noise, 0.f, 1.f);
	}
	if(m_bKey['O'])
	{
		m_GeoState.m_AngleDeviation += timeScale * 10.f;
		Clamp(m_GeoState.m_AngleDeviation, 0.f, 180.f);
	}
	if(m_bKey['P'])
	{
		m_TexState.m_AngleDeviation += timeScale * 10.f;
		Clamp(m_TexState.m_AngleDeviation, 0.f, 180.f);
	}
	if(m_bKey['G'])
	{
		m_GeoState.m_EnvRadius *= 1.f + timeScale * 0.5f;
		Clamp(m_GeoState.m_EnvRadius, 100.f, 10000.f);
	}
	if(m_bKey['F'])
	{
		m_GeoState.m_EnvHeight += timeScale * 10.f;
		Clamp(m_GeoState.m_EnvHeight, -100.f, 100.f);
	}
}


//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
//       the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
    // TODO: update world

    // Update user input state
	MoveOnInput();

	UpdateTexWaves(m_fElapsedTime);
	UpdateGeoWaves(m_fElapsedTime);

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: UpdateInput()
// Desc: Update the user input.  Called once per frame 
//-----------------------------------------------------------------------------
void CMyD3DApplication::UpdateInput( UserInput* pUserInput )
{
    pUserInput->bRotateUp    = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
    pUserInput->bRotateDown  = ( m_bActive && (GetAsyncKeyState( VK_DOWN )  & 0x8000) == 0x8000 );
    pUserInput->bRotateLeft  = ( m_bActive && (GetAsyncKeyState( VK_LEFT )  & 0x8000) == 0x8000 );
    pUserInput->bRotateRight = ( m_bActive && (GetAsyncKeyState( VK_RIGHT ) & 0x8000) == 0x8000 );

	pUserInput->bMoveUp = ( m_bActive && (GetAsyncKeyState( VK_UP )    & 0x8000) == 0x8000 );
}




//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
//       rendering. This function sets up render states, clears the
//       viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
	RenderTexture();

    // Clear the viewport
    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         0x00707070, 1.0f, 0L );

    // Begin the scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
        // TODO: render world
		m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &m_matProjection);
		m_pd3dDevice->SetTransform(D3DTS_VIEW, &m_matView);
        
		m_pd3dDevice->SetTexture(0, m_LandTex);
		m_LandMesh->DrawSubset(0);
		m_pd3dDevice->SetTexture(0, NULL);

		m_PillarsMesh->DrawSubset(0);

		RenderWater();

		if( m_bDrawBump )
		{
			D3DXMATRIXA16 matIdent;
			D3DXMatrixIdentity(&matIdent);

			m_pd3dDevice->SetTransform(D3DTS_VIEW, &matIdent);
			matIdent._11 = 0.5f;
			matIdent._22 = 0.5f;
			m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matIdent);

			m_pd3dDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_ONE);
			m_pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
			m_pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_ALWAYS);

			m_pd3dDevice->SetTexture(0, m_BumpTex);
			m_pd3dDevice->SetFVF(kClearVertFVF);
			m_pd3dDevice->SetStreamSource(0, m_BumpVBuffer, 0, kVSize);

			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );

			m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);

			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
			m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
}

        // Render stats and help text  
        RenderText();

        // End the scene.
        m_pd3dDevice->EndScene();
    }

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: RenderText()
// Desc: Renders stats and help text to the scene.

⌨️ 快捷键说明

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