[OGRE]基础教程来四发:来谈一谈地形系统

[OGRE]基础教程来四发:来谈一谈地形系统

标签: OGRE
  2238人阅读  评论(1)  收藏  举报
  分类:

英文链接如下:http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Basic+Tutorial+3&structure=Tutorials


直接贴上能够直接运行的代码,具体内容看注释即可。

首先是头文件BasicTutorial3.h:

[cpp]  view plain  copy
  1. #include <Terrain/OgreTerrain.h>  
  2. #include <Terrain/OgreTerrainGroup.h>  
  3. #include "BaseApplication.h"  
  4.   
  5. class BasicTutorial3 :public BaseApplication  
  6. {  
  7. private:  
  8.     Ogre::TerrainGlobalOptions* mTerrainGlobals;  
  9.     Ogre::TerrainGroup* mTerrainGroup;  
  10.     OgreBites::Label* mInfoLabel;  
  11.     bool mTerrainsImported;  
  12.   
  13.     void defineTerrain(long x, long y);  
  14.     void initBlendMaps(Ogre::Terrain* terrain);  
  15.     void configureTerrainDefaults(Ogre::Light* light);  
  16. public:  
  17.     BasicTutorial3(void);  
  18.     virtual ~BasicTutorial3(void);  
  19.   
  20. protected:  
  21.     virtual void createScene(void);  
  22.     virtual void createFrameListener(void);  
  23.     virtual void destroyScene(void);  
  24.     virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);  
  25. };  

然后是源文件BasicTutorial3.cpp:

[cpp]  view plain  copy
  1. #include "BasicTutorial3.h"  
  2.   
  3. //-------------------------------------------------------------------------------------  
  4. BasicTutorial3::BasicTutorial3(void)  
  5. {  
  6. }  
  7. //-------------------------------------------------------------------------------------  
  8. BasicTutorial3::~BasicTutorial3(void)  
  9. {  
  10. }  
  11. //-------------------------------------------------------------------------------------  
  12. void BasicTutorial3::destroyScene(void)  
  13. {  
  14.     OGRE_DELETE mTerrainGroup;  
  15.     OGRE_DELETE mTerrainGlobals;  
  16. }  
  17. //-------------------------------------------------------------------------------------  
  18. void getTerrainImage(bool flipX, bool flipY, Ogre::Image& img)  
  19. {  
  20.     img.load("terrain.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);  
  21.     if (flipX)  
  22.         img.flipAroundY();  
  23.     if (flipY)  
  24.         img.flipAroundX();  
  25. }  
  26. //-------------------------------------------------------------------------------------  
  27. void BasicTutorial3::defineTerrain(long x, long y)  
  28. {  
  29.     Ogre::String filename = mTerrainGroup->generateFilename(x, y);  
  30.     if (Ogre::ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename))  
  31.     {  
  32.         mTerrainGroup->defineTerrain(x, y);  
  33.     }  
  34.     else  
  35.     {  
  36.         Ogre::Image img;  
  37.         getTerrainImage(x % 2 != 0, y % 2 != 0, img);  
  38.         mTerrainGroup->defineTerrain(x, y, &img);  
  39.         mTerrainsImported = true;  
  40.     }  
  41.   
  42. }  
  43. //-------------------------------------------------------------------------------------  
  44. void BasicTutorial3::initBlendMaps(Ogre::Terrain* terrain)  
  45. {  
  46.     Ogre::TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1);  
  47.     Ogre::TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2);  
  48.     Ogre::Real minHeight0 = 70;  
  49.     Ogre::Real fadeDist0 = 40;  
  50.     Ogre::Real minHeight1 = 70;  
  51.     Ogre::Real fadeDist1 = 15;  
  52.     float* pBlend0 = blendMap0->getBlendPointer();  
  53.     float* pBlend1 = blendMap1->getBlendPointer();  
  54.     for (Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y)  
  55.     {  
  56.         for (Ogre::uint16 x = 0; x < terrain->getLayerBlendMapSize(); ++x)  
  57.         {  
  58.             Ogre::Real tx, ty;  
  59.   
  60.             blendMap0->convertImageToTerrainSpace(x, y, &tx, &ty);  
  61.             Ogre::Real height = terrain->getHeightAtTerrainPosition(tx, ty);  
  62.             Ogre::Real val = (height - minHeight0) / fadeDist0;  
  63.             val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1);  
  64.             *pBlend0++ = val;  
  65.   
  66.             val = (height - minHeight1) / fadeDist1;  
  67.             val = Ogre::Math::Clamp(val, (Ogre::Real)0, (Ogre::Real)1);  
  68.             *pBlend1++ = val;  
  69.         }  
  70.     }  
  71.     blendMap0->dirty();  
  72.     blendMap1->dirty();  
  73.     blendMap0->update();  
  74.     blendMap1->update();  
  75. }  
  76. //-------------------------------------------------------------------------------------  
  77. void BasicTutorial3::configureTerrainDefaults(Ogre::Light* light)  
  78. {  
  79.     //决定地图将有多精确,数值越小越精确  
  80.     mTerrainGlobals->setMaxPixelError(8);  
  81.     mTerrainGlobals->setCompositeMapDistance(3000);  
  82.     //灯光贴图  
  83.     mTerrainGlobals->setLightMapDirection(light->getDerivedDirection());  
  84.     mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());  
  85.     mTerrainGlobals->setCompositeMapDiffuse(light->getDiffuseColour());  
  86.     // 设置默认的导入选项  
  87.     Ogre::Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();  
  88.     defaultimp.terrainSize = 513;  
  89.     defaultimp.worldSize = 12000.0f;  
  90.     defaultimp.inputScale = 600; // due terrain.png is 8 bpp  
  91.     defaultimp.minBatchSize = 33;  
  92.     defaultimp.maxBatchSize = 65;  
  93.     // 纹理贴图  
  94.     defaultimp.layerList.resize(3);  
  95.     defaultimp.layerList[0].worldSize = 100;  
  96.     defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");  
  97.     defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");  
  98.     defaultimp.layerList[1].worldSize = 30;  
  99.     defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");  
  100.     defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");  
  101.     defaultimp.layerList[2].worldSize = 200;  
  102.     defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");  
  103.     defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");  
  104.   
  105. }  
  106. //-------------------------------------------------------------------------------------  
  107. void BasicTutorial3::createScene(void)  
  108. {  
  109.     //设置摄像机  
  110.     mCamera->setPosition(Ogre::Vector3(1683, 50, 2116));  
  111.     mCamera->lookAt(Ogre::Vector3(1963, 50, 1660));  
  112.     mCamera->setNearClipDistance(0.1);  
  113.     mCamera->setFarClipDistance(50000);  
  114.     if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_INFINITE_FAR_PLANE))  
  115.     {  
  116.         mCamera->setFarClipDistance(0);   // 如果有可能尽量设置为无穷大  
  117.     }  
  118.   
  119.     //设置灯光  
  120.     Ogre::Vector3 lightdir(0.55, -0.3, 0.75);  
  121.     lightdir.normalise();  
  122.     Ogre::Light* light = mSceneMgr->createLight("tstLight");  
  123.     light->setType(Ogre::Light::LT_DIRECTIONAL);  
  124.     light->setDirection(lightdir);  
  125.     light->setDiffuseColour(Ogre::ColourValue::White);  
  126.     light->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));  
  127.     mSceneMgr->setAmbientLight(Ogre::ColourValue(0.2, 0.2, 0.2));  
  128.   
  129.     //存储所有地形的默认选项  
  130.     mTerrainGlobals = OGRE_NEW Ogre::TerrainGlobalOptions();  
  131.     //地形管理(不做分页)  
  132.     mTerrainGroup = OGRE_NEW Ogre::TerrainGroup(mSceneMgr, Ogre::Terrain::ALIGN_X_Z, 513, 12000.0f);  
  133.     mTerrainGroup->setFilenameConvention(Ogre::String("BasicTutorial3Terrain"), Ogre::String("dat"));  
  134.     mTerrainGroup->setOrigin(Ogre::Vector3::ZERO);  
  135.     //设置地形  
  136.     configureTerrainDefaults(light);  
  137.     //自定义地形  
  138.     for (long x = 0; x <= 0; ++x)  
  139.         for (long y = 0; y <= 0; ++y)  
  140.             defineTerrain(x, y);  
  141.   
  142.     //在我们开始的时候可以加载只要我们想要任何东西  
  143.     mTerrainGroup->loadAllTerrains(true);  
  144.   
  145.     if (mTerrainsImported)  
  146.     {  
  147.         Ogre::TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();  
  148.         while(ti.hasMoreElements())  
  149.         {  
  150.             Ogre::Terrain* t = ti.getNext()->instance;  
  151.             initBlendMaps(t);  
  152.         }  
  153.     }  
  154.     //清空临时资源  
  155.     mTerrainGroup->freeTemporaryResources();  
  156. }  
  157. //-------------------------------------------------------------------------------------  
  158. void BasicTutorial3::createFrameListener(void)  
  159. {  
  160.     BaseApplication::createFrameListener();  
  161.     mInfoLabel = mTrayMgr->createLabel(OgreBites::TL_TOP, "TInfo""", 350);  
  162. }  
  163. //-------------------------------------------------------------------------------------  
  164. bool BasicTutorial3::frameRenderingQueued(const Ogre::FrameEvent& evt)  
  165. {   
  166.     bool ret = BaseApplication::frameRenderingQueued(evt);  
  167.   
  168.     if (mTerrainGroup->isDerivedDataUpdateInProgress())  
  169.     {  
  170.         mTrayMgr->moveWidgetToTray(mInfoLabel, OgreBites::TL_TOP, 0);  
  171.         mInfoLabel->show();  
  172.         if (mTerrainsImported)  
  173.         {  
  174.             mInfoLabel->setCaption("Building terrain, please wait...");  
  175.         }  
  176.         else  
  177.         {  
  178.             mInfoLabel->setCaption("Updating textures, patience...");  
  179.         }  
  180.     }  
  181.     else  
  182.     {  
  183.         mTrayMgr->removeWidgetFromTray(mInfoLabel);  
  184.         mInfoLabel->hide();  
  185.         if (mTerrainsImported)  
  186.         {  
  187.             mTerrainGroup->saveAllTerrains(true);  
  188.             mTerrainsImported = false;  
  189.         }  
  190.     }  
  191.   
  192.     return ret;  
  193. }  
  194.   
  195.   
  196.   
  197.   
  198.   
  199. #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32  
  200. #define WIN32_LEAN_AND_MEAN  
  201. #include "windows.h"  
  202. #endif  
  203.   
  204. #ifdef __cplusplus  
  205. extern "C" {  
  206. #endif  
  207.   
  208. #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32  
  209.     INT WINAPI WinMain( HINSTANCE hInst, HINSTANCELPSTR strCmdLine, INT )  
  210. #else  
  211.     int main(int argc, char *argv[])  
  212. #endif  
  213.     {  
  214.         // Create application object  
  215.         BasicTutorial3 app;  
  216.   
  217.         try {  
  218.             app.go();  
  219.         } catch( Ogre::Exception& e ) {  
  220. #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32  
  221.             MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);  
  222. #else  
  223.             std::cerr << "An exception has occured: " <<  
  224.                 e.getFullDescription().c_str() << std::endl;  
  225. #endif  
  226.         }  
  227.   
  228.         return 0;  
  229.     }  
  230.   
  231. #ifdef __cplusplus  
  232. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值