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么。
相关文章推荐
- 关系数据库设计范式介绍
- ConcurrentHashMap vs Collections.synchronizedMap()不同
- Labview实现幅度信号调制(AM)
- Canvas scale- 缩放
- 【解决】failed to complete gradle execution问题
- 黑马程序员-死锁
- 使用maven构建spring项目
- texifield
- PAT B 锤子剪刀布
- C++模板特化
- ios经验总结
- POJ熄灯问题
- JavaScript权威指南_135_第15章_脚本化文档_15.8-文档和元素的几何形状和滚动-判定元素在某点
- 获取PDF页数
- Sublime Text 3 (含:配置 C# 编译环境)
- What Is Your Grade?(1084)
- 大型文件去重
- C中malloc函数用法
- 利用反射,分析类
- 高德GCJ-02坐标转换