📄 terrain.cpp
字号:
#include "Terrain.h"
//----------------------------------------------------------------------
// 函数名称:HeightMap::TextureTileManeger::~TextureTileManeger - public
// 描述:析构函数
// 参数:None
// 返回:None
//----------------------------------------------------------------------
HeightMap::TextureTileManeger::~TextureTileManeger()
{
// 删除所有载入的纹理对象
for (size_t i = 0; i < m_vecTexture.size(); ++i)
{
if (m_vecTexture[i] != NULL)
{
delete m_vecTexture[i];
}
}
// 删除所有载入的纹理对象的作用区域
for (size_t i = 0; i < m_vecTextureRegion.size(); ++i)
{
if (m_vecTextureRegion[i] != NULL)
{
delete m_vecTextureRegion[i];
}
}
}
//-----------------------------------------
// 函数名称:HeightMap::~HeightMap - public
// 描述:虚析构函数
// 参数:None
// 返回:None
//-----------------------------------------
HeightMap::~HeightMap()
{
// 删除高度数据
CleanUpHeightData();
// 释放地形纹理数据资源
CleanUpTerrainTextureData();
}
//-----------------------------------------------
// 函数名称:HeightMap::CleanUpHeightData - public
// 描述:释放高度数据资源
// 参数:None
// 返回:None
//-----------------------------------------------
GLvoid HeightMap::CleanUpHeightData()
{
delete [] m_pHeightData;
m_pHeightData = NULL;
m_iHeightMapSize = 0;
m_fScale = 0.0f;
}
//-----------------------------------------------
// 函数名称:HeightMap::CleanUpHeightData - public
// 描述:释放地形纹理数据资源
// 参数:None
// 返回:None
//-----------------------------------------------
GLvoid HeightMap::CleanUpTerrainTextureData()
{
// 删除地形纹理数据
if (m_uiTerrainTextureID != 0)
{
glDeleteLists(m_uiTerrainTextureID, 1);
m_uiTerrainTextureID = 0;
}
if (m_pTerrainData != NULL)
{
delete [] m_pTerrainData;
m_pTerrainData = NULL;
}
}
//--------------------------------------------------------
// 函数名称:HeightMap::CleanUpIlluminationData - public
// 描述:释放光照数据资源
// 参数:None
// 返回:None
//--------------------------------------------------------
GLvoid HeightMap::CleanUpIlluminationData()
{
delete [] m_pIlluminationData;
m_pIlluminationData = NULL;
m_iIlluminationMapSize = 0;
m_IlluminationType = NoIllumination;
}
//-----------------------------------------------------
// 函数名称:HeightMap::LoadHeightMapFromFile - public
// 描述:从文件载入高度图
// 参数:heightMapFilePath - 高度图文件路径
// size - 高度图的尺寸
// 返回:GL_TRUR - 成功载入高度图文件
// G_FALSE - 载入高度图文件失败
//-----------------------------------------------------
GLboolean HeightMap::LoadHeightMapFromFile(const string &heightMapFilePath, GLint size)
{
// 文件指针
FILE* pFile = NULL;
// 打开文件
pFile = fopen(heightMapFilePath.c_str(), "rb");
// 错误检测
if (pFile == NULL)
{
// 错误信息:打开文件错误
return GL_FALSE;
}
// 检测是否类中已保存有高度图
if (m_pHeightData != NULL)
{
CleanUpHeightData(); // 卸载之前的高度图
}
// 记录尺寸信息
m_iHeightMapSize = size;
// 为高度图分配内存
m_pHeightData = new GLubyte[m_iHeightMapSize*m_iHeightMapSize];
// 读取高度图的高度信息,0 -- 255的值
fread(m_pHeightData, 1, m_iHeightMapSize*m_iHeightMapSize, pFile);
// 关闭文件
fclose(pFile);
return GL_TRUE;
}
//----------------------------------------------------
// 函数名称:HeightMap::WriteHeightMapToFile - public
// 描述:将当前保存在类中的高度图数据写进一个文件中
// 参数:heightMapFileName - 写进文件位置
// 返回:GL_TRUE - 成功将高度图数据写进文件中
// GL_FALSE - 将高度图数据写进文件中失败
//----------------------------------------------------
GLboolean HeightMap::WriteHeightMapToFile(const string &heightMapFileName) const
{
// 检测类中是否保存有高度图
if (m_pHeightData == NULL)
{
// 错误信息:此类对象中未保存有任何高度图
return GL_FALSE;
}
// 文件指针
FILE* pFile = NULL;
// 创建文件
pFile = fopen(heightMapFileName.c_str(), "wb");
if (pFile == NULL)
{
// 错误信息:创建高度图文件失败
return GL_FALSE;
}
// 将高度图的高度数据写进高度文件中
fwrite(m_pHeightData, 1, m_iHeightMapSize*m_iHeightMapSize, pFile);
// 关闭文件
fclose(pFile);
return GL_TRUE;
}
//-----------------------------------------------------------
// 函数名称:HeightMap::LoadIlluminationMapFromFile - public
// 描述:从文件中载入照明图
// 参数:illuminationFilePath - 照明图文件路径
// size - 照明图的尺寸
// 返回:GL_TRUR - 成功载入照明图文件
// G_FALSE - 载入照明图文件失败
//-----------------------------------------------------------
GLboolean HeightMap::LoadIlluminationMapFromFile(const string &illuminationFilePath, GLint size)
{
// 文件指针
FILE* pFile = NULL;
// 打开文件
pFile = fopen(illuminationFilePath.c_str(), "rb");
// 错误检测
if (pFile == NULL)
{
// 错误信息:打开文件错误
return GL_FALSE;
}
// 检测是否类中已保存有照明图
if (m_pIlluminationData != NULL)
{
CleanUpIlluminationData(); // 卸载之前的照明图
}
// 记录尺寸信息
m_iIlluminationMapSize = size;
// 为照明图分配内存
m_pIlluminationData = new GLubyte[m_iIlluminationMapSize*m_iIlluminationMapSize];
// 读取高度图的高度信息,0 -- 255的值
fread(m_pIlluminationData, 1, m_iIlluminationMapSize*m_iIlluminationMapSize, pFile);
// 关闭文件
fclose(pFile);
return GL_TRUE;
}
//---------------------------------------------------------
// 函数名称:HeightMap::WriteIlluminationMapToFile - public
// 描述:将照明图写进一个文件中
// 参数:illuminationMapFileName - 写进文件位置
// 返回:GL_TRUE - 成功将照明图数据写进文件中
// GL_FALSE - 将照明图数据写进文件中失败
//---------------------------------------------------------
GLboolean HeightMap::WriteIlluminationMapToFile(const string &illuminationMapFileName) const
{
// 检测类中是否保存有高度图
if (m_pIlluminationData == NULL)
{
// 错误信息:此类对象中未保存有任何照明图
return GL_FALSE;
}
// 文件指针
FILE* pFile = NULL;
// 创建文件
pFile = fopen(illuminationMapFileName.c_str(), "wb");
if (pFile == NULL)
{
// 错误信息:创建高度图文件失败
return GL_FALSE;
}
// 将高度图的高度数据写进高度文件中
fwrite(m_pIlluminationData, 1, m_iIlluminationMapSize*m_iIlluminationMapSize, pFile);
// 关闭文件
fclose(pFile);
return GL_TRUE;
}
//-------------------------------------------------
// 函数名称:HeightMap::NormalizeTerrain - private
// 描述:规范化地形高度值到0 -- 255的范围内
// 参数:heightData - 临时保存的GLfloat高度数据
// 返回:GL_TRUE -成功规范化地形
// GL_FALSE - 规范化地形失败
//-------------------------------------------------
GLboolean HeightMap::NormalizeTerrain(GLfloat *heightData)
{
// 保存最大和最小高度值
GLfloat fMin = heightData[0];
GLfloat fMax = heightData[0];
GLuint uiTotalSize = m_iHeightMapSize*m_iHeightMapSize;
// 计算最大和最小高度值
for(GLuint i = 1; i < uiTotalSize; ++i)
{
if(heightData[i] > fMax)
{
fMax = heightData[i];
}
else if(heightData[i] < fMin)
{
fMin = heightData[i];
}
}
// 错误检测
if(fMax <= fMin)
{
// 错误信息;生成的高度不正确,规范化地形错误
return GL_FALSE;
}
// 计算高度差
GLfloat fHeightDifference = fMax - fMin;
// 将高度值缩放到0.0f -- 255.0f的范围内
for(GLuint i = 0; i < uiTotalSize; ++i)
{
heightData[i] = (heightData[i] - fMin)/fHeightDifference*255.0f;
}
return GL_TRUE;
}
//-----------------------------------------------------
// 函数名称:HeightMap::FilterHeightArea - private
// 描述:为使用Fault Formation算法生成地形进行过滤融合
// 参数:heightData - 临时保存的GLfloat高度数据
// stride - 过滤点的间隔数
// filter - 过滤线性差值混合参数
// 返回:None
//-----------------------------------------------------
GLvoid HeightMap::FilterHeightArea(GLfloat *heightData, GLint stride, GLuint count, GLfloat filter)
{
GLfloat previousHeight = heightData[0]; // 前一点的高度
GLuint uiStride = stride; // 记录跨距
// 过滤整个地形,与前一个高度值进行线性差值
for(GLuint i = 0; i < count - 1; ++i)
{
heightData[uiStride] = filter*previousHeight + (1.0f - filter)*heightData[uiStride];
previousHeight = heightData[uiStride]; // 为下一个线性差值做准备
uiStride += stride;
}
}
//-----------------------------------------------------
// 函数名称:HeightMap::FilterHeightField - private
// 描述:以各个方向对整个地形进行过滤融合
// 参数:heightData - 临时保存的GLfloat高度数据
// filter - 过滤线性差值混合参数
// 返回:None
//-----------------------------------------------------
GLvoid HeightMap::FilterHeightField(GLfloat *heightData, GLfloat filter)
{
// 对过滤算法的理解:从左右上下四个
//方向对高度图值进行差值融合,以
// 使整个高度图趋向于平滑
// 临时变量
GLint i;
// 对高度图的每一行自左向右过滤地形
for(i = 0; i < m_iHeightMapSize; ++i)
{
FilterHeightArea(&heightData[m_iHeightMapSize*i], 1, m_iHeightMapSize, filter);
}
// 对高度图的每一行自右向左过滤地形
for(i = 0; i < m_iHeightMapSize; ++i)
{
FilterHeightArea(&heightData[m_iHeightMapSize*i + m_iHeightMapSize - 1], -1, m_iHeightMapSize, filter);
}
// 对高度图的每一列自上向下过滤地形
for(i = 0; i < m_iHeightMapSize; ++i)
{
FilterHeightArea(&heightData[i], m_iHeightMapSize, m_iHeightMapSize, filter);
}
// 对高度图的每一列自下向上过滤地形
for(i = 0; i < m_iHeightMapSize; ++i)
{
FilterHeightArea(&heightData[m_iHeightMapSize*(m_iHeightMapSize - 1) + i], -m_iHeightMapSize, m_iHeightMapSize, filter);
}
}
//-------------------------------------------------------
// 函数名称:HeightMap::GenerateTerrainWithFault - public
// 描述:使用Fault Formation算法生成地形
// 参数:size - 地形的尺寸
// iterationTime - 指定生成地形的跌代次数
// minHeight - 地形的最小高度
// maxHeight - 地形的最大高度
// filter - 过滤地形的参数
// 返回:GLTRUE - 成功生成地形
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -