您的位置:首页 > 其它

Ogre 1.7中的地形教程

2010-09-07 10:56 309 查看
地形创建的工作步骤:

1.创建地形全局配置

2.创建地形分组

3.创建默认的地形分块属性

4.创建地形分块

--------------------------------------------------------------------------------

第一步

首先,在Ogre1.7中,地形是由一块一块的地形组成的,他们每快地形都有共同的属性,所以在创建地形之前我们必须指定地形块的全局配置。

代码:

mTerrainGlobals = new Ogre::TerrainGlobalOptions();
mTerrainGlobals->setMaxPixelError(8);
mTerrainGlobals->setCompositeMapDistance(3000);
mTerrainGlobals->setLightMapDirection(l->getDerivedDirection());
mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());
mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour());
mTerrainGlobals->setLightMapSize(TERRAINWORLDSIZE);

代码说明:

首先实例化一个TerrainGlobalOptions的全局对象

然后我们看几个主要属性

mTerrainGlobals->setLightMapDirection(l->getDerivedDirection());

//设置光线的方向,所有地形块均采用同一个方向的光
mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());

//设置环境光
mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour());

//设置漫反射光
mTerrainGlobals->setLightMapSize(TERRAINWORLDSIZE);

//设置光线图的大小,这个数字越小,地图的阴影将越粗糙

其余的几个属性可保留此默认

--------------------------------------------------------------------------------

第二步

我们将要创建地形分组对象,该对象用于创建以及管理地形块。

代码:

mTerrainGroup = new Ogre::TerrainGroup(mSceneMgr, Ogre::Terrain::ALIGN_X_Z, TERRAINWORLDSIZE, TERRAINWORLDSIZE);
mTerrainGroup->setOrigin(Ogre::Vector3((float)TERRAINWORLDSIZE / 2.0f,0,(float)TERRAINWORLDSIZE / 2.0f));

这段代码比较简单

首先是实例化一个TerrainGroup对象

并为他指定场管理器、地形的平铺方向、地形的大小

平铺方向一般采用ALIGN_X_Z,也就是采用Y作为高度

然后第二句设置了该地形组的起始位置,在以后创建的地形块中均采用此位置作为相对位置

--------------------------------------------------------------------------------

第三步

有了地形分组之后,我们就可以通过地形分组创建地形块了,但是每一个地形块都有很多属性,我们可以在创建地形块的同时设置那些属性,但是这样极为不方便。所以,我们可以先设置默认的地形块属性,那么创建地形块的时候就可以一个方法搞定了

代码:

////设置地形默认属性
Ogre::Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
defaultimp.terrainSize = TERRAINWORLDSIZE;
defaultimp.worldSize = TERRAINWORLDSIZE;
defaultimp.inputScale = 1;
defaultimp.minBatchSize = 33;
defaultimp.maxBatchSize = 65;
//设置纹理
defaultimp.layerList.resize(1);
defaultimp.layerList[0].worldSize = BLENDMAPWORLDSIZE;
defaultimp.layerList[0].textureNames.push_back("DefaultTexture.jpg");
defaultimp.layerList[0].textureNames.push_back(DEFAULTNORMALMAP);

这些属性都比较容易理解,设置地形大小,设置每个titles大小,设置bath相关,以及设置默认的纹理。

--------------------------------------------------------------------------------

第四步

以上三步工作做好了之后,我们就可以很方便的创建地形块了

mTerrainGroup->defineTerrain(x, y,0.0f);

加上这句代码,你将会在你的场景中看到一块地形了

defineTerrain方法首先要指定该块地形在地形分组中的索引位置,然后第三个参数必须指定高度数据,这里我设置为0.0f,那么将是出现一个平面地形。

--------------------------------------------------------------------------------

纹理混合

地形创建好之后,接下来再来给大家讲一下纹理混合的问题

Ogre1.7的地形纹理默认支持8层纹理混合,如果想更改,可通过地形的全局配置设置,混合越多越慢。

纹理混合包括两大步骤

1.设置纹理以及法线图

2.设置纹理混合的系数

--------------------------------------------------------------------------------

首先先获取一个Terrain对象,可通过TerrainGroup的GetTerrainAt方法获取

那么我们可以对该Terrain对象进行纹理控制

比如新增一层纹理

代码:

Ogre::StringVector vTextures;
vTextures.push_back(textureName);
Ogre::String fName = textureName.substr(0,textureName.find_first_of("."));
vTextures.push_back(fName + _S("_normalheight.dds"));
terrain->addLayer(k,BLENDMAPWORLDSIZE,&vTextures);

这段代码非常简单,知道stl估计都看得懂。vTextures的第一个元素代表纹理图本身,第二个元素代表法线图。法线可以为纹理增加凹凸不平的效果。

那么通过以上方式,增加了N层纹理之后,你可能发现“为什么只显示第一层纹理啊?其他新增的问题怎么不显示了?”,那是因为你还没有为他指定混合系数

一张纹理,贴在地形上,你必须指定他的纹理可见度。比如我的一个地形,我需要在左边显示A纹理,右边显示B纹理,那也就是说A纹理的左边设置为可见,B纹理的右边设置为可见。那如何做到这一点呢?

首先看一小段代码

Ogre::TerrainLayerBlendMap* blendMap = terrain->getLayerBlendMap(l);
float* data = blendMap->getBlendPointer();
for (int h = 0;h<100;h++)
{
for (int 0;w<100;w++)
{
data[dataIndex] = 0.0f;
}
}
blendMap->dirty();
blendMap->update();

看开始两句,获取了Terrain的第X层纹理,然后获取了纹理系数data,然后我们把高100宽100的位置的混合系数设置为0,即不可见,混合系数取值为0~1之间,系数越大纹理越清晰,故0就是一点都不可见。

改变纹理系数之后,再更新了一下纹理。

当这段代码执行以后,你会发现你的地形纹理上出现了一个100X100的白色正方形,明白了吧,纹理系数就是这么简单,多层纹理的时候必须为每层纹理设置系数。

今天的文章先简单写到这里,如果还有不明白的请QQ81786254或者Email:is-dragon@hotmail.com询问。

文章任何信息均由本博原创,转载请注明出处!

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dragon2/archive/2010/09/04/5862925.aspx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: