分类:
版权声明:本文为博主原创文章,未经博主允许不得转载。
英文链接如下:http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Basic+Tutorial+3&structure=Tutorials
直接贴上能够直接运行的代码,具体内容看注释即可。
首先是头文件BasicTutorial3.h:
- #include <Terrain/OgreTerrain.h>
- #include <Terrain/OgreTerrainGroup.h>
- #include "BaseApplication.h"
- class BasicTutorial3 :public BaseApplication
- {
- private:
- Ogre::TerrainGlobalOptions* mTerrainGlobals;
- Ogre::TerrainGroup* mTerrainGroup;
- OgreBites::Label* mInfoLabel;
- bool mTerrainsImported;
- void defineTerrain(long x, long y);
- void initBlendMaps(Ogre::Terrain* terrain);
- void configureTerrainDefaults(Ogre::Light* light);
- public:
- BasicTutorial3(void);
- virtual ~BasicTutorial3(void);
- protected:
- virtual void createScene(void);
- virtual void createFrameListener(void);
- virtual void destroyScene(void);
- virtual bool frameRenderingQueued(const Ogre::FrameEvent& evt);
- };
然后是源文件BasicTutorial3.cpp:
- #include "BasicTutorial3.h"
- //-------------------------------------------------------------------------------------
- BasicTutorial3::BasicTutorial3(void)
- {
- }
- //-------------------------------------------------------------------------------------
- BasicTutorial3::~BasicTutorial3(void)
- {
- }
- //-------------------------------------------------------------------------------------
- void BasicTutorial3::destroyScene(void)
- {
- OGRE_DELETE mTerrainGroup;
- OGRE_DELETE mTerrainGlobals;
- }
- //-------------------------------------------------------------------------------------
- void 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 BasicTutorial3::defineTerrain(long x, long y)
- {
- Ogre::String filename = mTerrainGroup->generateFilename(x, y);
- if (Ogre::ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(), filename))
- {
- mTerrainGroup->defineTerrain(x, y);
- }
- else
- {
- Ogre::Image img;
- getTerrainImage(x % 2 != 0, y % 2 != 0, img);
- mTerrainGroup->defineTerrain(x, y, &img);
- mTerrainsImported = true;
- }
- }
- //-------------------------------------------------------------------------------------
- void BasicTutorial3::initBlendMaps(Ogre::Terrain* terrain)
- {
- Ogre::TerrainLayerBlendMap* blendMap0 = terrain->getLayerBlendMap(1);
- Ogre::TerrainLayerBlendMap* blendMap1 = terrain->getLayerBlendMap(2);
- Ogre::Real minHeight0 = 70;
- Ogre::Real fadeDist0 = 40;
- Ogre::Real minHeight1 = 70;
- Ogre::Real fadeDist1 = 15;
- 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 BasicTutorial3::configureTerrainDefaults(Ogre::Light* light)
- {
- //决定地图将有多精确,数值越小越精确
- mTerrainGlobals->setMaxPixelError(8);
- mTerrainGlobals->setCompositeMapDistance(3000);
- //灯光贴图
- mTerrainGlobals->setLightMapDirection(light->getDerivedDirection());
- mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());
- mTerrainGlobals->setCompositeMapDiffuse(light->getDiffuseColour());
- // 设置默认的导入选项
- Ogre::Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();
- defaultimp.terrainSize = 513;
- defaultimp.worldSize = 12000.0f;
- defaultimp.inputScale = 600; // due terrain.png is 8 bpp
- defaultimp.minBatchSize = 33;
- defaultimp.maxBatchSize = 65;
- // 纹理贴图
- defaultimp.layerList.resize(3);
- 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 = 200;
- defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");
- defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");
- }
- //-------------------------------------------------------------------------------------
- void BasicTutorial3::createScene(void)
- {
- //设置摄像机
- mCamera->setPosition(Ogre::Vector3(1683, 50, 2116));
- mCamera->lookAt(Ogre::Vector3(1963, 50, 1660));
- mCamera->setNearClipDistance(0.1);
- mCamera->setFarClipDistance(50000);
- if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(Ogre::RSC_INFINITE_FAR_PLANE))
- {
- mCamera->setFarClipDistance(0); // 如果有可能尽量设置为无穷大
- }
- //设置灯光
- Ogre::Vector3 lightdir(0.55, -0.3, 0.75);
- lightdir.normalise();
- Ogre::Light* light = mSceneMgr->createLight("tstLight");
- light->setType(Ogre::Light::LT_DIRECTIONAL);
- light->setDirection(lightdir);
- light->setDiffuseColour(Ogre::ColourValue::White);
- light->setSpecularColour(Ogre::ColourValue(0.4, 0.4, 0.4));
- mSceneMgr->setAmbientLight(Ogre::ColourValue(0.2, 0.2, 0.2));
- //存储所有地形的默认选项
- mTerrainGlobals = OGRE_NEW Ogre::TerrainGlobalOptions();
- //地形管理(不做分页)
- mTerrainGroup = OGRE_NEW Ogre::TerrainGroup(mSceneMgr, Ogre::Terrain::ALIGN_X_Z, 513, 12000.0f);
- mTerrainGroup->setFilenameConvention(Ogre::String("BasicTutorial3Terrain"), 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);
- if (mTerrainsImported)
- {
- Ogre::TerrainGroup::TerrainIterator ti = mTerrainGroup->getTerrainIterator();
- while(ti.hasMoreElements())
- {
- Ogre::Terrain* t = ti.getNext()->instance;
- initBlendMaps(t);
- }
- }
- //清空临时资源
- mTerrainGroup->freeTemporaryResources();
- }
- //-------------------------------------------------------------------------------------
- void BasicTutorial3::createFrameListener(void)
- {
- BaseApplication::createFrameListener();
- mInfoLabel = mTrayMgr->createLabel(OgreBites::TL_TOP, "TInfo", "", 350);
- }
- //-------------------------------------------------------------------------------------
- bool BasicTutorial3::frameRenderingQueued(const Ogre::FrameEvent& evt)
- {
- bool ret = BaseApplication::frameRenderingQueued(evt);
- if (mTerrainGroup->isDerivedDataUpdateInProgress())
- {
- mTrayMgr->moveWidgetToTray(mInfoLabel, OgreBites::TL_TOP, 0);
- mInfoLabel->show();
- if (mTerrainsImported)
- {
- mInfoLabel->setCaption("Building terrain, please wait...");
- }
- else
- {
- mInfoLabel->setCaption("Updating textures, patience...");
- }
- }
- else
- {
- mTrayMgr->removeWidgetFromTray(mInfoLabel);
- mInfoLabel->hide();
- if (mTerrainsImported)
- {
- mTerrainGroup->saveAllTerrains(true);
- mTerrainsImported = false;
- }
- }
- return ret;
- }
- #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
- #define WIN32_LEAN_AND_MEAN
- #include "windows.h"
- #endif
- #ifdef __cplusplus
- extern "C" {
- #endif
- #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
- #else
- int main(int argc, char *argv[])
- #endif
- {
- // Create application object
- BasicTutorial3 app;
- try {
- app.go();
- } catch( Ogre::Exception& e ) {
- #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
- MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
- #else
- std::cerr << "An exception has occured: " <<
- e.getFullDescription().c_str() << std::endl;
- #endif
- }
- return 0;
- }
- #ifdef __cplusplus
- }