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

📄 terrain.cpp

📁 3D游戏展示程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//--------------------------------------------------
//  Desc: LOD Terrain
//  Author: artsylee/2007.1.10
//--------------------------------------------------

#include <stdio.h>
#include "Terrain.h"
#include "Common.h"
#include "SkyBox.h"
#include "Heightmap.h"
#include "ase/ASEngine.h"

extern CSkyBox	skybox;
CHeightmap g_Hmap;
bool g_bLineMode = false;

CTerrain::CTerrain()
{
	m_numTriangles = 0;
}

CTerrain::~CTerrain()
{
	if(g_pTextureManager == NULL)	return;
	
	for(int i=0; i<2; i++)
	{
		g_pTextureManager->ReleaseTexture(m_hBlend[i]);
	}
}

bool CTerrain::LoadTerrain()
{
	// height map
	g_Hmap.LoadHeightmap("Picture\\Hightmap256.raw", 256);
	// LOD
	FILE* fp = fopen("Picture\\lodmap.lod", "rb");
	if(fp==NULL)
	{
		return false;
	}
	for(int z=MOVE_MAP_SIZE-1; z>-1; z--)
	{
		for(int x=0; x<MOVE_MAP_SIZE; x++)
		{
			fread(&m_LODmap[z][x], sizeof(unsigned char), 1, fp);
		}
	}
	fclose(fp);
	// Texture
	m_hBlend[0] = g_pTextureManager->LoadTexture("Picture\\Tile_1.tga", MM_KEEPINMEMORY, 0);
	m_hBlend[1] = g_pTextureManager->LoadTexture("Picture\\Tile_2.tga", MM_KEEPINMEMORY, 0);

	return true;
}

void CTerrain::SmoothEdge(void)
{
	for(int z=0; z<256; z++)
	{
		g_Hmap.m_HeightData.m_pData[z*256+255] = (g_Hmap.m_HeightData.m_pData[z*256+254]+
			g_Hmap.m_HeightData.m_pData[z*256+0])/2;
	}
	for(int x=0; x<256; x++)
	{
		g_Hmap.m_HeightData.m_pData[255*256+x] = (g_Hmap.m_HeightData.m_pData[254*256+x]+
			g_Hmap.m_HeightData.m_pData[0*256+x])/2;
	}
	g_Hmap.SaveHeightmap("Picture\\Hightmap256.raw");
}

void CTerrain::Update()
{
}

void CTerrain::Render()
{
	if(g_pD3DDevice)
	{
		D3DXMATRIXA16 matWorld;
		D3DXMatrixTranslation(&matWorld, (float)(g_Hmap.m_ViewOffsetX), 0, (float)(g_Hmap.m_ViewOffsetZ));
		g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

		g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
		g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
		g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);

		g_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_BLENDDIFFUSEALPHA);
		g_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		g_pD3DDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
		g_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
		g_pD3DDevice->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0);

		if(g_stInputInfo.KeyValue==DIK_L)
		{
			g_bLineMode = !g_bLineMode;
		}
		
		SET_TEXTURE_TYPE(0, m_hBlend[0]);
		SET_TEXTURE_UNTYPE(1, m_hBlend[1]);
		g_pD3DDevice->SetFVF(HeightmapVertex::FVF);
		if(g_bLineMode)
		{
			g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
			g_pD3DDevice->SetTexture(1, NULL);
			g_pD3DDevice->SetTexture(0, NULL);
		}

		int min = g_Hmap.m_Frustum.m_minZ;
		int max = g_Hmap.m_Frustum.m_maxZ;
		m_numTriangles = 0;
		int numArea = 0;
		if(g_Hmap.m_bViewerChange)
		{
			m_BlendIndex = 0;
		}
		g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
		//---------------------------------------------------
		// 地形Render
		// (优化前: 资源消耗7.9ms-8.3ms)
		// (优化后: 资源消耗3.6ms-4.7ms)
		//---------------------------------------------------
		for(int z=(g_Hmap.m_Frustum.m_pos[min].y); z<=(g_Hmap.m_Frustum.m_pos[max].y); z++)
		{
			for(int x=(g_Hmap.m_Frustum.m_LeftArray[z]); x<=(g_Hmap.m_Frustum.m_RightArray[z]); x++)
			{
				if(RenderTile(x, z))
					numArea++;
			}
		}
		if(m_BlendIndex>TERRAINVERTEX)
		{
			WriteLog(INFO_ERROR, "Terrain Vertex Error!");
		}
		g_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, m_BlendIndex/3, m_BlendVertex, sizeof(HeightmapVertex));

		if(g_bLineMode)
			g_pD3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
		g_pD3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);

		g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
		g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
		g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
		g_pD3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
		g_pD3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
		g_pD3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
		g_pD3DDevice->SetTexture(1, NULL);

	//	DrawSingleLine(0, 100, 0xffffffff, false, "number of triangles: %d, AREA: %d", m_numTriangles, numArea);
	//	DrawSingleLine(0, 100, 0xffffffff, false, "m_Index: %d", m_BlendIndex);
	}
}

