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

📄 ch23p1_simplewater.cpp

📁 游戏开发特殊技巧-special.effects.game.programming
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
#############################################################################

  Ch23p1_SimpleWater.cpp: a program that demonstrates the 3D water effect.
  
#############################################################################
*/

// include files ////////////////////////////////////////////////////////////
#define STRICT
#include <stdio.h>
#include <math.h>
#include <D3DX8.h>
#include "D3DApp.h"
#include "D3DFile.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "DXUtil.h"
#include "D3DHelperFuncs.h"
#include "Ch23p1_resource.h"
#include "Camera.h"
#include "InputManager.h"
#include "SkyBox.h"
#include "Timer.h"
#include "GroundPlane.h"
#include "Ch23p1_WaterPlane.h"

const int NUMSPRITES = 5;
const int CUBEMAP_RESOLUTION = 256;

//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc: Application class. The base class (CD3DApplication) provides the 
//       generic functionality needed in all Direct3D samples. CMyD3DApplication 
//       adds functionality specific to this sample program.
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
  // Font for drawing text
  CD3DFont* m_pFont;
  CD3DFont* m_pFontSmall;

  // Scene
  CUserControlledCamera m_Camera;

  // Mouse Input
  CInputManager m_InputManager;

  // skybox
  CSkyBox m_SkyBox;

	// ground plane
	CGroundPlane m_GroundPlane;

  // pool frame
  CD3DMesh* m_pPoolFrame;
  
  // water
  CWaterPlane m_Water;

  LPDIRECT3DCUBETEXTURE8 m_pCubeMap;
  IDirect3DSurface8* m_pCubeFaceZBuffer;

protected:
  HRESULT OneTimeSceneInit();
  HRESULT InitDeviceObjects();
  HRESULT RestoreDeviceObjects();
  HRESULT InvalidateDeviceObjects();
  HRESULT DeleteDeviceObjects();
  HRESULT FinalCleanup();
  HRESULT Render() { return(ScreenRender()); }
  HRESULT ScreenRender();
  HRESULT CoreRender(bool bRenderWater, D3DXMATRIX matView);
  HRESULT CubeMapRender();
  HRESULT FrameMove();
  HRESULT ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format );
  LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

	void ProcessInput();
	int m_iLightPosX;
	int m_iLightPosY;

public:
  CMyD3DApplication();
};

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
//       message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
  CMyD3DApplication d3dApp;

  if( FAILED( d3dApp.Create( hInst ) ) )
    return 0;

  return d3dApp.Run();
}

//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application constructor. Sets attributes for the app.
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
	m_strWindowTitle    = _T("Ch23p1_SimpleWater");
  m_bUseDepthBuffer   = TRUE;
  m_pFont            = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
  m_pFontSmall       = new CD3DFont( _T("Arial"),  9, D3DFONT_BOLD );\
  m_pCubeMap          = NULL;
  m_pCubeFaceZBuffer  = NULL;
}

//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
//       permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
  return S_OK;
}

//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
//       the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
	if (m_fElapsedTime < 0.0001f) {
		m_fElapsedTime = 0.0001f;
	}
	
  ProcessInput();
  m_Camera.Update(m_fElapsedTime);

	CTimer::UpdateAll(m_fElapsedTime);
  m_Water.Update(m_fElapsedTime);

  // Render the scene into the surfaces of the cubemap
  if( FAILED( CubeMapRender() ) )
      return E_FAIL;


	return S_OK;
}

void CMyD3DApplication::ProcessInput()
{
  const float fSpeed = 0.5f;
  unsigned char m_bKey[256];
  ZeroMemory( m_bKey, 256 );
  GetKeyboardState(m_bKey);
  // Process keyboard input
  if(m_bKey['D'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(fSpeed, 0.0f, 0.0f)); // Slide Right
  if(m_bKey['A'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(-fSpeed, 0.0f, 0.0f));// Slide Left
  if(m_bKey['Q'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, fSpeed, 0.0f)); // Slide Up
  if(m_bKey['Z'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, -fSpeed, 0.0f));// Slide Down
  if(m_bKey['W'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, 0.0f, fSpeed)); // Slide Foward
  if(m_bKey['S'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, 0.0f, -fSpeed));// Slide Back

  // mouse look
  DIMOUSESTATE2 dims2;
  m_InputManager.ReadMouse(dims2);

  // play with the divisor constants to change the mouselook sensitivity.
  // I've found that these values most accurately simulate my beloved Q3A setup. :)
  m_Camera.AddToYawPitchRoll((float)dims2.lX/0.8f, (float)dims2.lY/0.8f, 0.0f);

	// prevent camera from moving down too far.
	D3DXVECTOR3 pos = m_Camera.GetPosition();
	if (pos.y < 1.7f) pos.y = 1.70f; 
	m_Camera.SetPosition(pos);
}

HRESULT CMyD3DApplication::CubeMapRender()
{
  // Set the projection matrix for a field of view of 90 degrees
  D3DXMATRIX matProj;
  D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 0.5f, 100.0f );
  m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );

  // Get the current view matrix, to concat it with the cubemap view vectors
  D3DXMATRIX matViewDir = m_Camera.GetViewMatrix();
  matViewDir._41 = 0.0f; matViewDir._42 = 0.0f; matViewDir._43 = 0.0f;
  D3DXPLANE plane; plane.a = plane.b = plane.c = plane.d = 0.0f;
  D3DXMATRIX matFlip; D3DXMatrixReflect(&matFlip, &plane);
  
  D3DXMatrixMultiply(&matViewDir, &matFlip, &matViewDir);
  // Store the current backbuffer and zbuffer
  LPDIRECT3DSURFACE8 pBackBuffer, pZBuffer;
  m_pd3dDevice->GetRenderTarget( &pBackBuffer );
  m_pd3dDevice->GetDepthStencilSurface( &pZBuffer );

  // Render to the six faces of the cube map
  for( DWORD i=0; i<6; i++ )
  {
    // Set the view transform for this cubemap surface
    D3DXMATRIX matView;
    matView = D3DUtil_GetCubeMapViewMatrix( (D3DCUBEMAP_FACES)i );
    D3DXMatrixMultiply( &matView, &matViewDir, &matView );
    m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

    // Set the rendertarget to the i'th cubemap surface
    LPDIRECT3DSURFACE8 pCubeMapFace;
    m_pCubeMap->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pCubeMapFace );
    m_pd3dDevice->SetRenderTarget( pCubeMapFace, m_pCubeFaceZBuffer);
    pCubeMapFace->Release();

    m_pd3dDevice->BeginScene();
    m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0L );
    CoreRender( FALSE, matView );
    m_pd3dDevice->EndScene();
  }

  m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_Camera.GetViewMatrix());
  // Change the rendertarget back to the main backbuffer
  m_pd3dDevice->SetRenderTarget( pBackBuffer, pZBuffer );
  pBackBuffer->Release();
  pZBuffer->Release();

  return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ScreenRender()
// 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::ScreenRender()
{
  if( SUCCEEDED( m_pd3dDevice->BeginScene() ) ) {

    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 0.5f, 100.0f );
    m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );


    CoreRender(true, m_Camera.GetViewMatrix());

    char buf[256];
    _snprintf(buf, 256, "Position: (%.2f, %.2f, %.2f)", 
      (float)m_Camera.GetPosition().x, (float)m_Camera.GetPosition().y, 
      (float)m_Camera.GetPosition().z);

    m_pFontSmall->DrawText( 2,  0,  D3DCOLOR_ARGB(255,255,255,0), buf );
    
    _snprintf(buf, 256, "Normals are: %s ('N' to switch)", 
      m_Water.GetHardcodeNormals() ? "Hard-coded to (0,1,0)" : "Calculated");

    m_pFontSmall->DrawText( 2,  15,  D3DCOLOR_ARGB(255,255,255,0), buf );

    _snprintf(buf, 256, "Environment Blend Factor: %0.1f (I,O to adjust)", 
      m_Water.GetEnvBlendFactor());

    m_pFontSmall->DrawText( 2,  30,  D3DCOLOR_ARGB(255,255,255,0), buf );
    
    _snprintf(buf, 256, "Simulated Water Depth: %0.1f (K,L to adjust)", 
      m_Water.GetDepth());

    m_pFontSmall->DrawText( 2,  45,  D3DCOLOR_ARGB(255,255,255,0), buf );
    
    _snprintf(buf, 256, "Press C to create a water drop.", 
      m_Water.GetDepth());

    m_pFontSmall->DrawText( 2,  60,  D3DCOLOR_ARGB(255,255,255,0), buf );
    
    // End the scene.
    m_pd3dDevice->EndScene();
  }
  return(S_OK);
}

HRESULT CMyD3DApplication::CoreRender(bool bRenderWater, D3DXMATRIX matView)
{
  D3DXMATRIX matWorld;
  D3DXMatrixIdentity( &matWorld );
  m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

  // Clear the backbuffer
  m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_ZBUFFER, 0x000000ff, 1.0f, 0L );
  
	m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 );
	m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );

⌨️ 快捷键说明

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