ogre1.8自己写的建立地形源码(注释,可直接使用)

提供了一段使用Ogre1.8引擎实现地形构建的完整源码,包括监听器类、应用类和main函数,详细解释了如何创建地形全局配置、地形分组、配置地图块参数、创建地形分块以及地形纹理图层混合合成等关键步骤。此外,还介绍了如何加载资源、启动应用以及保存和导入地形数据。代码经过优化,易于直接使用。
 

ogre1.8自己写的建立地形源码(注释,可直接使用)

分类: Ogre   901人阅读  评论(1)  收藏  举报

为了便于直接使用,所有代码都放在一个cpp文件中了,如下:

[cpp]  view plain copy
  1. /*这个cpp文件包括监听器类,Application类和main函数*/  
  2. #define TERRAIN_PAGE_MIN_X 0  
  3. #define TERRAIN_PAGE_MIN_Y 0  
  4. #define TERRAIN_PAGE_MAX_X 0  
  5. #define TERRAIN_PAGE_MAX_Y 0  
  6.   
  7. #define TERRAIN_FILE_PREFIX String("ygTerrain") //保存的地形文件名  
  8. #define TERRAIN_FILE_SUFFIX String("dat")  //保存的地形文件的扩展名  
  9. #define TERRAIN_WORLD_SIZE 12000.0f  
  10. #define TERRAIN_SIZE 513  
  11.   
  12. #include <Ogre.h>  
  13. #include <OIS/OIS.h>  
  14. #include <iostream>  
  15. #include <OgreTerrain.h>  
  16. #include <OgreTerrainLayerBlendMap.h>  
  17. #include <OgreTerrainGroup.h>  
  18.   
  19. using namespace Ogre;  
  20.   
  21. class MyFrameListener : public Ogre::FrameListener  //监听器类  
  22. {  
  23. private:  
  24.     OIS::InputManager *m_pInputManage;  
  25.     OIS::Keyboard *m_pKeyBoard;  
  26.     OIS::Mouse *m_pMouse;  
  27.     Ogre::Camera *m_pCamera;  
  28.     Ogre::Viewport *m_pViewport;  
  29.     Ogre::Timer m_Time;  
  30.   
  31.     bool m_bWirmline;  
  32.   
  33.     float m_fMovementSpeed;  
  34.   
  35. public:  
  36.     MyFrameListener( Ogre::RenderWindow *pWin, Ogre::Camera *pCamera, Ogre::Viewport *pViewport )  
  37.     {  
  38.         m_pCamera = pCamera;  
  39.         m_fMovementSpeed = 10;  
  40.   
  41.         m_Time.reset();  
  42.   
  43.         m_pViewport = pViewport;  
  44.         m_bWirmline = true;  
  45.   
  46.         OIS::ParamList Params;  
  47.         size_t WindowHandle = 0;  
  48.         std::ostringstream WinHandleString;  
  49.         pWin->getCustomAttribute( "WINDOW", &WindowHandle );  
  50.         WinHandleString<<WindowHandle;  
  51.   
  52.         Params.insert( std::make_pair( "WINDOW", WinHandleString.str() ) );  
  53.   
  54.         m_pInputManage = OIS::InputManager::createInputSystem( Params );  
  55.   
  56.         m_pKeyBoard = static_cast<OIS::Keyboard*>( m_pInputManage->createInputObject( OIS::OISKeyboard, false ) );  
  57.         m_pMouse = static_cast<OIS::Mouse*>( m_pInputManage->createInputObject( OIS::OISMouse, false ) );  
  58.   
  59.     }  
  60.     ~MyFrameListener()  
  61.     {  
  62.         m_pInputManage->destroyInputObject( m_pKeyBoard );  
  63.         m_pInputManage->destroyInputObject( m_pMouse );  
  64.         OIS::InputManager::destroyInputSystem( m_pInputManage );  
  65.     }  
  66.   
  67.   
  68.     bool frameStarted( const Ogre::FrameEvent& evt )  
  69.     {  
  70.         m_pKeyBoard->capture();  
  71.         bool bWalk = false;  
  72.         if( m_pKeyBoard->isKeyDown( OIS::KC_ESCAPE ) )  
  73.         {  
  74.             return false;  
  75.         }  
  76.         if( m_pKeyBoard->isKeyDown( OIS::KC_R ) && m_Time.getMilliseconds() > 250 )  
  77.         {  
  78.             m_Time.reset();  
  79.             if( m_bWirmline )  
  80.             {  
  81.                 m_pCamera->setPolygonMode( Ogre::PolygonMode::PM_WIREFRAME );  
  82.                 m_bWirmline = false;  
  83.             }  
  84.             else  
  85.             {  
  86.                 m_pCamera->setPolygonMode( Ogre::PolygonMode::PM_SOLID );  
  87.                 m_bWirmline = true;  
  88.             }  
  89.         }  
  90.         Ogre::Vector3 translate( 0, 0, 0 );  
  91.   
  92.         if( m_pKeyBoard->isKeyDown( OIS::KC_W ) )  
  93.         {  
  94.             translate += Ogre::Vector3( 0, 0, -1 );  
  95.         }  
  96.         if( m_pKeyBoard->isKeyDown( OIS::KC_S ) )  
  97.         {  
  98.             translate += Ogre::Vector3( 0, 0, 1 );  
  99.         }  
  100.         if( m_pKeyBoard->isKeyDown( OIS::KC_D ) )  
  101.         {  
  102.             translate += Ogre::Vector3( 1, 0, 0 );  
  103.         }  
  104.         if( m_pKeyBoard->isKeyDown( OIS::KC_A ) )  
  105.         {  
  106.             translate += Ogre::Vector3( -1, 0, 0 );  
  107.         }  
  108.   
  109.         m_pCamera->moveRelative( translate * m_fMovementSpeed * evt.timeSinceLastFrame * m_fMovementSpeed * 8 );  
  110.   
  111.         m_pMouse->capture();  
  112.   
  113.         float fDotX = m_pMouse->getMouseState().X.rel * evt.timeSinceLastFrame * -1;  
  114.         float fDotY = m_pMouse->getMouseState().Y.rel * evt.timeSinceLastFrame * -1;  
  115.   
  116.         m_pCamera->yaw( Ogre::Radian( fDotX ) );  
  117.         m_pCamera->pitch( Ogre::Radian( fDotY ) );  
  118.   
  119.   
  120.         return true;  
  121.     }  
  122.   
  123.     bool frameRenderingQueued( const Ogre::FrameEvent& evt )  
  124.     {  
  125.         return true;  
  126.     }  
  127.   
  128.     bool frameEnded( const Ogre::FrameEvent& evt)  
  129.     {  
  130.         return true;  
  131.     }  
  132. };  
  133.   
  134. class MyApplication  //Application类  
  135. {  
  136. private:  
  137.     Ogre::Root *m_pRoot;  
  138.     Ogre::SceneManager *mSceneMgr;  
  139.     MyFrameListener *m_pFrameListener;  
  140.     bool m_bKeepRunning;  
  141.     Ogre::TerrainGlobalOptions *mTerrainGlobals;  
  142.     Ogre::TerrainGroup *mTerrainGroup;  
  143.     bool mTerrainsImported;  
  144.   
  145. public:  
  146.     MyApplication()  
  147.         : m_pRoot( NULL ),  
  148.         mSceneMgr( NULL ),  
  149.         m_pFrameListener( NULL ),  
  150.         m_bKeepRunning( true ),  
  151.         mTerrainGlobals( NULL ),  
  152.         mTerrainsImported( false )  
  153.     {  
  154.     }  
  155.   
  156.     ~MyApplication()  
  157.     {  
  158.         if( mTerrainGlobals )  
  159.         {  
  160.             delete mTerrainGlobals;  
  161.         }  
  162.         if( mTerrainGroup )  
  163.         {  
  164.             delete mTerrainGroup;  
  165.         }  
  166.   
  167.         if( m_pRoot )  
  168.         {  
  169.             delete m_pRoot;  
  170.             m_pRoot = NULL;  
  171.         }  
  172.     }  
  173.   
  174.     void RenderOneFrame()  
  175.     {  
  176.         Ogre::WindowEventUtilities::messagePump();  
  177.         m_bKeepRunning = m_pRoot->renderOneFrame();  
  178.     }  
  179.   
  180.     bool KeepRunning()  
  181.     {  
  182.         return m_bKeepRunning;  
  183.     }  
  184.   
  185.     void LoadResources()  
  186.     {  
  187.         Ogre::ConfigFile cf;  
  188.         cf.load( "resources_d.cfg" );  
  189.         Ogre::ConfigFile::SectionIterator SecIter = cf.getSectionIterator();  
  190.         Ogre::String SectionName, DataName, TypeName;  
  191.   
  192.         while( SecIter.hasMoreElements() )  
  193.         {  
  194.             SectionName = SecIter.peekNextKey();  
  195.             Ogre::ConfigFile::SettingsMultiMap *SetMap = SecIter.getNext();  
  196.             Ogre::ConfigFile::SettingsMultiMap::iterator SetIter;  
  197.             for( SetIter = SetMap->begin(); SetIter != SetMap->end(); ++SetIter )  
  198.             {  
  199.                 TypeName = SetIter->first;  
  200.                 DataName = SetIter->second;  
  201.                 Ogre::ResourceGroupManager::getSingleton().addResourceLocation( DataName, TypeName, SectionName );  
  202.             }  
  203.         }  
  204.   
  205.         Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();  
  206.     }  
  207.   
  208.     int StartUp()  
  209.     {  
  210.         if( !m_pRoot )  
  211.         {  
  212.             m_pRoot = new Ogre::Root( "plugins_d.cfg" );  
  213.             if( !m_pRoot->showConfigDialog() )  
  214.             {  
  215.                 return -1;  
  216.             }  
  217.         }  
  218.         Ogre::RenderWindow *pWindow = m_pRoot->initialise( true );  
  219.   
  220.         mSceneMgr = m_pRoot->createSceneManager( Ogre::ST_GENERIC );  
  221.         Ogre::Camera *pCamera = mSceneMgr->createCamera( "Camera1" );  
  222.         pCamera->setPosition( 0, 1400, 100 );  
  223.         pCamera->lookAt( 0, 0, 0 );  
  224.         pCamera->setNearClipDistance( 5 );  
  225.   
  226.         Ogre::Viewport *pViewport = pWindow->addViewport( pCamera );  
  227.         pViewport->setBackgroundColour( Ogre::ColourValue( 0, 0, 0, 1 ) );  
  228.         pCamera->setAspectRatio( Ogre::Real( pViewport->getActualWidth() ) / Ogre::Real( pViewport->getActualHeight() ) );  
  229.   
  230.         LoadResources();  
  231.         CreateScene();  
  232.         m_pFrameListener = new MyFrameListener( pWindow, pCamera, pViewport );  
  233.         m_pRoot->addFrameListener( m_pFrameListener );  
  234.         return 0;  
  235.   
  236.     }  
  237.   
  238.     void CreateScene()  
  239.     {  
  240.         //建立光源  
  241.         Ogre::Light *pLight = mSceneMgr->createLight( "Light1" );  
  242.         pLight->setType( Ogre::Light::LT_DIRECTIONAL );  
  243.         pLight->setDirection( Ogre::Vector3(0.55, -0.3, 0.75) );  
  244.         pLight->setSpecularColour( Ogre::ColourValue( 0.4f, 0.4f, 0.4f ) );  
  245.         pLight->setDiffuseColour( Ogre::ColourValue::White );  
  246.         mSceneMgr->setAmbientLight( Ogre::ColourValue( 0.2f, 0.2f, 0.2f ) );  
  247.   
  248.         //设置场景背景色和建立天空盒  
  249.         Ogre::ColourValue FadeColour( 0.9, 0.9, 0.9 );  
  250.         mSceneMgr->setFog( Ogre::FOG_LINEAR, FadeColour, 0.0f, 15000.0f, 28000.0f );  
  251.         Ogre::Plane plane;  
  252.         plane.d = 1000;  
  253.         plane.normal = Ogre::Vector3::NEGATIVE_UNIT_Y;  
  254.         mSceneMgr->_setSkyPlane( true, plane, "Examples/CloudySky", 500, 20, true, 0.5f, 150, 150 );  
  255.   
  256.         //--------------------------以下内容是建立地形过程-----------------------------  
  257.         //第一步  创建地形全局配置 TerrainGlobalOptions  
  258.         //在Ogre中,地形是由一块一块的地形组成的,他们每快地形都有共同的属性,所以在创建地形之前我们必须指定地形块的全局配置。  
  259.         mTerrainGlobals = OGRE_NEW TerrainGlobalOptions();  
  260.   
  261.         //第二步  创建地形分组Ogre::TerrainGroup  
  262.         mTerrainGroup = OGRE_NEW TerrainGroup(mSceneMgr, Terrain::ALIGN_X_Z, TERRAIN_SIZE, TERRAIN_WORLD_SIZE);  
  263.         //调用saveAllTerrain函数时保存的地形文件的名字为TERRAIN_FILE_PREFIX.TERRAIN_FILE_SUFFIX  
  264.         mTerrainGroup->setFilenameConvention(TERRAIN_FILE_PREFIX, TERRAIN_FILE_SUFFIX);   
  265.         mTerrainGroup->setOrigin(/*mTerrainPos*/Ogre::Vector3::ZERO);  
  266.         /*上面这段代码比较简单 
  267.         首先是实例化一个TerrainGroup对象 
  268.         并为他指定场管理器、地形的平铺方向、地形的大小 
  269.         平铺方向一般采用ALIGN_X_Z,也就是采用Y作为高度 
  270.         然后第二句设置了该地形组的起始位置,在以后创建的地形块中均采用此位置作为相对位置*/  
  271.   
  272.         //第三步  配置地图块参数   
  273.         configureTerrainDefaults(pLight);//包括设置地形全局选项和地形分组的属性  
  274.   
  275.         //第四步  创建地形分块  
  276.         for (long x = TERRAIN_PAGE_MIN_X; x <= TERRAIN_PAGE_MAX_X; ++x)  
  277.             for (long y = TERRAIN_PAGE_MIN_Y; y <= TERRAIN_PAGE_MAX_Y; ++y)  
  278.                 defineTerrain(x, y,false); //为true则为一块平地  
  279.         mTerrainGroup->loadAllTerrains(true);  
  280.   
  281.         //第五步  地形纹理图层混合合成  
  282.         Ogre::TerrainGroup::TerrainIterator iter = mTerrainGroup->getTerrainIterator();  
  283.         while( iter.hasMoreElements() ) //迭代每个插槽中的地形块  
  284.         {  
  285.             Ogre::Terrain *t = iter.getNext()->instance;  
  286.             initBlendMaps( t );  
  287.         }  
  288.         //--------------------------以上内容是建立地形过程-----------------------------  
  289.   
  290.         //下面是保存地形,下次直接加载就行了  
  291.         if( mTerrainsImported )   
  292.         {  
  293.             //如果要反复修改TerrainGroup的数据,就不必保存地形了  
  294.             mTerrainGroup->saveAllTerrains( true );  //注意,保存的是地形顶点和TerrainGroup的数据,TerrainGlobalOption的数据不会被保存  
  295.             mTerrainsImported =false;  
  296.         }  
  297.     }  
  298.   
  299.     //配置地图块参数函数  
  300.     void configureTerrainDefaults(Light* l)  
  301.     {  
  302.         mTerrainGlobals->setMaxPixelError(8);  
  303.         mTerrainGlobals->setCompositeMapDistance(3000);//距离镜头超过3000部分使用地图合成(CompositeMap)模式表现  
  304.         mTerrainGlobals->setLightMapDirection(l->getDerivedDirection());//地图光照方向(和实时阴影生成相关)  
  305.         mTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());  
  306.         mTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour());  
  307.   
  308.         /*如果有了地形分组之后,我们就可以通过地形分组创建地形块了, 
  309.         但是每一个地形块都有很多属性,我们可以在创建地形块的同时设置那些属性, 
  310.         但是这样极为不方便。所以,我们可以先设置默认的地形块属性, 
  311.         那么创建地形块的时候就可以一个方法搞定了*/  
  312.         //设置地形默认属性    
  313.         Terrain::ImportData& defaultimp = mTerrainGroup->getDefaultImportSettings();  
  314.         defaultimp.terrainSize = TERRAIN_SIZE;//不太了解,调试中,这个值越小,地图边缘锯齿现象越严重,太小的话,运行起来程序会跑死、出错  
  315.         defaultimp.worldSize = TERRAIN_WORLD_SIZE;//假设为a,那么地图大小为 a x a  
  316.         defaultimp.inputScale = 600;//决定地图最大落差(高度),即位图中白色和黑色部分的高度差  
  317.         defaultimp.minBatchSize = 33;  
  318.         defaultimp.maxBatchSize = 65;  
  319.   
  320.         defaultimp.layerList.resize(3);  
  321.         //这里设置了3层纹理,DDS为一种高级的纹理模式,DirectDrawSurface,觉得难以理解的话  
  322.         //可以理解为一种特殊的.jpg图片模式,但是用DDS质材的话可以接收并显示地形阴影,用JPG就显示不出来,  
  323.         //而且据我调试观察发现,第一个.dds质材是用来显示纹理图形,第二个.dds才是用来接收和显示阴影的。  
  324.         defaultimp.layerList[0].worldSize = 100; //这个值关系到此贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊  
  325.         defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_diffusespecular.dds");  
  326.         defaultimp.layerList[0].textureNames.push_back("dirt_grayrocky_normalheight.dds");  
  327.         defaultimp.layerList[1].worldSize = 30;  
  328.         defaultimp.layerList[1].textureNames.push_back("grass_green-01_diffusespecular.dds");  
  329.         defaultimp.layerList[1].textureNames.push_back("grass_green-01_normalheight.dds");  
  330.         defaultimp.layerList[2].worldSize = 200;  
  331.         defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_diffusespecular.dds");  
  332.         defaultimp.layerList[2].textureNames.push_back("growth_weirdfungus-03_normalheight.dds");  
  333.   
  334.         ////下面内容用于测试,换一种地形  
  335.         //defaultimp.layerList.resize(3);    
  336.         //defaultimp.layerList[0].worldSize = 100; //这个值关系到贴图的细致程度,太大的话图片被拉伸得很大,看起来模糊  
  337.         //defaultimp.layerList[0].textureNames.push_back("BeachStones.jpg");  
  338.         //defaultimp.layerList[0].textureNames.push_back("");  
  339.         //defaultimp.layerList[1].worldSize = 30;  
  340.         //defaultimp.layerList[1].textureNames.push_back("grass_1024.jpg");  
  341.         //defaultimp.layerList[1].textureNames.push_back("");  
  342.         //defaultimp.layerList[2].worldSize = 200;  
  343.         //defaultimp.layerList[2].textureNames.push_back("terr_rock6.jpg");  
  344.         //defaultimp.layerList[2].textureNames.push_back("");  
  345.     }  
  346.     //defineTerrain(x, y, blankTerrain)定义为:  
  347.     void defineTerrain(long x, long y, bool flat = false)  
  348.     {  
  349.         /*如果想创建平坦的地形(例子中是山地地形,这里只是延伸说明,源码没有下面内容), 
  350.         但可以作为参考,帮助理解地形的建立过程,如下:*/  
  351.         if (flat) //表示平坦地图,高度为0  
  352.         {  
  353.             mTerrainGroup->defineTerrain(x, y, 0.0f);  
  354.         }  
  355.         else //若是想读取位图来创建地形,而不是平坦的地面,需要进行如下操作*/  
  356.         {  
  357.             String filename = mTerrainGroup->generateFilename(x, y);  
  358.             //经调试,发现filename=ygTerrain_00000000.dat  
  359.             //如果有存档的,或者说以前运行过这个例子,直接加载.dat文件  
  360.             if (ResourceGroupManager::getSingleton().resourceExists(mTerrainGroup->getResourceGroup(),filename))  
  361.             {  
  362.                 /*仔细研究了下resourceExists函数,由于调试中filename=ygTerrain_00000000.dat, 
  363.                 那么这个dat文件是怎么加载入资源组管理器中的呢?发现resources_d.cfg文件中 
  364.                 这么一句话[General]:FileSystem=D:/MySoft/ogre_src_v1-8-1/Samples/Media,所以资源加载阶段, 
  365.                 把这个文件夹中的所有文件包括.bat文件都加载进入资源组了,而我的ygTerrain_00000000.dat文件 
  366.                 就放在这个文件夹下。*/  
  367.   
  368.                 //下面函数功能是定义一个在地形网格中的插槽,在这个阶段,地形实例实际上并没有出现在网格中,  
  369.                 //只有做只是为它准备一个位置。我们像这样做的原因是为了支持这种地形实例的后台准备。  
  370.                 //参数的x,y坐标表示地形槽相对中心插槽的位置  
  371.                 //只有xy坐标参数的情况下,这个函数从一个现成的如terrain.bat文件中加载地形插槽  
  372.                 mTerrainGroup->defineTerrain(x, y);  
  373.             }  
  374.             //否则读取位图,创建加载地形  
  375.             else  
  376.             {  
  377.                 Image img;  
  378.                 getTerrainImage(x % 2 != 0, y % 2 != 0, img);//从PNG格式的灰度图图片读取灰度值,作为高度的换算基值  
  379.                 //调用重载函数defineTerrain创建地形,注意此时img代表了已经加载好高度图的数据集  
  380.                 mTerrainGroup->defineTerrain(x, y, &img);   
  381.                 mTerrainsImported = true//作为下文地形纹理渲染标志,失败则表示没有创建好地形  
  382.             }  
  383.         }  
  384.     }  
  385.     //getTerrainImage()定义为:  
  386.     void getTerrainImage(bool flipX, bool flipY, Image& img)  
  387.     {  
  388.         //高度图在这里给出  
  389.         img.load("terrain.png", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);  
  390.         if (flipX)  
  391.             img.flipAroundY(); //这些函数封装在.dll里了,没能看个究竟~  
  392.         if (flipY)  
  393.             img.flipAroundX(); //这些函数封装在.dll里了,没能看个究竟~  
  394.   
  395.     }  
  396.     //地形纹理图层混合合成函数  
  397.     void initBlendMaps(Terrain* terrain)  
  398.     {   /*纹理混合,Ogre1.7的地形纹理默认支持8层纹理混合(1.8的还不清楚),如果想更改,可通过地形的全局配置设置, 
  399.         混合越多越慢。刚才我们定义了三层纹理。默认情况下,引擎只显示第一层纹理纹理, 
  400.         所以我们得为每一层指定混合系数,0表示不显示,1表示显示,0~1表示混合混合显示。*/  
  401.         //取得第2层纹理(绿色地皮grass_green)  
  402.         Ogre::TerrainLayerBlendMap *pBlend1 = terrain->getLayerBlendMap( 1 );  
  403.         //取得第3层纹理(长了植物growth_weirdfungus)  
  404.         Ogre::TerrainLayerBlendMap *pBlend2 = terrain->getLayerBlendMap( 2 );  
  405.         Ogre::Real MinHeight1 = 70;  
  406.         Ogre::Real FadeDist1 = 40;  
  407.         Ogre::Real MinHeight2 = 70;  
  408.         Ogre::Real FadeDist2 = 15;  
  409.         float *pBlend1Point = pBlend1->getBlendPointer();//取得纹理地图起始位置  
  410.         float *pBlend2Point = pBlend2->getBlendPointer();  
  411.         for( Ogre::uint16 y = 0; y < terrain->getLayerBlendMapSize(); ++y )  
  412.         {  
  413.             for( Ogre::uint16 x = 0; x <terrain->getLayerBlendMapSize(); ++x )  
  414.             {  
  415.                 Ogre::Real tx, ty;  
  416.                 //将纹理坐标转换为地形坐标(类似蒙皮)  
  417.                 pBlend1->convertImageToTerrainSpace( x, y, &tx, &ty );  
  418.                 //取得在(x,y)点坐标的高度(2D坐标系的xy)  
  419.                 Ogre::Real height = terrain->getHeightAtTerrainPosition( tx, ty );  
  420.                 //在不同的高度使用不同的纹理,  
  421.                 //当高度<70,Val=0不显示纹理1,高度>110,val=1,只显示纹理2 ,70~110之间混合显示  
  422.                 //当高度<70,Val=0不显示纹理1,高度>85,val=1,只显示纹理3 ,70~85之间混合显示  
  423.                 Ogre::Real val = ( height - MinHeight1 ) / FadeDist1; //70-110之间混合显示  
  424.                 val = Ogre::Math::Clamp( val, static_cast<Ogre::Real>( 0 ), static_cast<Ogre::Real>( 1 ) );  
  425.                 *pBlend1Point++ = val;  
  426.   
  427.                 val = ( height - MinHeight2 ) / FadeDist2; //70-85之间混合显示  
  428.                 val = Ogre::Math::Clamp( val, static_cast<Ogre::Real>( 0 ), static_cast<Ogre::Real>( 1 ) );  
  429.                 //执行混合设置,0的话不显示,1只显示它,0~1混合显示,值设置完毕之后,指针++指向下一个  
  430.                 *pBlend2Point++ = val;  
  431.             }  
  432.         }  
  433.         pBlend1->dirty();  
  434.         pBlend2->dirty();  
  435.         pBlend1->update();  
  436.         pBlend2->update();  
  437.         /*总之,第一层范围最大,全部都100%显示;第二层范围稍大,70-110之间按比例混合显示, 
  438.         第三层范围最小,70-85之间按比例混合显示。 
  439.         即:当小于70时,则第二层和第三层都不显示,只显示第一层。 
  440.         当大于70且小于85时,第一层100%显示,第二层和第三层按比例混合显示。 
  441.         当大于85且小于110时,第一层和第二层100%显示(只显示第二层),第三层按比例混合显示。 
  442.         当大于110时,三层都100%显示,由于第三层最后铺上,实际上只显示第三层。 
  443.         总之,可以把70-85看成第二层纹理的过渡带,70-110看成第三层纹理的过渡带, 
  444.         分析每一层纹理时独立开来,不要管其他纹理的影响。*/  
  445.     }  
  446. };  
  447.   
  448. int main() //入口,main函数  
  449. {  
  450.   
  451.     MyApplication app;  
  452.     app.StartUp();  
  453.     while( app.KeepRunning() )  
  454.     {  
  455.         app.RenderOneFrame();  
  456.     }  
  457.   
  458.     return 0;  
  459. }  


使用时,把上面所有代码拷贝到一个cpp文件中,设置好头文件包含目录、库文件目录(附加依赖项)以及工作目录,就可以直接运行了。下面是截图:


附:

我的vs2010附加包含目录:

D:/MySoft/ogre_src_v1-8-1/OgreMain/include;
D:/MySoft/ogre_src_v1-8-1_OgreBuild/include;
D:/MySoft/ogre_src_v1-8-1/Dependencies/include;
D:/MySoft/ogre_src_v1-8-1/Dependencies/include/OIS;
D:/MySoft/ogre_src_v1-8-1/Dependencies/include/Cg;
D:/MySoft/ogre_src_v1-8-1;
D:/MySoft/ogre_src_v1-8-1/OgreMain/include/Threading;
D:/MySoft/ogre_src_v1-8-1/Components/Terrain/../Paging/include;
D:/MySoft/ogre_src_v1-8-1/Components/Terrain/include;

我的附加依赖项:

D:\MySoft\ogre_src_v1-8-1_OgreBuild\lib\Debug\OgreMain_d.lib
D:\MySoft\ogre_src_v1-8-1\Dependencies\lib\Debug\OIS_d.lib
D:\MySoft\ogre_src_v1-8-1_OgreBuild\lib\Debug\OgreTerrain_d.lib
D:\MySoft\ogre_src_v1-8-1_OgreBuild\lib\Debug\OgrePaging_d.lib
D:\MySoft\ogre_src_v1-8-1\Dependencies\lib\debug\freetype2311_d.lib
D:\MySoft\ogre_src_v1-8-1\Dependencies\lib\debug\FreeImaged.lib
D:\MySoft\ogre_src_v1-8-1\Dependencies\lib\debug\zziplibd.lib
D:\MySoft\ogre_src_v1-8-1\Dependencies\lib\debug\zlibd.lib

注意,上面的D:\MySoft\ogre_src_v1-8-1_OgreBuild是我用cmake构建代码时使用的目录,根据不同情况更改,或者使用OGRE_HOME更方便。另外,由于附加依赖项直接使用了路径+库文件名,所以附加库目录就可以不用设置了。(如果附加依赖项不含路径,只有库文件名的话,则需要设置附加库目录,以便vs知道去哪寻找库文件)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值