bool CTerrain::RenderTile(int x, int z)
{ 
	unsigned char level = m_LODmap[z][x];
	if(level==0) 
	{
		return false;
	}
	
	if(level == 7)
		DrawLevel_7(x, z);	
	else if(level == 6)
		DrawLevel_6(x, z);	
	else if(level == 5)
		DrawLevel_5(x, z);	
	else if(level == 4)
		DrawLevel_4(x, z);
	else if(level == 3)
		DrawLevel_3(x, z);
	else if(level == 2)
		DrawLevel_2(x, z);
	else if(level == 1)		
		DrawLevel_1(x, z);
	// LOD5 & LOD7 渲染格子最多
	if(level == 4 || level == 6)
		return true;
	else
		return false;
		
}

//----------------------------------------------------
// LOD1(2格与1格的过渡层)
//----------------------------------------------------
void CTerrain::DrawLevel_1(int x, int z)
{
	HeightmapVertex pV[10];
	int rx = (x-128)*4;
	int rz = (z-128)*4;
	int index0 = g_Hmap.GetHeightIndex(x, z);
	int index1 = g_Hmap.GetHeightIndex(x, z+1);
	int index2 = g_Hmap.GetHeightIndex(x+1, z);
	int index3 = g_Hmap.GetHeightIndex(x+1, z+1);
	if(index0==-1 || index1==-1 || index2==-1 || index3==-1)
	{
		return;
	}

	int index4 = g_Hmap.GetHeightIndexOffset(index0, -1, 1);
	int index5 = g_Hmap.GetHeightIndexOffset(index0, -2, 0);
	int index6 = g_Hmap.GetHeightIndexOffset(index0, -2, 2);
	int index7 = g_Hmap.GetHeightIndexOffset(index0, 0, 2);
	int index8 = g_Hmap.GetHeightIndexOffset(index0, -3, 1);
	int index9 = g_Hmap.GetHeightIndexOffset(index1, 0, 2);
	int index10 = g_Hmap.GetHeightIndexOffset(index0, -1, 3);
	int index11 = g_Hmap.GetHeightIndexOffset(index2, -2, 0);
	int index12 = g_Hmap.GetHeightIndexOffset(index0, -3, 3);

	int index20 = g_Hmap.GetHeightIndexOffset(index0, -1, 0);
	int index21 = g_Hmap.GetHeightIndexOffset(index0, -2, 1);
	int index22 = g_Hmap.GetHeightIndexOffset(index0, -1, 2);
	int index23 = g_Hmap.GetHeightIndexOffset(index0, 0, 1);
	int index24 = g_Hmap.GetHeightIndexOffset(index0, -3, 0);
	int index25 = g_Hmap.GetHeightIndexOffset(index1, 0, 1);
	int index26 = g_Hmap.GetHeightIndexOffset(index0, -3, 2);
	int index27 = g_Hmap.GetHeightIndexOffset(index0, -2, 3);
	int index28 = g_Hmap.GetHeightIndexOffset(index2, -1, 0);
	int index29 = g_Hmap.GetHeightIndexOffset(index0, 0, 3);
	int index30 = g_Hmap.GetHeightIndexOffset(index1, 0, 3);
	int index31 = g_Hmap.GetHeightIndexOffset(index2, -3, 0);

	float ax,az,bx,bz,cx,cz,dx,dz;
	switch(0)
	{
	case 0: ax=0.0f; az=0.0f; bx=0.0f; bz=1.0f; cx=1.0f; cz=1.0f; dx=1.0f; dz=0.0f;	break;
	case 1: ax=0.0f; az=1.0f; bx=1.0f; bz=1.0f; cx=1.0f; cz=0.0f; dx=0.0f; dz=0.0f;	break;
	case 2: ax=1.0f; az=1.0f; bx=1.0f; bz=0.0f; cx=0.0f; cz=0.0f; dx=0.0f; dz=1.0f;	break;
	case 3: ax=1.0f; az=0.0f; bx=0.0f; bz=0.0f; cx=0.0f; cz=1.0f; dx=1.0f; dz=1.0f;	break;
	default:ax=1.0f; az=0.0f; bx=0.0f; bz=0.0f; cx=0.0f; cz=1.0f; dx=1.0f; dz=1.0f;	break;
	}
	int point = 0;
	pV[point++] = HeightmapVertex(float(rx+1)*10, g_Hmap.m_HeightData.m_pData[index4], 
		float(rz+1)*10, g_Hmap.m_pLightColor[index4], (ax+0.5f)*0.5f, (az+0.5f)*0.5f);

	pV[point++] = HeightmapVertex(float(rx*10), g_Hmap.m_HeightData.m_pData[index0], 
		float(rz*10), g_Hmap.m_pLightColor[index0], ax, az);

	if(m_LODmap[z][x-1] == 1)
	{
		pV[point++] = HeightmapVertex(float(rx*10), g_Hmap.m_HeightData.m_pData[index20], 
			float(rz+1)*10, g_Hmap.m_pLightColor[index20], (ax+(ax+bx)*0.5f)*0.5f, (az+(az+bz)*0.5f)*0.5f);
		m_numTriangles++;
	}

	pV[point++] = HeightmapVertex(float(rx*10), g_Hmap.m_HeightData.m_pData[index5], 
		float(rz+2)*10, g_Hmap.m_pLightColor[index5], (ax+bx)*0.5f, (az+bz)*0.5f);
	// add
	pV[point++] = HeightmapVertex(float(rx+1)*10, g_Hmap.m_HeightData.m_pData[index21], 
		float(rz+2)*10, g_Hmap.m_pLightColor[index21], ((ax+bx)*0.5f+0.5f)*0.5f, ((az+bz)*0.5f+0.5f)*0.5f);

	pV[point++] = HeightmapVertex(float(rx+2)*10, g_Hmap.m_HeightData.m_pData[index6], 
		float(rz+2)*10, g_Hmap.m_pLightColor[index6], 0.5f, 0.5f);
	// add
	pV[point++] = HeightmapVertex(float(rx+2)*10, g_Hmap.m_HeightData.m_pData[index22], 
		float(rz+1)*10, g_Hmap.m_pLightColor[index22], ((ax+dx)*0.5f+0.5f)*0.5f, ((az+dz)*0.5f+0.5f)*0.5f);

	pV[point++] = HeightmapVertex(float(rx+2)*10, g_Hmap.m_HeightData.m_pData[index7], 
		float(rz*10), g_Hmap.m_pLightColor[index7], (ax+dx)*0.5f, (az+dz)*0.5f);

	if(m_LODmap[z-1][x] == 1)
	{
		pV[point++] = HeightmapVertex(float(rx+1)*10, g_Hmap.m_HeightData.m_pData[index23], 
			float(rz*10), g_Hmap.m_pLightColor[index23], ((ax+dx)*0.5f+ax)*0.5f, ((az+dz)*0.5f+az)*0.5f);
		m_numTriangles++;
	}

	pV[point++] = HeightmapVertex(float(rx*10), g_Hmap.m_HeightData.m_pData[index0], 
		float(rz*10), g_Hmap.m_pLightColor[index0], ax, az);

	g_pD3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, point - 2, pV, sizeof(HeightmapVertex));

	point = 0;
	pV[point++] = HeightmapVertex(float(rx+1)*10, g_Hmap.m_HeightData.m_pData[index8], 
		float(rz+3)*10, g_Hmap.m_pLightColor[index8], (bx+0.5f)*0.5f, (bz+0.5f)*0.5f);

	pV[point++] = HeightmapVertex(float(rx*10), g_Hmap.m_HeightData.m_pData[index5], 
		float(rz+2)*10, g_Hmap.m_pLightColor[index5], (ax+bx)*0.5f, (az+bz)*0.5f);

	if(m_LODmap[z][x-1] == 1)
	{
		pV[point++] = HeightmapVertex(float(rx*10), g_Hmap.m_HeightData.m_pData[index24], 
			float(rz+3)*10, g_Hmap.m_pLightColor[index24], ((ax+bx)*0.5f+bx)*0.5f, ((az+bz)*0.5f+bz)*0.5f);
		m_numTriangles++;
	}

	pV[point++] = HeightmapVertex(float(rx*10), g_Hmap.m_HeightData.m_pData[index1], 
		float(rz+4)*10, g_Hmap.m_pLightColor[index1], bx, bz);

	if(m_LODmap[z+1][x] == 1)
	{
		pV[point++] = HeightmapVertex(float(rx+1)*10, g_Hmap.m_HeightData.m_pData[index25], 
			float(rz+4)*10, g_Hmap.m_pLightColor[index25], ((bx+cx)*0.5f+bx)*0.5f, ((bz+cz)*0.5f+bz)*0.5f);
		m_numTriangles++;
	}

	pV[point++] = HeightmapVertex(float(rx+2)*10, g_Hmap.m_HeightData.m_pData[index9], 

⌨️ 快捷键说明

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