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

📄 old_landscape.cpp

📁 c++程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Landscape.cpp: Implementierung der Klasse CLandscape.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Landscape.h"

// Conversion factor for converting between degrees and radians
#define PI_OVER_180 0.0174532925f

// RGB macros
#define RGB_GETRED(rgb)		(((rgb) >> 16) & 0xff) 
#define RGB_GETGREEN(rgb)	(((rgb) >> 8) & 0xff) 
#define RGB_GETBLUE(rgb)    ((rgb) & 0xff)

// Array index for axis
const int x = 0;
const int y = 1;
const int z = 2;

//////////////////////////////////////////////////////////////////////
// Konstruktion/Destruktion
//////////////////////////////////////////////////////////////////////

CLandscape::CLandscape()
{
	// Init member variables to default values
	m_StepSize      = 0.2f;
	m_TextureCount  = -1;
	m_ArrayWidth	= 0;
	m_ArrayHeight	= 0;
	m_LandscapeList = 0;
	m_HeightMapHeightScaling = 5.0f;

	// No surface height data array pointer present
	m_Surface = 0;
}

CLandscape::~CLandscape()
{
	// Delete surface height data array
	delete m_Surface;
	m_Surface = 0;
}

void CLandscape::GenerateLandscape(const char sHeightMapFileName[], const short int iArrayWidth,
								   const short int iArrayHeight)
{
	// Load heightmap file, calculate the triangles to make a landscape out of it and
	// render it into a display list

	//////////////////////////////////////////////////////////////////////
	// Declare variables
	//////////////////////////////////////////////////////////////////////
	
	// Save passed array height & width to the corresponding member variables
	// (Decrement cause array indexing starts with zero)
	m_ArrayWidth = iArrayWidth;
	m_ArrayWidth--;
	m_ArrayHeight = iArrayHeight;
	m_ArrayHeight--;

	// Loop variables
	int i; int j;

	// Set surface height array pointer. Store the surface height aray in the member data
	// cause GetSurfaceHeight() will need it after the calculation of the landscape has been
	// finished. Pass a 1 based element count.
	m_Surface = new CDynamicArray2D(m_ArrayWidth + 1, m_ArrayHeight + 1);

	// 3D Triangle array to hold all later calculated landscape triangles
	CLandscapeTriangle ***cTriangles = new CLandscapeTriangle ** [m_ArrayWidth + 1];
	for (i=0; i<m_ArrayWidth + 1; i++)
	{
		cTriangles[i] = new CLandscapeTriangle * [m_ArrayHeight + 1];
		for (j=0; j<m_ArrayHeight + 1; j++)
			cTriangles[i][j] = new CLandscapeTriangle[2];
	}

	// Vertex normal array to hold all the later calculated normals. Pass a 1 based
	// element count.
	CDynamicArray3D cVertexNormals(m_ArrayWidth + 1, m_ArrayHeight + 1, 3);

	//////////////////////////////////////////////////////////////////////
	// Load the heightmap into the member data
	//////////////////////////////////////////////////////////////////////

	LoadHeightmap(sHeightMapFileName);

	//////////////////////////////////////////////////////////////////////
	// Calculate surface from the loaded heightmap
	//////////////////////////////////////////////////////////////////////
	
	CalculateSurface(&cVertexNormals, cTriangles);

	//////////////////////////////////////////////////////////////////////
	// Render the loaded landscape into a displaylist
	//////////////////////////////////////////////////////////////////////

	RenderToDisplayList(&cVertexNormals, cTriangles);

	//////////////////////////////////////////////////////////////////////
	// Clean up
	//////////////////////////////////////////////////////////////////////

	// Delete triangle array
	for (i=0; i<m_ArrayWidth + 1; i++)
	{
		for (j=0; j<m_ArrayHeight + 1; j++)
			delete[] cTriangles[i][j];

		delete[] cTriangles[i];
	}
	delete cTriangles;
	cTriangles = 0;
}

