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

📄 simpleterrain.cpp

📁 游戏编程精粹2第四章源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* Copyright (C) Greg Snook, 2001. 
 * All rights reserved worldwide.
 *
 * This software is provided "as is" without express or implied
 * warranties. You may freely copy and compile this source into
 * applications you distribute provided that the copyright text
 * below is included in the resulting source code, for example:
 * "Portions Copyright (C) Greg Snook, 2001"
 */
#ifndef SIMPLETERRAIN_H
#define SIMPLETERRAIN_H
/****************************************************************************************\

	SimpleTerrain.cpp

	SimpleTerrain component interface for a basic terrain manager.

	Part of the Gems II sample code library.
	Created 3/27/2001 by Greg Snook
	gregsnook@home.com

    ------------------------------------------------------------------------------------- 
	Notes/Revisions:
	I make no aplogies for spelling errors :)

\****************************************************************************************/
#define STRICT
#include <tchar.h>
#include <stdio.h>
#include <windows.h>
#include <commdlg.h>
#include <d3dx8.h>
#include "D3DApp.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "DXUtil.h"
#include "resource.h"
#include "TileDefinitions.h" // <- the index buffers are defined in here


/*	SimpleTerrain
------------------------------------------------------------------------------------------
	
	SimpleTerrain is a sample class that demonstrates the terrain method. 
	It's been written for clarity, not speed. 
	
------------------------------------------------------------------------------------------
*/
#define TILE_VERTS 9	// our tiles are 9x9 vertices
#define TILE_COUNT 16	// our terrain in 16x16 tiles

// the overall terrain is a set of VERTEX_COUNT x VERTEX_COUNT vertices
#define VERTEX_COUNT ((TILE_COUNT*(TILE_VERTS-1))+1) 

class SimpleTerrain : public CD3DApplication
{
public:

	// Data Types & Constants...

	// our sample contains 4 possible detail levels per tile
	enum LEVEL
	{
		LEVEL_0 = 0,
		LEVEL_1,
		LEVEL_2,
		LEVEL_3,
		TOTAL_LEVELS
	};

	// data about each index buffer we create
	struct INDEX_BUFFER
	{
		IDirect3DIndexBuffer8*	pIndexBuffer;
		int						IndexCount;
		int						TriangleCount;
	};

	// the index buffers needed for each of our detail levels
	struct DETAIL_LEVEL
	{
		INDEX_BUFFER 	TileBodies[16];
		INDEX_BUFFER	TileConnectors[TOTAL_SIDES][TOTAL_LEVELS];
	};

	// a tile of our terrain
	struct TILE
	{
		LEVEL					DetailLevel;// the current detail level to use
		IDirect3DVertexBuffer8* VBuffer;	// a pile of vertices for this tile
		D3DXVECTOR3				Center;		// the center point of the tile
	};

	// our vertex format for this sample
	struct TERRAIN_VERTEX
	{
		D3DXVECTOR3  vert;
		D3DXVECTOR3  norm;
		float		tu,tv;
	};

	// the FVF code for this sample
	enum VERTEX_FVF
	{
		FVF = D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1
	};

	// Creators...

	SimpleTerrain();
	~SimpleTerrain(){};

	// Operators...

	// Mutators...
	void GenerateDetailLevels();
	void GenerateTiles();
	void DrawTerrain();

    HRESULT OneTimeSceneInit();
    HRESULT InitDeviceObjects();
    HRESULT RestoreDeviceObjects();
    HRESULT InvalidateDeviceObjects();
    HRESULT DeleteDeviceObjects();
    HRESULT Render();
    HRESULT FrameMove();
    HRESULT FinalCleanup();

    LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

	// Accessors...

private:

	// Data...
	TILE				m_TerrainTile[TILE_COUNT][TILE_COUNT];	// our sample terrain of 32x32 tiles
	DETAIL_LEVEL		m_DetailLevel[TOTAL_LEVELS]; // data for each detail level

    LPDIRECT3DTEXTURE8	m_pMeshTexture;			// simple texture for our terrain
	LPDIRECT3DSURFACE8	m_pHeightData;			// greyscale height information
    D3DMATERIAL8		m_MeshMaterial;			// a basic material for the terrain

    CD3DFont*           m_pFont;              // Font for outputting frame stats
    CD3DArcBall         m_ArcBall;            // Mouse rotation utility
    D3DXVECTOR3         m_vObjectCenter;      // Center of bounding sphere of object
    FLOAT               m_fObjectRadius;      // Radius of bounding sphere of object
    D3DXMATRIX          m_matWorld;			  // the world transform matrix

	D3DXVECTOR3			m_CameraPos;		  // position of the camera
	int					m_FacesDrawn;		  // count of faces actually rendered each frame

	bool				m_bWireframe;		// wireframe mode toggle
	float				m_CameraOffset;		// camera's zoom factor

	// Private Functions...

	// Nonexistant Functions...

	SimpleTerrain( const SimpleTerrain& Src);
	SimpleTerrain& operator=( const SimpleTerrain& Src);

};


//-----------------------------------------------------------------------------
// 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 )
{
    SimpleTerrain d3dApp;

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

    return d3dApp.Run();
}

//-----------------------------------------------------------------------------
// Name: SimpleTerrain()
// Desc: Constructor
//-----------------------------------------------------------------------------
SimpleTerrain::SimpleTerrain()
{
    // Override base class members
    m_strWindowTitle     = _T("GEMS II: Simple Terrain");
    m_bUseDepthBuffer    = TRUE;
    m_bShowCursorWhenFullscreen = TRUE;

    // Initialize member variables
    m_pFont              = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
	m_pMeshTexture = 0;
	m_pHeightData = 0;

	D3DUtil_InitMaterial(m_MeshMaterial, 0.5f, 0.6f, 0.5f, 1.0f);

	ZeroMemory(m_TerrainTile, sizeof(TILE)*TILE_COUNT*TILE_COUNT);
	ZeroMemory(m_DetailLevel, sizeof(DETAIL_LEVEL)*TOTAL_LEVELS);

	m_FacesDrawn = 0;

	m_bWireframe = false;
	m_CameraOffset = -2.0f;

}




//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
//       permanent initialization.
//-----------------------------------------------------------------------------
HRESULT SimpleTerrain::OneTimeSceneInit()
{
    // Set cursor to indicate that user can move the object with the mouse
#ifdef _WIN64
    SetClassLongPtr( m_hWnd, GCLP_HCURSOR, (LONG_PTR)LoadCursor( NULL, IDC_SIZEALL ) );
#else
    SetClassLong( m_hWnd, GCL_HCURSOR, (LONG)LoadCursor( NULL, IDC_SIZEALL ) );
#endif


    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
//       the scene.
//-----------------------------------------------------------------------------
HRESULT SimpleTerrain::FrameMove()
{
     // Setup world matrix
    D3DXMATRIX matWorld;
    D3DXMATRIX matRotationInverse;
    D3DXMatrixTranslation( &matWorld, -m_vObjectCenter.x,
                                      -m_vObjectCenter.y,
                                      -m_vObjectCenter.z );
    D3DXMatrixInverse( &matRotationInverse, NULL, m_ArcBall.GetRotationMatrix() );
    D3DXMatrixMultiply( &matWorld, &matWorld, &matRotationInverse );
    D3DXMatrixMultiply( &matWorld, &matWorld, m_ArcBall.GetTranslationMatrix() );
    m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

 	m_CameraPos = D3DXVECTOR3( 0, 0, m_CameraOffset*m_fObjectRadius );
	D3DXMATRIX matView;
    D3DXMatrixLookAtLH( &matView, &m_CameraPos,
                                  &D3DXVECTOR3( 0, 0, 0 ),
                                  &D3DXVECTOR3( 0, 1, 0 ) );
    m_pd3dDevice->SetTransform( D3DTS_VIEW,  &matView );
    
	// transform the camera point into model space 
    D3DXMATRIX matWorldInv;
    D3DXMatrixInverse( &matWorldInv, NULL, &matWorld);

	D3DXVECTOR4 NewCamera;
	D3DXVec3Transform(&NewCamera, &m_CameraPos, &matWorldInv);

	// store this value as our camera position in model space
	m_CameraPos.x = NewCamera.x;
	m_CameraPos.y = NewCamera.y;
	m_CameraPos.z = NewCamera.z;

	// calc the minnimim distance for each detail level
	float detail_step = m_fObjectRadius/4.0f;
	float min_level3 = detail_step;
	float min_level2 = detail_step * 2.0f;
	float min_level1 = detail_step * 3.0f;

	// choose detail levels for each tile
	for (int i=0;i<TILE_COUNT;++i)
	{
		for (int j=0;j<TILE_COUNT;++j)
		{
			D3DXVECTOR3 VectorToCamera(m_TerrainTile[i][j].Center - m_CameraPos);
			float DistanceToCamera = D3DXVec3Length(&VectorToCamera) - m_fObjectRadius;

			if (DistanceToCamera < min_level3)
			{
				m_TerrainTile[i][j].DetailLevel = LEVEL_3;
			}
			else if (DistanceToCamera < min_level2)
			{
				m_TerrainTile[i][j].DetailLevel = LEVEL_2;
			}
			else if (DistanceToCamera < min_level1)
			{
				m_TerrainTile[i][j].DetailLevel = LEVEL_1;
			}
			else 
			{
				m_TerrainTile[i][j].DetailLevel = LEVEL_0;
			}
		}
	}

	// allow the user to drive the camera closer or further away
	// using the Up/Down arrow keys
	if (GetAsyncKeyState(VK_DOWN) & 0x8000) 
	{
		m_CameraOffset -= 0.01f;
	}
	else if (GetAsyncKeyState(VK_UP) & 0x8000)
	{
		m_CameraOffset += 0.01f;

		if (m_CameraOffset >= 0.0f)
		{
			m_CameraOffset = -0.01f;
		}
	}

	return S_OK;
}



//-----------------------------------------------------------------------------
// 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 SimpleTerrain::Render()
{
    D3DXMATRIX matWorld;
    D3DXMATRIX matTemp;
    FLOAT fTrisPerSec;
    TCHAR strInfo[120];

    // Clear the scene
    m_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         0x000000ff, 1.0f, 0x00000000 );

    // Draw scene
    if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
    {
		// setup the proper material and texture
		m_pd3dDevice->SetMaterial( &m_MeshMaterial);
		m_pd3dDevice->SetTexture( 0, m_pMeshTexture);

		if (m_bWireframe)
		{
			m_pd3dDevice->SetRenderState(D3DRS_FILLMODE , D3DFILL_WIREFRAME );
		}
		else
		{
			m_pd3dDevice->SetRenderState(D3DRS_FILLMODE , D3DFILL_SOLID );
		}

⌨️ 快捷键说明

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