需要用到的外部图片资源:

在ogre调用时需要多用到的几个外部dll:

OgreTerrain_d.dll

需要添加头文件

#include "Ogre\Ogre.h"
#include "Ogre\OgreFileSystemLayer.h"
#include "Ogre\OgreTerrain.h"
#include "Ogre\OgreTerrainGroup.h"
#include "Ogre\OgreTerrainQuadTreeNode.h"
#include "Ogre\OgreTerrainMaterialGeneratorA.h"
#include "Ogre\OgreTerrainPaging.h"

定义类初始化需要的结构体

struct CrisTerrainInitStruct
{
CrisTerrainInitStruct():m_scenemanager(NULL),fMaxHoriz(1000),fMinHoriz(0),sMapFilename(""),sElevationFilename(""),fMapSize(TERRAIN_WORLD_SIZE)
{
fInputScale = fMaxHoriz - fMinHoriz;
}
SceneManager* m_scenemanager;
String sMapFilename; //地图卫星图片
String sElevationFilename;//高程图
Real fMinHoriz;//最低点
Real fMaxHoriz;//最高点
Real fMapSize;//地形边长
Real fInputScale; //地形高低差 对比像素的0~1 .可以不需要设置
//位置放在000点,
};

类的外部接口

void Init(CrisTerrainInitStruct* sInitData);

实现的一些重要步骤:

第一步  创建地形全局配置 TerrainGlobalOptions

mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();
//TerrainGlobalOptions是一个类,定义了地形块的一些全局变量和默认值,需要的话我们可以改变他的变量参数,我们后面再做改变。

 第二步  创建地形分组Ogre::TerrainGroup

//实例化一个TerrainGroup对象

mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, m_sInitData->fMapSize);

第三步  配置地图块参数 configureTerrainDefaults

configureTerrainDefaults();

第四步  创建地形分块

//defineTerrain方法首先要指定该块地形在地形分组中的索引位置,然后第三个参数必须指定高度数据,用灰度图创建山地地形
for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)
for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)
defineTerrain(x, y, blankTerrain);

下面是我的代码:

头文件:

#pragma once
#define DebugTerrain
#include "Ogre\Ogre.h"
#include "Ogre\OgreFileSystemLayer.h"
#include "CrisConfig\CrisConfig.h"
#include "Ogre\OgreTerrain.h"
#include "Ogre\OgreTerrainGroup.h"
#include "Ogre\OgreTerrainQuadTreeNode.h"
#include "Ogre\OgreTerrainMaterialGeneratorA.h"
#include "Ogre\OgreTerrainPaging.h"//分页多少
#define TERRAIN_PAGE_MIN_X 0
#define TERRAIN_PAGE_MIN_Y 0
#define TERRAIN_PAGE_MAX_X 0
#define TERRAIN_PAGE_MAX_Y 0#define TERRAIN_FILE_PREFIX String("testTerrain")
#define TERRAIN_FILE_SUFFIX String("dat")
#define TERRAIN_WORLD_SIZE 1200.0f
#define TERRAIN_SIZE 513using namespace Ogre;struct CrisTerrainInitStruct
{CrisTerrainInitStruct():m_scenemanager(NULL),fMaxHoriz(1000),fMinHoriz(0),sMapFilename(""),sElevationFilename(""),fMapSize(TERRAIN_WORLD_SIZE){fInputScale = fMaxHoriz - fMinHoriz;}SceneManager* m_scenemanager;String           sMapFilename;   //地图卫星图片String          sElevationFilename;//高程图Real            fMinHoriz;//最低点Real         fMaxHoriz;//最高点Real         fMapSize;//地形边长Real         fInputScale;    //地形高低差 对比像素的0~1 .可以不需要设置
//位置放在000点,
};class CrisTerrain
{
public:CrisTerrain();~CrisTerrain();void Init(CrisTerrainInitStruct*    sInitData);//void setTerrainImage(const Ogre::String& szCfgFilename = "terrain_texture.jpg");protected:TerrainGlobalOptions* mTerrainGlobals;TerrainGroup* mTerrainGroup;TerrainPaging* mTerrainPaging;PageManager* mPageManager;void testOption();//为了小样例测试加载的,在大工程中可以直接不用
private:CrisTerrainInitStruct*  m_sInitData;void loadConfigFile(const Ogre::String& szCfgFilename = "");Ogre::String                     m_szConfigFileName;CCrisConfigManager                  m_hConfigMgr;bool mFly;Real mFallVelocity;Real mBrushSizeTerrainSpace;Real mHeightUpdateCountDown;Real mHeightUpdateRate;Vector3 mTerrainPos;bool mTerrainsImported;SceneManager*            mSceneMgr;/** @brief 实例化地形 */void setupContent();/** @brief 实例化地形参数 */void configureTerrainDefaults();void initBlendMaps(Terrain* terrain);void defineTerrain(long x, long y, bool flat = false);void getTerrainImage(bool flipX, bool flipY, Image& img);};

  实现文件:

#include "Terrain.h"CrisTerrain::CrisTerrain(): mTerrainGroup(0), mTerrainPaging(0), mPageManager(0), mFallVelocity(0), mBrushSizeTerrainSpace(0.02), mHeightUpdateCountDown(0), mTerrainPos(0,0,0), mTerrainsImported(false)
{}CrisTerrain::~CrisTerrain()
{}void CrisTerrain::Init(CrisTerrainInitStruct* sInitData)
{mSceneMgr = sInitData->m_scenemanager;m_sInitData = sInitData;setupContent();//loadConfigFile("terrain.cfg");
}void CrisTerrain::loadConfigFile(const String& szFilename)
{if(!szFilename.empty())m_szConfigFileName = szFilename;elsereturn;//m_hConfigMgr.LoadFromResourceSystem(m_szConfigFileName);//String worldTexture = m_hConfigMgr.GetValueString("Ter", "WorldTexture", "testter.jpg");//OutputDebugString(worldTexture.c_str());}//void CrisTerrain::setTerrainImage(const Ogre::String& szCfgFilename)
//{
//  Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
//  defaultimp.terrainSize = TERRAIN_SIZE;//不太了解,调试中,这个值越小,地图边缘锯齿现象越严重,太小的话,运行起来程序会跑死、出错
//  defaultimp.worldSize = m_sInitData->fMapSize;//假设为a,那么地图大小为 a x a
//  defaultimp.inputScale = 60;//决定地图最大落差(高度),即位图中白色和黑色部分的高度差
//  defaultimp.minBatchSize = 33;
//  defaultimp.maxBatchSize = 65;
//  // textures
//  defaultimp.layerList.resize(3);//这里设置了3层纹理,DDS为一种高级的纹理模式,DirectDrawSurface,觉得难以理解的话
可以理解为一种特殊的.jpg图片模式,但是用DDS质材的话可以接收并显示地形阴影,用JPG就显示不出来,而且据我调试观
察发现,第一个.dds质材是用来显示纹理图形,第二个.dds才是用来接收和显示阴影的
//
//  defaultimp.layerList[0].worldSize = 1;//这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊
//  defaultimp.layerList[0].textureNames.push_back(szCfgFilename);
//  defaultimp.layerList[0].textureNames.push_back(szCfgFilename);
//  defaultimp.layerList[1].worldSize = 1;
//  defaultimp.layerList[1].textureNames.push_back(szCfgFilename);
//  defaultimp.layerList[1].textureNames.push_back(szCfgFilename);
//  defaultimp.layerList[2].worldSize = 2;
//  defaultimp.layerList[2].textureNames.push_back(szCfgFilename);
//  defaultimp.layerList[2].textureNames.push_back(szCfgFilename);
//
//  mTerrainGroup->loadAllTerrains(true);
//
//  if (mTerrainsImported)
//  {
//      TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
//      while(ti.hasMoreElements())
//      {
//          Terrain* t = ti.getNext()->instance;
//          initBlendMaps(t);
//      }
//  }
//
//  mTerrainGroup->freeTemporaryResources();
//}void CrisTerrain::testOption()
{//mEditMarker = mSceneMgr->createEntity("editMarker", "sphere.mesh");//mEditNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();//mEditNode->attachObject(mEditMarker);//mEditNode->setScale(0.05, 0.05, 0.05);Ogre::FileSystemLayer* mFSLayer = OGRE_NEW_T(Ogre::FileSystemLayer, Ogre::MEMCATEGORY_GENERAL)(OGRE_VERSION_NAME);ResourceGroupManager::getSingleton().createResourceGroup("Terrain");ResourceGroupManager::getSingleton().addResourceLocation(mFSLayer->getWritablePath(""), "FileSystem", "Terrain", false, false);MaterialManager::getSingleton().setDefaultTextureFiltering(TFO_ANISOTROPIC);MaterialManager::getSingleton().setDefaultAnisotropy(7);//mSceneMgr->setFog(FOG_LINEAR, ColourValue(0.7, 0.7, 0.8), 0, 1000, 2500);LogManager::getSingleton().setLogDetail(LL_BOREME);mSceneMgr->setAmbientLight(ColourValue(0.6, 0.6, 0.6));create a few entities on the terrain//Entity* e = mSceneMgr->createEntity("tudorhouse.mesh");//Vector3 entPos(mTerrainPos.x + 2043, 0, mTerrainPos.z + 1715);//Quaternion rot;//entPos.y = mTerrainGroup->getHeightAtWorldPosition(entPos) + 65.5 + mTerrainPos.y;//rot.FromAngleAxis(Degree(Math::RangeRandom(-180, 180)), Vector3::UNIT_Y);//SceneNode* sn = mSceneMgr->getRootSceneNode()->createChildSceneNode(entPos, rot);//sn->setScale(Vector3(0.12, 0.12, 0.12));//sn->attachObject(e);//mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
}void CrisTerrain::setupContent()
{bool blankTerrain = false;//blankTerrain = true;mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();//TerrainGlobalOptions是一个类,定义了地形块的一些全局变量和默认值,需要的话我们可以改变他的变量参数,我们后面再做改变。#ifdef DebugTerraintestOption();
#endif//创建地形分组Ogre::TerrainGroup    /*实例化一个TerrainGroup对象参数1:为他指定场管理器、参数2:地形的平铺方向,平铺方向一般采用ALIGN_X_Z,也就是采用Y作为高度参数3:unit16 TERRAINSIZE=2~n+1,比如512+1=513,不符合公式的可能会导致地图显示异常,表示“Thesize of each terrain down one edge in vertices (2^n+1)”楼主只能理解意思,不能完全正确表达其中的专有名词,实际调试中,这个参数影响地图边缘的锯齿度,越小锯齿越明显,取值太小的话,运行会错误;参数4:Real TERRAINWORLDSIZE,地图大小,表示地图正方形的边长)*/mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, m_sInitData->fMapSize);//定义命名前缀mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX);//设置了该地形组的起始位置,在以后创建的地形块中均采用此位置作为相对位置mTerrainGroup->setOrigin(mTerrainPos);mTerrainGroup->setResourceGroup("Terrain");//配置地图块参数 configureTerrainDefaultsconfigureTerrainDefaults();for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)defineTerrain(x, y, blankTerrain);// 开始前加载好mTerrainGroup->loadAllTerrains(true);if (mTerrainsImported){TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();while(ti.hasMoreElements()){Terrain* t = ti.getNext()->instance;initBlendMaps(t);}}mTerrainGroup->freeTemporaryResources();
}void CrisTerrain::getTerrainImage(bool flipX, bool flipY, Image& img)
{img.load(m_sInitData->sElevationFilename, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);if (flipX)img.flipAroundY();if (flipY)img.flipAroundX();}void CrisTerrain::defineTerrain(long x, long y, bool flat)
{// if a file is available, use it// if not, generate file from import// Usually in a real project you'll know whether the compact terrain data is// available or not; I'm doing it this way to save distribution sizeif (flat){mTerrainGroup->defineTerrain(x, y, 0.0f);}else{String filename = mTerrainGroup->generateFilename(x, y);if (ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename)){mTerrainGroup->defineTerrain(x, y);}else{Image img;getTerrainImage(x % 2 != 0, y % 2 != 0, img);mTerrainGroup->defineTerrain(x, y, &img);mTerrainsImported = true;}}
}void CrisTerrain::configureTerrainDefaults()
{// Configure globalmTerrainGlobals->setMaxPixelError(8);// testing composite mapmTerrainGlobals->setCompositeMapDistance(3000);//距离镜头超过3000部分使用地图合成(CompositeMap)模式表现//mTerrainGlobals->setUseRayBoxDistanceCalculation(true);//mTerrainGlobals->getDefaultMaterialGenerator()->setDebugLevel(1);//mTerrainGlobals->setLightMapSize(256);// Configure default import settings for if we use imported imageTerrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();defaultimp.terrainSize = TERRAIN_SIZE;//不太了解,调试中,这个值越小,地图边缘锯齿现象越严重,太小的话,运行起来程序会跑死、出错defaultimp.worldSize = m_sInitData->fMapSize;//假设为a,那么地图大小为 a x adefaultimp.inputScale = m_sInitData->fInputScale;//决定地图最大落差(高度),即位图中白色和黑色部分的高度差defaultimp.minBatchSize = 33;defaultimp.maxBatchSize = 65;// texturesdefaultimp.layerList.resize(3);//这里设置了3层纹理,DDS为一种高级的纹理模式,DirectDrawSurface,觉得难以理解的话
//可以理解为一种特殊的.jpg图片模式,但是用DDS质材的话可以接收并显示地形阴影,用JPG就显示不出来,而且据我调试观
//察发现,第一个.dds质材是用来显示纹理图形,第二个.dds才是用来接收和显示阴影的defaultimp.layerList[0].worldSize = m_sInitData->fMapSize;//这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊defaultimp.layerList[0].textureNames.push_back(m_sInitData->sMapFilename);defaultimp.layerList[0].textureNames.push_back(m_sInitData->sMapFilename);defaultimp.layerList[1].worldSize = m_sInitData->fMapSize;defaultimp.layerList[1].textureNames.push_back("white2.dds");defaultimp.layerList[1].textureNames.push_back("white2.dds");defaultimp.layerList[2].worldSize = m_sInitData->fMapSize;defaultimp.layerList[2].textureNames.push_back("white2.dds");defaultimp.layerList[2].textureNames.push_back("white2.dds");//defaultimp.layerList[0].worldSize = 100;//这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊//defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");//defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");//defaultimp.layerList[1].worldSize = 30;//defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");//defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");//defaultimp.layerList[2].worldSize = 100;//defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");//defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");
}void CrisTerrain::initBlendMaps(Terrain* terrain)
{TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1);TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2);Real minHeight0 = 70;Real fadeDist0 = 40;Real minHeight1 = 70;Real fadeDist1 = 15;float* pBlend1 = blendMap1->getBlendPointer();for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y){for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x){Real tx, ty;blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty);Real height = terrain->getHeightAtTerrainPosition(tx, ty);Real val = (height - minHeight0) / fadeDist0;Math::Clamp(val, (Real)0, (Real)1);val = (height - minHeight1) / fadeDist1;val = Math::Clamp(val, (Real)0, (Real)1);*pBlend1++ = val;}}blendMap0->dirty();blendMap1->dirty();//blendMap0->loadImage("blendmap1.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);blendMap0->update();blendMap1->update();// set up a colour map/*if (!terrain->getGlobalColourMapEnabled()){terrain->setGlobalColourMapEnabled(true);Image colourMap;colourMap.load("testcolourmap.jpg", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);terrain->getGlobalColourMap()->loadImage(colourMap);}*/}

  

转载于:https://www.cnblogs.com/lyggqm/p/5507689.html

[Ogre][地形][原创]基于OgreTerrain的地形实现相关推荐

  1. 基于GeoMipmap的地形系统。

    这两天做了一个基于GeoMipmap的地形系统,程序采用四叉树进行剔除,采用Texture Splate进行纹理映射,顶点渐变使用Shader实现,几何破裂现象采用了Chunk LOD的做法,也就是给 ...

  2. [转]的C#实现三维数字地形漫游(基于Irrlicht)

    马省轩  任丽娜 摘  要:本文采用C#编程语言,利用Irrlicht三维图形引擎实现了三维数字地形的漫游.为三维数字地形显示提供了较易实现的解决方案. 关键词:C#   高度图 Irrlicht引擎 ...

  3. 基于OpenGL的地形建模技术的研究与实现

    毕业论文 基于OpenGL的地形建模技术的研究与实现 诚信声明 本人郑重声明:本设计(论文)及其研究工作是本人在指导教师的指导下独立完成的,在完成设计(论文)时所利用的一切资料均已在参考文献中列出. ...

  4. 基于ArcGIS的地形分析——流向、流量、SPI、TWI计算

    基于ArcGIS的地形分析--流向.流量.SPI.TWI计算 1. 参考资料 https://www.leg.mn.gov/docs/2016/mandated/160722.pdf 参考目录: 该手 ...

  5. [GIS原理] 9 数字地形分析DTA、数字地形模型DTM、数字高程模型DEM、数字地表模型DSM、不规则三角网TIN

    在知识传播途中,向涉及到的相关著作权人谨致谢意! 文章目录 1 数字地形分析(DTA) 1.1 数字地形模型(DTM) 1.1.1 DSM与DEM对比 1.2 数字地形分析研究与应用进展 1.2.1 ...

  6. Unity 3D 地形系统概述|| Unity 3D 创建地形

    在三维游戏世界中,通常会将丰富多彩的游戏元素融合在一起,比如游戏中起伏的地形.郁郁葱葱的树木.蔚蓝的天空..凶恶的猛兽等,营造出身临其境的游戏沉浸感,让玩家置身游戏世界,忘记现实. 地形作为游戏场景中 ...

  7. (原创)基于ZedBoard的Webcam设计(二):USB摄像头图片采集+QT显示

    在(原创基于ZedBoard的Webcam设计(一):Zedboard上的USB摄像头(V4L2接口)的图片采集中,我们完成了ZedBoard上USB摄像头的单幅图片采集,采集到的图片是存储在文件系统 ...

  8. Android加密通信防抓包,[原创]基于Taintdroid思想的android ssl\tsl保密通信抓包研究(未成功,分享一下思路)...

    [旧帖] [原创]基于Taintdroid思想的android ssl\tsl保密通信抓包研究(未成功,分享一下思路) 0.00元 2014-5-12 22:07 1565 [旧帖] [原创]基于Ta ...

  9. [原创]基于Comsol的方形、三角形、椭圆形克拉尼板仿真研究

    [原创]基于Comsol的方形.三角形.椭圆形克拉尼板仿真研究 **起因:**很早就看到过这种能把声波可视化的技术了,但仍然停留在第1次看到时候的震撼当中,也一直在思考这物理层面上是用什么方程来描述的 ...

  10. Ogre 编辑器二(用Ogre的地形组件加载天龙八部地形)

    主界面如上文设计完成后,场景刚开始添加了是Ogre例子里的,发现场景里实物太少,于是想到直接把天龙的场景拿下来,天龙网上有源码,参考了下,把天龙的地形用Ogre的地形组件完成了下,如下是效果图: 因为 ...

最新文章

  1. 误删/usr/bin/python2.7解决方案
  2. python列表索引负数_python – 如何检查列表索引是否存在?
  3. 判断用户输入的银行卡号是否正确--基于Luhn算法的格式校验
  4. python字符串截取split 失败_python如何截断字符串
  5. java面向对象编程集合边框_第六章使用java实现面向对象-集合框架
  6. 拿什么拯救你,程序新丁?
  7. 论文阅读笔记(七)——Thin MobileNet
  8. nodejs的moment操作时间
  9. vmlinuz 文件解压缩(zImage|bzImage)
  10. 用c语言写财务软件,财务软件,您选对了吗?T+/T+C、T3深度实测对比
  11. Android根据包名获取APP名称
  12. Win/ubuntu16.04+tensorflow_gpu+Anaconda
  13. APP支付支付签名验证失败
  14. IntelliJ IDEA-ssm使用IDEA导入一个Maven风格的ssm项目
  15. 满满的骚操作,通用流行框架大全
  16. 制作二十四进制的时钟特效(JavaScript)
  17. Golang: 让你的零值更有用
  18. 2020秋季《大数据与物联网》期末答案参考
  19. Python(贪心算法)问题 C: 活动选择_学校在最近几天有n个活动,这些活动都需要使用学校的大礼堂,在同一时间,礼堂只能被一个活动使用。
  20. 从零编写60%+胜率的短线择时信号!零基础python量化投资代码详解【邢不行】

热门文章

  1. 快速在MyEclipse中打开jsp类型的文件
  2. 去掉iPhone、iPad的默认按钮样式
  3. 利用if...else if....else循环语句编程
  4. WebStorm介绍
  5. Python 参数解析(getopt模块)
  6. C 标准库中输出到字符串、到文件的相关函数
  7. 每天一道剑指offer-连续子数组的最大和
  8. canopy java_在Windows上安装带有Enthought Canopy的Theano
  9. string 转 byte_计算机毕业设计中java实现在线预览poi实现word、excel、ppt转html
  10. react 点击使父元素消失_在 React 组件中使用 Refs 指南