void CLandscape::CalculateSurface(CDynamicArray3D *cVertexNormals, CLandscapeTriangle ***cTriangles)
{
	// Fill the passed arrays with the data from in the member data stored surface height array, which
	// must be already calculated. The m_ArrayHeight and m_ArrayWidth member variables need to be set,
	// pointers have to be valid, pointers are not deleted.

	// Loop trough the whole surface array
	for (int iY=0; iY<=m_ArrayHeight - 1; iY++)
		for (int iX=0; iX<=m_ArrayWidth - 1; iX++)
		{
			// Set random texture index
			cTriangles[iX][iY][0].m_TextureIndex = 
				cTriangles[iX][iY][1].m_TextureIndex = Rnd(m_TextureCount + 1);
			
			// Lower-left triangle
					
			// Calculate and set triangle vertices
			cTriangles[iX][iY][0].m_Vertices[0][x] = iY * m_StepSize;
			cTriangles[iX][iY][0].m_Vertices[0][y] = m_Surface->m_Array[iX][iY];
			cTriangles[iX][iY][0].m_Vertices[0][z] = iX * m_StepSize;
			cTriangles[iX][iY][0].m_Vertices[1][x] = (iY + 1) * m_StepSize;
			cTriangles[iX][iY][0].m_Vertices[1][y] = m_Surface->m_Array[iX+1][iY+1];
			cTriangles[iX][iY][0].m_Vertices[1][z] = (iX + 1) * m_StepSize;
			cTriangles[iX][iY][0].m_Vertices[2][x] = (iY + 1) * m_StepSize;
			cTriangles[iX][iY][0].m_Vertices[2][y] = m_Surface->m_Array[iX][iY+1];
			cTriangles[iX][iY][0].m_Vertices[2][z] = iX * m_StepSize;

			// Calculate normal
			cTriangles[iX][iY][0].CalcNormal();

			cVertexNormals->m_Array[iX][iY][x]		+= cTriangles[iX][iY][0].m_Normal[x];
			cVertexNormals->m_Array[iX+1][iY+1][y]	+= cTriangles[iX][iY][0].m_Normal[y];
			cVertexNormals->m_Array[iX][iY+1][z]	+= cTriangles[iX][iY][0].m_Normal[z];

			cVertexNormals->m_Array[iX][iY][x]		+= cTriangles[iX][iY][0].m_Normal[x];
			cVertexNormals->m_Array[iX+1][iY+1][y]	+= cTriangles[iX][iY][0].m_Normal[y];
			cVertexNormals->m_Array[iX][iY+1][z]	+= cTriangles[iX][iY][0].m_Normal[z];

			cVertexNormals->m_Array[iX][iY][x]		+= cTriangles[iX][iY][0].m_Normal[x];
			cVertexNormals->m_Array[iX+1][iY+1][y]	+= cTriangles[iX][iY][0].m_Normal[y];
			cVertexNormals->m_Array[iX][iY+1][z]	+= cTriangles[iX][iY][0].m_Normal[z];
			
			// Upper right triangle

			// Calculate and set triangle vertices
			cTriangles[iX][iY][1].m_Vertices[0][x] = iY * m_StepSize;
			cTriangles[iX][iY][1].m_Vertices[0][y] = m_Surface->m_Array[iX+1][iY];
			cTriangles[iX][iY][1].m_Vertices[0][z] = (iX + 1) * m_StepSize;
			cTriangles[iX][iY][1].m_Vertices[1][x] = (iY + 1) * m_StepSize;
			cTriangles[iX][iY][1].m_Vertices[1][y] = m_Surface->m_Array[iX+1][iY+1];
			cTriangles[iX][iY][1].m_Vertices[1][z] = (iX + 1) * m_StepSize;
			cTriangles[iX][iY][1].m_Vertices[2][x] = iY * m_StepSize;
			cTriangles[iX][iY][1].m_Vertices[2][y] = m_Surface->m_Array[iX][iY];
			cTriangles[iX][iY][1].m_Vertices[2][z] = iX * m_StepSize;
					
			// Calculate normal
			cTriangles[iX][iY][1].CalcNormal();

			cVertexNormals->m_Array[iX+1][iY][x]	+= cTriangles[iX][iY][1].m_Normal[x];
			cVertexNormals->m_Array[iX+1][iY+1][y]	+= cTriangles[iX][iY][1].m_Normal[y];
			cVertexNormals->m_Array[iX][iY][z]		+= cTriangles[iX][iY][1].m_Normal[z];

			cVertexNormals->m_Array[iX+1][iY][x]	+= cTriangles[iX][iY][1].m_Normal[x];
			cVertexNormals->m_Array[iX+1][iY+1][y]	+= cTriangles[iX][iY][1].m_Normal[y];
			cVertexNormals->m_Array[iX][iY][z]		+= cTriangles[iX][iY][1].m_Normal[z];

			cVertexNormals->m_Array[iX+1][iY][x]	+= cTriangles[iX][iY][1].m_Normal[x];
			cVertexNormals->m_Array[iX+1][iY+1][y]	+= cTriangles[iX][iY][1].m_Normal[y];
			cVertexNormals->m_Array[iX][iY][z]		+= cTriangles[iX][iY][1].m_Normal[z];
		}

	// Convert all normals to unit length
	for (int iCurNormalX=0; iCurNormalX<=m_ArrayWidth; iCurNormalX++)
		for (int iCurNormalY=0; iCurNormalY<=m_ArrayHeight; iCurNormalY++)
			if (iCurNormalX == 0 || iCurNormalY == 0)
			{
				// Special handling for the normals that don't have six neighbor planes
				cVertexNormals->m_Array[iCurNormalX][iCurNormalY][x] = 0.0f;
				cVertexNormals->m_Array[iCurNormalX][iCurNormalY][y] = 1.0f;
				cVertexNormals->m_Array[iCurNormalX][iCurNormalY][z] = 0.0f;
			}
			else
			{
				cVertexNormals->m_Array[iCurNormalX][iCurNormalY][x] /= 3.0f;
				cVertexNormals->m_Array[iCurNormalX][iCurNormalY][y] /= 3.0f;
				cVertexNormals->m_Array[iCurNormalX][iCurNormalY][z] /= 3.0f;
			}
}

void CLandscape::RenderToDisplayList(CDynamicArray3D *cVertexNormals, CLandscapeTriangle ***cTriangles)
{
	// Render the loaded landscape into a displaylist. The m_ArrayHeight and m_ArrayWidth
	// member variables need to be set, pointers have to be valid, pointers are not deleted.

	// Generate a displaylist index
	m_LandscapeList = glGenLists(1);

	// Use passed display list index
	glNewList(m_LandscapeList, GL_COMPILE);

		// Bright base color
		glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

		// Are any textures loaded ?
		int iStartIndex;
		if (m_TextureCount == -1)

⌨️ 快捷键说明

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