您的位置:首页 > 其它

ogre 创建地形

2015-07-23 14:06 357 查看
ogre 创建地形
先来看代码:
void TutorialApplication::createScene(void)
{
// Create your scene here :)
// 	设置相机的位置,因为地形一般都比较大,所以设置得远一点
mCamera->setPosition(Ogre::Vector3(1683,50,2116));
mCamera->lookAt(Ogre::Vector3(1963,50,1660));
mCamera->setNearClipDistance(0.1);

bool infiniteClip = mRoot->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_INFINITE_FAR_PLANE);

if (infiniteClip)
{
// 如果显卡系统(即渲染系统)支持无穷远的剪切,那么设置可以看到无穷远的地方
mCamera->setFarClipDistance(0);
}
else
{
mCamera->setFarClipDistance(50000);
}

// 设置环境光
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.2,0.2,0.2));
Ogre::Vector3 lightdir(0.55,-0.3,0.75);
lightdir.normalise();

// 创建一个有向光
Ogre::Light* light = mSceneMgr->createLight("TestLight");
light->setType(Ogre::Light::LT_DIRECTIONAL);
light->setDirection(lightdir);
light->setDiffuseColour(Ogre::ColourValue::White);
light->setSpecularColour(Ogre::ColourValue(0.4,0.4,0.4));

// 创建全局的地形配置信息
mTerrainGlobals = OGRE_NEW Ogre::TerrainGlobalOptions();

// 创建TerrainGroup对象,以管理地形
// 第一参数为场景管理器,第二个参数为地形的的排布,第三个参数为地形的大小,第四个参数为整个地块的大小
mTerrainGroup = OGRE_NEW Ogre::TerrainGroup(
mSceneMgr,
Ogre::Terrain::ALIGN_X_Z,
513,
12000.0);
mTerrainGroup->setFilenameConvention(Ogre::String("terrain"),Ogre::String("dat"));
mTerrainGroup->setOrigin(Ogre::Vector3::ZERO);
// 配置地形
configureTerrainDefaults(light);

// 定义地形
for (long x = 0; x <= 0; ++x)
for(long y = 0; y<=0; ++y)
{
defineTerrain(x,y);
}

// 同步载入所有的地形,这样我们一启动就可以得到所有的一切了
mTerrainGroup->loadAllTerrains(true);

// 如果只是单纯的载入地形,将所有已存在的地形调用initBlendMaps
if (mTerrainsImported)
{
Ogre::TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();

while (ti.hasMoreElements())
{
Ogre::Terrain* t = ti.getNext()->instance;
initBlendMaps(t);
}
}
// 清理临时资源
mTerrainGroup->freeTemporaryResources();
}

void TutorialApplication::createFrameListener()
{
BaseApplication::createFrameListener();
mInfoLabel = mTrayMgr->createLabel(OgreBites::TL_TOP,"TerrainInfo","",350);
}

void TutorialApplication::destroyScene()
{
OGRE_DELETE mTerrainGroup;
OGRE_DELETE mTerrainGlobals;
}

bool TutorialApplication::frameRenderingQueued(const Ogre::FrameEvent& fe)
{
if(mTerrainGroup->isDerivedDataUpdateInProgress())
{
mTrayMgr->moveWidgetToTray(mInfoLabel,OgreBites::TL_TOP,0);
mInfoLabel->show();

if (mTerrainsImported)
{
mInfoLabel->setCaption("Building terrain ...");
}
else
{
mInfoLabel->setCaption("Updating terrain ...");
}
}
else
{
mTrayMgr->removeWidgetFromTray(mInfoLabel);
mInfoLabel->hide();
if (mTerrainsImported)
{
mTerrainGroup->saveAllTerrains(true);
mTerrainsImported = false;
}
}

bool ret = BaseApplication::frameRenderingQueued(fe);
return ret;
}

void TutorialApplication::defineTerrain(long x,long y)
{
// 说明生成地图的名字
Ogre::String filename = mTerrainGroup->generateFilename(x,y);
bool exists = Ogre::ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(),filename);
if (exists)
{
// 本名字的地形已经存在了,直接加入
mTerrainGroup->defineTerrain(x,y);
}
else
{
// 本地形还不存在,需要载入进来
Ogre::Image img;
getTerrainImage(x%2!=2,y%2!=0,img);
mTerrainGroup->defineTerrain(x,y,&img);
mTerrainsImported = true;
}

}

void TutorialApplication::getTerrainImage(bool flipX,bool flipY,Ogre::Image& img)
{
// 载入图片并做适当的裁切
img.load("terrain.png",Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
if (flipX)
{
img.flipAroundY();
}

if(flipY)
{
img.flipAroundX();
}
}
//混合地形
void TutorialApplication::initBlendMaps(Ogre::Terrain* terrain)
{
Ogre::Real minHeight0 = 70;
Ogre::Real fadeDist0 = 40;
Ogre::Real minHeight1 = 70;
Ogre::Real fadeDist1 = 15;

Ogre::TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1);
Ogre::TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2);

float* pBlend0 = blendMap0->getBlendPointer();
float* pBlend1 = blendMap1->getBlendPointer();

for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize();++y)
for(Ogre::uint16 x=0; x< terrain->getLayerBlendMapSize(); ++x)
{
Ogre::Real tx,ty;
blendMap0->convertImageToTerrainSpace(x,y,&tx,&ty);
Ogre::Real height = terrain->getHeightAtTerrainPosition(tx,ty);
Ogre::Real val = (height - minHeight0) / fadeDist0;
val = Ogre::Math::Clamp(val,(Ogre::Real)0,(Ogre::Real)1);
*pBlend0 ++ = val;

val = (height - minHeight1) / fadeDist1;
val = Ogre::Math::Clamp(val,(Ogre::Real)0,(Ogre::Real)1);
*pBlend1++ = val;
}

blendMap0->dirty();
blendMap1->dirty();
blendMap0->update();
blendMap1->update();
}
void TutorialApplication::configureTerrainDefaults(Ogre::Light* light)
{
// 配置MaxPixelError为8
// 本配置决定了地形的精度,这个值越小则地形越精细,但需要更大的开销
mTerrainGlobals->setMaxPixelError(8);
// 配置CompositeMapDistance为3000
// 本配置决定了多远的距离内,地形才会被渲染出来
mTerrainGlobals->setCompositeMapDistance(3000);

// 设置其环境光和漫反射光,这样在光照下才能够反衬出自身的纹理
mTerrainGlobals->setLightMapDirection(light->getDerivedDirection());
mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());
mTerrainGlobals->setCompositeMapDiffuse(light->getDiffuseColour());

// 当我们载入地形时,其默认的配置如下:
Ogre::Terrain::ImportData& importData = mTerrainGroup->getDefaultImportSettings();
importData.terrainSize = 513;
importData.worldSize = 12000.0;
importData.inputScale = 600;
importData.minBatchSize = 33;
importData.maxBatchSize = 65;
// 纹理信息
importData.layerList.resize(3);

importData.layerList[0].worldSize = 100;
importData.layerList[0].textureNames.push_back(
"dirt_grayrock_diffusespecular.dds");
importData.layerList[0].textureNames.push_back(
"dirt_grayrocky_normalheight.dds");

importData.layerList[1].worldSize = 30;
importData.layerList[1].textureNames.push_back(
"grass_green-01_diffusespecular.dds");
importData.layerList[1].textureNames.push_back(
"grass_green-01_normalheight.dds");

importData.layerList[2].worldSize = 200;
importData.layerList[2].textureNames.push_back(
"growth_weirdfungus-03_diffusespecular.dds");
importData.layerList[2].textureNames.push_back(
"growth_weirdfungus-03_normalheight.dds");
}


class TutorialApplication : public BaseApplication
{
public:
TutorialApplication(void);
virtual ~TutorialApplication(void);

protected:
virtual void createScene(void);
virtual void createFrameListener();
virtual void destroyScene();
virtual bool frameRenderingQueued(const Ogre::FrameEvent& fe);
private:
void defineTerrain(long x,long y);
void initBlendMaps(Ogre::Terrain* terrain);
void configureTerrainDefaults(Ogre::Light* light);
static void getTerrainImage(bool flipX,bool flipY,Ogre::Image& img);
bool mTerrainsImported;
Ogre::TerrainGroup* mTerrainGroup;
Ogre::TerrainGlobalOptions* mTerrainGlobals;
OgreBites::Label* mInfoLabel;

};
没太搞懂的是,为什么要弄个terrain的类型出来。它和entity不一样是mesh么。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: