Ogre 节点、属性方法 案例分析

  1667人阅读  评论(0)  收藏 

DirectX使用的是左手坐标正向右,y正向上,z正向前,即向屏幕里

Ogre/OpGL  使用的是右手坐标系 x正向右,y正向上,z正向自己,即向屏幕外

 

以下开发工具为 Visual Studio 2010, DirectX版本为:Microsoft DirectX SDK (June 2010)

       Ogre版本为:OgreSDK_vc10_v1-7-3

注意:要想Ogre程序能运行,必须将Ogre库的dll文件路径配置进环境变量:


一:9个实体,随机出现一个,隐藏另一个,鼠标移到转动相机,按键盘移动相机.

(程序为游戏类编程/Ogre/Ogre1.73/FirstOGRE)

 1:新建一个空的 win32控制台应用程序,命名为:FirstOGRE

 2:添加一个 FirstOGRE.cpp文件

 3:配置包含目录(包含Ogre的头文件的目录)库目录(包含Ogrelib文件的目录)


        

 4:配置附加依赖项:

            OgreRTShaderSystem_d.lib

OgreMain_d.lib

OIS_d.lib

      

 5:将OgreSDK_vc10_v1-7-3安装目录下的 media目录拷贝到当前工程目录下,将OgreSDK_vc10_v1-7-3安装目录

下的 bin目录下 debug目录下和 release目录的下后缀为 .cfg的文件拷贝到当前目录下并修改.cfg文件

内的配置内容(修改配置路径的内容)

  

  

   

     

 6:添加一个 MyEntity

   MyEntity.h

#ifndef MyEntity_H_

#define MyEntity_H_

 

#include <OGRE/ExampleApplication.h>

 

class MyEntity

{

public:

   MyEntity(Ogre::SceneManager*mSceneMgrint iint j);//创建实体,节点,并为节点创建动画.

   ~MyEntity(void);

 

public:

   voidupdate(floatinterval);//动画

   voidenable(); //随机显示实体

   voiddisable();//让显示的实体隐藏

   boolisEnable();//判断显示隐藏状态

 

private:

   Ogre::Entity *m_pEnt;         //创建的实体

   Ogre::SceneNode *m_pSceneNode;//保存实体的节点

 

   Ogre::AnimationState *m_pAnimState;//负责实体的动画

};

 

#endif

    

   MyEntity.cpp

#include "MyEntity.h"

 

MyEntity::MyEntity(Ogre::SceneManager*mSceneMgr,int i, int j)

{

   using namespace Ogre;

 

   m_pEnt = mSceneMgr->createEntity("myEntiy"+Ogre::StringConverter::toString(i*3+j),"Sinbad.mesh");//创建实体,并给实体命名

   m_pEnt->setVisible(false);//默认情况下实体隐藏

   m_pSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(50*i, 0, 50*j));//创建一个节点时,给节点一个位置

   //pSceneNode->setScale(Ogre::Vector3(6.0f, 6.0f, 6.0f));//节点放大6

   m_pSceneNode->attachObject(m_pEnt);//节点与实体关联

 

   //创建实体的动画

   Ogre::Animation *pAnimation =mSceneMgr->createAnimation("myEntiy"+Ogre::StringConverter::toString(i*3+j), 3.0f);//第一个为动画的名称,后一个为动画的时长

   pAnimation->setInterpolationMode(Ogre::Animation::IM_SPLINE);//设置动画差值为样条插值

   Ogre::NodeAnimationTrack*pTrack =pAnimation->createNodeTrack(0,m_pSceneNode);//创建一个轨迹动画,第一个值为索引,第二个为关联的节点

   //在第秒,物体放大为整个物体的倍

   Ogre::TransformKeyFrame*pKey =pTrack->createNodeKeyFrame(0.0f);

   pKey->setScale(Ogre::Vector3(3.0f,3.0f, 3.0f));//物体放大3

   pKey->setTranslate(Ogre::Vector3(50*i, 0, 50*j));//转换点

   //在第秒后,物体放大为整个物体的倍

   pKey = pTrack->createNodeKeyFrame(1.0f);

   pKey->setScale(Ogre::Vector3(6.0f,6.0f, 6.0f));

   pKey->setTranslate(Ogre::Vector3(50*i, 0, 50*j));

   //在第秒后,物体放大为整个物体的倍

   pKey = pTrack->createNodeKeyFrame(2.0f);

   pKey->setScale(Ogre::Vector3(6.0f,6.0f, 6.0f));

   pKey->setTranslate(Ogre::Vector3(50*i, 0, 50*j));

   //在第秒后,物体放大为整个物体的倍

   pKey = pTrack->createNodeKeyFrame(3.0f);

   pKey->setScale(Ogre::Vector3(3.0f,3.0f, 3.0f));

   pKey->setTranslate(Ogre::Vector3(50*i, 0, 50*j));

   //通过上面的动画创建动画状态

   m_pAnimState = mSceneMgr->createAnimationState("myEntiy"+Ogre::StringConverter::toString(i*3+j));

   m_pAnimState->setEnabled(false);//初期动画为关闭

   m_pAnimState->setLoop(true);    //设置动画为循环播放

}

 

MyEntity::~MyEntity(void)

{

}

 

void MyEntity::update(floatinterval)

{

   /*自己写的缩放动画

   floatscale = 0.0f;

   if(interval<= 0.5f) scale = 6.0f*interval;

   elsescale = 6.0f*(1-interval);

   m_pSceneNode->setScale(scale,scale, scale);

   */

 

   m_pAnimState->setTimePosition(interval);//设置动画的起点

}

 

void MyEntity::enable()

{

   if(!m_pEnt->getVisible()){

       m_pAnimState->setEnabled(true);//设置动画为开启

       m_pAnimState->setTimePosition(0.0f);//设置动画的起点

       m_pEnt->setVisible(true);

   }

}

 

void MyEntity::disable()

{

   if(m_pEnt->getVisible())m_pEnt->setVisible(false);//隐藏

}

 

bool MyEntity::isEnable()

{

   return m_pEnt->getVisible();//判断是否是显示

}

     

 7:添加一个 MyEntityManager

   MyEntityManager.h

#ifndef MyEntityManager_H_

#define MyEntityManager_H_

 

#include "MyEntity.h"

 

class MyEntityManager//MyEntity的管理类

{

public:

MyEntityManager(Ogre::SceneManager*mSceneMgr);

~MyEntityManager(void);

 

public:

voidupdate(constFrameEvent&evt);//帧事件

 

private:

MyEntity*m_pMyEnt[9];//9个实体

MyEntity*m_pCurrentMyEnt;//记录当前可见实体

floatm_time;//用于时间累加,当大于等于1,还原为0

};

 

#endif

      

   MyEntityManager.cpp

#include "MyEntityManager.h"

 

MyEntityManager::MyEntityManager(Ogre::SceneManager*mSceneMgr) : m_time(0.0f),m_pCurrentMyEnt(NULL)

{

/*Ogre::Entity*pEnt = mSceneMgr->createEntity("Sword", "Sword.mesh");

SceneNode*pSceneNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

pSceneNode->setScale(Ogre::Vector3(6.0f,6.0f, 6.0f));

pSceneNode->attachObject(pEnt);*/

 

for(inti=0; i<3; i++){  //创建9个实体

     for(intj=0; j<3; j++){

         m_pMyEnt[i*3+j] =new MyEntity(mSceneMgr,ij);

     }

}

}

 

MyEntityManager::~MyEntityManager(void)

{

for(inti=0; i<9; i++){

     deletem_pMyEnt[i];

     m_pMyEnt[i] =NULL;

}

m_pCurrentMyEntNULL;

}

 

void MyEntityManager::update(constFrameEventevt)

{

m_time+= evt.timeSinceLastFrame;

if(m_time >= 1.0f){//当每过1,随机显示一个实体

     if(NULL !=m_pCurrentMyEnt)m_pCurrentMyEnt->disable();

     m_pCurrentMyEntm_pMyEnt[rand()%9];

     m_pCurrentMyEnt->enable();

 

     m_time= 0.0f;  //还原为0.0f

}

 

if(NULL !=m_pCurrentMyEnt)m_pCurrentMyEnt->update(m_time);//更新显示的实体状态

}

 

 8:添加一个监听类:MyEntityFrameListener

   MyEntityFrameListener.h

#ifndef MyEntityFrameListener_H_

#define MyEntityFrameListener_H_

 

#include "ogre/exampleframelistener.h"

 

class MyEntityManager;

class MyEntityFrameListener:public ExampleFrameListener,publicOIS::KeyListener,public OIS::MouseListener

{

public:

//bufferedKeys,bufferedMouse,bufferedJoy:是否启用键盘,鼠标,手柄的缓冲,默认不启用,会导致不停地检查输入设备信息来确定按键是否按下或释放,鼠标是否移动等等,如果检测

//                                       不够快速,某一动作可能不会被发现,所以调用时,要启用缓冲,在缓冲模式下,OIS会记录所有输入设备的变化,并把它们通过消息告知应

//                                       用程序。在缓冲模式下不需要检查输入设备的状态,只需要处理OIS发送的消息。

MyEntityFrameListener(MyEntityManager *pMyEntMgr,RenderWindow*win,Camera*cam,bool bufferedKeysfalsebool bufferedMouse = false,boolbufferedJoy=false);

~MyEntityFrameListener(void);

 

public:

//virtualbool processUnbufferedKeyInput(const FrameEvent& evt); //键盘输入

//virtual bool processUnbufferedMouseInput(constFrameEvent& evt);//鼠标输入

virtualboolkeyPressed(constOIS::KeyEvent &arg);//启用bufferedKeys缓存,并继承了KeyListener,则使用此替代processUnbufferedKeyInput

virtualboolkeyReleased(constOIS::KeyEvent &arg);

 

virtualboolmouseMoved(const OIS::MouseEvent &arg);

virtualboolmousePressed(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

virtualboolmouseReleased(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

 

        void moveCamera(); //移动相机

virtualboolframeEnded(constFrameEvent&evt); //循环刷新界面

 

private:

MyEntityManager*m_pMyEntMgr;//实体管理类,也是实体集合类

};

 

#endif

      

   MyEntityFrameListener.cpp

#include "MyEntityFrameListener.h"

#include "MyEntityManager.h"

 

MyEntityFrameListener::MyEntityFrameListener(MyEntityManager *pMyEntMgr,RenderWindow*win,Cameracambool bufferedKeys,boolbufferedMouse,bool bufferedJoy)

:ExampleFrameListener(win,cambufferedKeys,bufferedMouse,bufferedJoy),m_pMyEntMgr(pMyEntMgr)

{

//启用了键鼠柄的缓冲,就能使用它们的回调函数

mKeyboard->setEventCallback(this);

mMouse->setEventCallback(this);

}

 

MyEntityFrameListener::~MyEntityFrameListener(void)

{

if(NULL !=m_pMyEntMgr){

     deletem_pMyEntMgr;

     m_pMyEntMgrNULL;

}

}

 

bool MyEntityFrameListener::keyPressed(constOIS::KeyEvent&arg)//键盘的键按下

{

   RealmoveScale = 0.2f;

  

   switch(arg.key){

   caseOIS::KC_A:

   caseOIS::KC_LEFT:

       mTranslateVector.x = -moveScale;//Move camera left

       break;

   caseOIS::KC_D:

   caseOIS::KC_RIGHT:

       mTranslateVector.x =moveScale//Move camera RIGHT

       break;

   caseOIS::KC_W:

   caseOIS::KC_UP:

       mTranslateVector.z = -moveScale;//Move camera forward

       break;

   caseOIS::KC_S:

   caseOIS::KC_DOWN:

       mTranslateVector.z =moveScale//Move camerabackward

       break;

   caseOIS::KC_PGUP:

       mTranslateVector.y =moveScale//Move camera up

       break;

   caseOIS::KC_PGDOWN:

       mTranslateVector.y = -moveScale;//Move camera down

       break;

   /*设置相机投影多边形模式,不用

   caseOIS::KC_NUMPAD0:

       case 0 :mCamera->setPolygonMode(PM_SOLID);

       break;

   caseOIS::KC_NUMPAD1:

       case 1 : mCamera->setPolygonMode(PM_WIREFRAME);

       break;

   caseOIS::KC_NUMPAD2:

       case 2 :mCamera->setPolygonMode(PM_POINTS);

       break;*/

   }

 

   returntrue;

}

 

bool MyEntityFrameListener::keyReleased(constOIS::KeyEvent &arg)//释放按下的键

{

        mTranslateVectorVector3::ZERO;//防止按键释放后还继续移动相机

returntrue;

}

 

bool MyEntityFrameListener::mouseMoved(constOIS::MouseEvent &arg)

{

    constOIS::MouseState&ms =arg.state;

    if(ms.buttonDown(OIS::MB_Left)) {

    } elseif(ms.buttonDown(OIS::MB_Right)) {

    } else{

        mRotXDegree(-ms.X.rel * 0.13);//转为弧度,如:Degree(180)

        mRotYDegree(-ms.Y.rel * 0.13);//转为弧度,如:Degree(180)

    }

    

  returntrue;

}

 

bool MyEntityFrameListener::mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

returntrue;

}

 

 

bool MyEntityFrameListener::mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

returntrue;

}

 

void MyEntityFrameListener::moveCamera()//移动相机

{

mCamera->yaw(mRotX);  //y轴转动

mCamera->pitch(mRotY);//x轴转动

mCamera->moveRelative(mTranslateVector);//移动相机

 

mRotXmRotY = 0; //防止鼠标不转动后继续转动相机

}

 

bool MyEntityFrameListener::frameEnded(constFrameEventevt)

{

//ExampleFrameListener::frameEnded(evt);//可以不用

moveCamera();//移动相机

if(NULL !=m_pMyEntMgr)m_pMyEntMgr->update(evt);//每个一秒随机显示一个实体,隐藏另一个实体等

 

returntrue;

}

 

 9:添加一个 应用程序类:MyExampleApplication

   MyExampleApplication.h

#ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

 

#include "MyEntityManager.h"

#include "MyEntityFrameListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

MyExampleApplication(void);

~MyExampleApplication(void);

 

public:

voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

voidcreateFrameListener(void);//创建帧监听

 

private:

MyEntityManager       *m_pMyEntMgr;

MyEntityFrameListener*m_pFrameLst;

};

 

#endif

      

   MyExampleApplication.cpp

#include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

m_pMyEntMgrNULL;

m_pFrameLstNULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if(NULL !=m_pMyEntMgr){

     deletem_pMyEntMgr;

     m_pMyEntMgrNULL;

}

 

if(NULL ==m_pFrameLst){

            mRoot->removeFrameListener(m_pFrameLst);//删除监听

    

     deletem_pFrameLst;

     m_pFrameLstNULL;

}

}

 

void MyExampleApplication::createScene(void)

{

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));//设置环境光

Light*l =mSceneMgr->createLight("mainLight");

l->setPosition(20, 80, 50);

 

Ogre::Vector3pst = mCamera->getPosition();

Ogre::Quaternionort = mCamera->getOrientation();

mCamera->setPosition(94.0f, 194.043f, 375.0f);//设置摄像机位置

mCamera->setOrientation(Ogre::Quaternion(0.953763f, -0.3f, -0.00865638f,-0.0027f));//设置摄像机角度

 

mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2",50);//设置天空盒

 

m_pMyEntMgrnew MyEntityManager(mSceneMgr);//创建9个实体

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(m_pMyEntMgr,mWindow,mCameratruetruetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

 

 10:FirstOGRE.cpp的内容:

#include "MyExampleApplication.h"

 

int main(){

  MyExampleApplicationm;

  m.go();

 

  return0;

}

     

     

二:旋转节点,缩放节点,坐标空间移动旋转节点等,绑定相机旋转节点等

(程序为游戏类编程/Ogre/Ogre1.73/SecondOGRE)

 1:新建一个 空的win32控制台应用程序,命名为:SecondOGRE.

 2:添加一个 SecondOGRE.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyExampleApplication

    MyExampleApplication.h

#ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include "MyEntityFrameListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

MyExampleApplication(void);

~MyExampleApplication(void);

 

public:

voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

voidcreateFrameListener(void);//创建帧监听

 

private:

MyEntityFrameListener*m_pFrameLst;

};

 

#endif

     

   MyExampleApplication.cpp

 #include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

  m_pFrameLst = NULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if (NULL !=m_pFrameLst){

    mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

    deletem_pFrameLst;

    m_pFrameLstNULL;

}

}

 

void MyExampleApplication::createScene(void)

{

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));//设置环境光

 

Light*l =mSceneMgr->createLight("mainLight");

l->setPosition(20, 80, 50);

 

Ogre::Vector3pst = mCamera->getPosition();

Ogre::Quaternionort = mCamera->getOrientation();

mCamera->setPosition(0, 100.0f, 100.0f);//设置摄像机位置

mCamera->setOrientation(Ogre::Quaternion(0.953763f, -0.3f, -0.00865638f,-0.0027f));//设置摄像机方向

 

mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2", 50);//设置天空盒

 

//创建地面

Planeplane(Vector3::UNIT_Y, -15);//通过法向量与恒定数创建一个Plane

MeshManager::getSingleton().createPlane("GrassPlane",

ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,

    1500, 1500,//宽度,高度

    200, 200,  // x方向段值,y方向段值,即面板分成多少个三角形

    true,      //创建一个垂直的法向量到面板

    1, 5, 5, Vector3::UNIT_Z);// 2D纹理坐标设置的数量,u,v方向重复的瓦片的数量,纹理方向

Entity*pEnt =mCamera->getSceneManager()->createEntity("GrassPlane","GrassPlane");

mCamera->getSceneManager()->getRootSceneNode()->createChildSceneNode("GrassPlane")->attachObject(pEnt);

pEnt->setMaterialName("Examples/BeachStones");//设置材质 Examples/GrassFloor

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(mWindow,mCamera,truetruetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

       

 5:添加一个类:MyEntityFrameListener

    MyEntityFrameListener.h

 #ifndef MyEntityFrameListener_H_

#define MyEntityFrameListener_H_

 

#include "ogre/exampleframelistener.h"

using namespaceOgre;

 

class MyEntityFrameListener:public ExampleFrameListener,publicOIS::KeyListener,public OIS::MouseListener

{

public:

MyEntityFrameListener(RenderWindow*winCameracambool bufferedKeys =falsebool bufferedMouse = false,boolbufferedJoyfalse);

~MyEntityFrameListener(void);

 

public:

virtualboolkeyPressed(constOIS::KeyEvent &arg);

virtualboolkeyReleased(constOIS::KeyEvent &arg);

 

virtualboolmouseMoved(constOIS::MouseEvent &arg);

virtualboolmousePressed(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

virtualboolmouseReleased(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

 

voidmoveCamera();//移动相机

virtualboolframeEnded(constFrameEvent&evt);//循环刷新界面

 

protected:

voidcreateEntity1();//创建实体,绕各自自身轴旋转节点等

voidcreateEntity2();//创建实体,缩放节点等

// root节点没有父节点,其它节点都有父节点

voidcreateEntity3();//坐标空间,TS_PARENT(父节点空间),TS_WORLD(世界坐标空间),TS_LOCAL(自己的空间)

voidcreateEntity4();//在各个空间的移动

voidcreateEntity5();//在各个空间的转动

 

protected:

SceneManager*mSceneMgr;

 

SceneNode*m_pNode7;

SceneNode*m_pNode8;

SceneNode*m_pNode9;

SceneNode*m_pNode10;

};

 

#endif

        

    MyEntityFrameListener.cpp

 #include "MyEntityFrameListener.h"

 

MyEntityFrameListener::MyEntityFrameListener(RenderWindow*win,Camera*cam,bool bufferedKeys,boolbufferedMouse,boolbufferedJoy)

  : ExampleFrameListener(win,cambufferedKeys,bufferedMouse,bufferedJoy)

{

  //启用了键鼠柄的缓冲,就能使用它们的回调函数

  mKeyboard->setEventCallback(this);

  mMouse->setEventCallback(this);

 

  mSceneMgrcam->getSceneManager();

 

    createEntity1();//创建实体,绕各自自身轴旋转节点等

  createEntity2();//创建实体,缩放节点

  createEntity3();//坐标空间,TS_PARENT(父节点空间),TS_WORLD(世界坐标空间),TS_LOCAL(自己的空间)

  createEntity4();//在各个空间的移动

  createEntity5();//在各个空间的转动

}

 

MyEntityFrameListener::~MyEntityFrameListener(void)

{

}

 

bool MyEntityFrameListener::keyPressed(constOIS::KeyEvent&arg)//键盘的键按下

{

  RealmoveScale = 0.2f;

 

  switch(arg.key){

  caseOIS::KC_A:

  caseOIS::KC_LEFT:

      mTranslateVector.x = -moveScale;//Move camera left

      break;

  caseOIS::KC_D:

  caseOIS::KC_RIGHT:

      mTranslateVector.x =moveScale//Move camera RIGHT

      break;

  caseOIS::KC_W:

  caseOIS::KC_UP:

      mTranslateVector.z = -moveScale;//Move camera forward

      break;

  caseOIS::KC_S:

  caseOIS::KC_DOWN:

      mTranslateVector.z =moveScale//Move camerabackward

      break;

  caseOIS::KC_PGUP:

      mTranslateVector.y =moveScale//Move camera up

      break;

  caseOIS::KC_PGDOWN:

      mTranslateVector.y = -moveScale;//Move camera down

      break;

  }

 

  returntrue;

}

 

bool MyEntityFrameListener::keyReleased(constOIS::KeyEvent&arg)//释放按下的键

{

  mTranslateVectorVector3::ZERO;//防止按键释放后还继续移动相机

  returntrue;

}

 

bool MyEntityFrameListener::mouseMoved(constOIS::MouseEvent&arg)

{

  constOIS::MouseState&ms =arg.state;

  if(ms.buttonDown(OIS::MB_Left)){

  } elseif(ms.buttonDown(OIS::MB_Right)) {

  } else{

      mRotXDegree(-ms.Y.rel * 0.13);//转为弧度,如:Degree(180)

      mRotYDegree(-ms.X.rel * 0.13);//转为弧度,如:Degree(180)

  }

 

  returntrue;

}

 

bool MyEntityFrameListener::mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

  returntrue;

}

 

 

bool MyEntityFrameListener::mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

  returntrue;

}

 

void MyEntityFrameListener::moveCamera() //移动相机

{

  // mCamera->yaw(mRotX);  //y轴转动

  //mCamera->pitch(mRotY);//x轴转动

  mCamera->moveRelative(mTranslateVector);//移动相机

 

  // pNode7->translate(tran3, Node::TS_PARENT);//TS_PARENT,点的位置:pos7+tran3

  //Quaternionq;q.FromAngleAxis(angle,axis);q.normalise();mOrientation = q*mOrientation;

  //pNode8->translate(tran8,Node::TS_LOCAL);//TS_LOCAL,点的位置:pos8+mOrientation*tran8

  //Quaternionq;q.FromAngleAxis(angle,axis);q.normalise();mOrientation = q*mOrientation;

  //pNode9->translate(tran9,Node::TS_WORLD);//TS_WORLD,点的位置:pos9+(mParent->_getDerivedOrientation().Inverse()*tran9)/mParent->_getDerivedScale())

  //Quaternionq;q.FromAngleAxis(angle,axis);q.normalise();

  //mOrientation =mOrientation*_getDerivedOrientation().Inverse()*q*_getDerivedOrientation();

 

  m_pNode7->yaw(mRotY);//m_pNode7节点必须转,下面的3个节点才会绕着m_pNode7节点转

  //m_pNode7节点转,会导致其子节点跟着转实际上不需要 m_pNode8->yaw +m_pNode8->lookAt

 

  //**m_pNode8->yaw(mRotY);//,Node::TS_PARENT //加不加空间都绕着自身点转动

  //**m_pNode8->lookAt(m_pNode7->getPosition(),Node::TS_WORLD);//可以防止m_pNode8自转

 

  //**m_pNode9->yaw(mRotY);//,Node::TS_WORLD //加不加空间都绕着自身点转动

  //**m_pNode9->lookAt(m_pNode7->getPosition(),Node::TS_WORLD);//可以防止m_pNode9自转

 

  m_pNode10->yaw(mRotY,Node::TS_WORLD);//m_pNode10节点绑定的相机会绕着m_pNode7节点所在点转,但是

//m_pNode10节点是绕着自己所在的点转,而不是m_pNode7节点所在的点

//m_pNode10->lookAt(m_pNode7->getPosition(),Node::TS_WORLD);//不能调用,否则m_pNode10不会转

  m_pNode10->pitch(mRotX);

 

  mRotXmRotY = Radian(0);//防止鼠标不转动后继续转动相机

}

 

bool MyEntityFrameListener::frameEnded(constFrameEventevt)

{

  moveCamera();//移动相机

  returntrue;

}

 

void MyEntityFrameListener::createEntity1()//创建实体,绕各自自身轴旋转节点等

{

  //(0,0,0)点放置一个节点实体,用于与下面4个节点实体做对比

  Entity*pEnt0 =mSceneMgr->createEntity("MyEntity0","Sinbad.mesh");

  pEnt0->setMaterialName("Ogre/Skin");

  SceneNode*pNode0 =mSceneMgr->createSceneNode("MyEntity0");  

  mSceneMgr->getRootSceneNode()->addChild(pNode0);//给根节点添加一个子节点

  pNode0->attachObject(pEnt0);//给节点附上实体

  pNode0->setPosition(0,0,0);//设置pNode1在根节点的位置

 

  //用于下面3个节点的父节点

  Entity*pEnt1 =mSceneMgr->createEntity("MyEntity1","Sinbad.mesh");

  SceneNode*pNode1 =mSceneMgr->createSceneNode("MyEntity1");  

  mSceneMgr->getRootSceneNode()->addChild(pNode1);//给根节点添加一个子节点

  pNode1->attachObject(pEnt1);//给节点附上实体

  pNode1->setPosition(0, 0, -150);//设置pNode1在根节点的位置

 

  //pitch:绕自身X轴转

  Entity*pEnt2 =mSceneMgr->createEntity("MyEntity2","Sinbad.mesh");

  SceneNode*pNode2 =mSceneMgr->createSceneNode("MyEntity2");

  pNode1->addChild(pNode2);//pNode1节点添加子节点pNode2

  pNode2->attachObject(pEnt2);//节点2附上实体

  pNode2->setPosition(10,0,0);//设置pNode2pNode1中的位置

  pNode2->pitch(Radian(Math::HALF_PI));//HALF_PIPI的一半,PI/2,X轴逆时针旋转PI/2

  Vector3v2 =pNode2->getPosition();//取得的是10,0,0

 

  // yaw:绕自身Y轴转

  Entity*pEnt3 =mSceneMgr->createEntity("MyEntity3","Sinbad.mesh");

  SceneNode*pNode3 =mSceneMgr->createSceneNode("MyEntity3");

  pNode1->addChild(pNode3);//pNode1节点添加子节点pNode3

  pNode3->attachObject(pEnt3);

  Vector3pos(0, 0, 0);

  Vector3transVec(20, 0, 0);

  pNode3->setPosition(pos);

  pNode3->translate(transVec);//新的位置为:pos + transVec

  pNode3->yaw(Degree(90.0f));//Y轴逆时针旋转90,相当于Radian(Math::HALF_PI)

 

  // roll:绕自身Z轴转

  Entity*pEnt4 =mSceneMgr->createEntity("MyEntity4","Sinbad.mesh");

  SceneNode*pNode4 =mSceneMgr->createSceneNode("MyEntity4");

  pNode1->addChild(pNode4);

  pNode4->attachObject(pEnt4);

  pNode4->setPosition(30,0,0);//设置pNode4pNode1中的位置

  pNode4->roll(Radian(Math::HALF_PI));//Z轴逆时针旋转P1/2

}

 

void MyEntityFrameListener::createEntity2()//创建实体,缩放节点

{

  Entity*pEnt5 =mSceneMgr->createEntity("MyEntity5","ninja.mesh");

  SceneNode*pNode5 =mSceneMgr->createSceneNode("MyEntity5");

  mSceneMgr->getRootSceneNode()->addChild(pNode5);

  pNode5->attachObject(pEnt5);

  pNode5->setPosition(60, 0, 0);

  pNode5->scale(0.1f, 0.1f, 0.1f);//节点缩小为当前大小的0.1

 

  Entity*pEnt6 =mSceneMgr->createEntity("MyEntity6","Sinbad.mesh");

  SceneNode*pNode6 =mSceneMgr->getRootSceneNode()->

      createChildSceneNode("MyEntity6",Vector3(70,0, 0));//为节点指定名称,指定位置

  pNode6->attachObject(pEnt6);

  pNode6->setScale(2.0f, 2.0f, 2.0f);//节点放大为原始大小的2

}

 

void MyEntityFrameListener::createEntity3()//坐标空间,TS_PARENT(父节点空间),TS_WORLD(世界坐标空间),TS_LOCAL(自己的空间)

{

  //下面两个个节点的父节点

  Entity*pEnt7 =mSceneMgr->createEntity("MyEntity7","Sinbad.mesh");

  m_pNode7mSceneMgr->getRootSceneNode()->createChildSceneNode("MyEntity7");

    m_pNode7->attachObject(pEnt7);

  m_pNode7->setPosition(Vector3(-30.0f,0.0f, -30.0f));

 

  //用于在TS_PARENT空间绕转

  Entity*pEnt8 =mSceneMgr->createEntity("MyEntity8","ninja.mesh");

  m_pNode8m_pNode7->createChildSceneNode("MyEntity8");

  m_pNode8->attachObject(pEnt8);

  m_pNode8->setPosition(0, 0, -20);

  m_pNode8->scale(0.05f, 0.05f, 0.05f);

 

  //用于在TS_WORLD空间绕转

  Entity*pEnt9 =mSceneMgr->createEntity("MyEntity9","Sinbad.mesh");

  m_pNode9m_pNode7->createChildSceneNode("MyEntity9");

  m_pNode9->attachObject(pEnt9);

  m_pNode9->setPosition(0, 0, -30);

 

  //m_pNode7节点的子节点,但是绕着m_pNode7节点转

  Vector3vPos =m_pNode7->getPosition();

  RealfRadius =pEnt7->getBoundingRadius();

  Vector3cameraNodePos(vPos.x,vPos.yvPos.z-fRadius);//相机节点位置在模型实体后面

 

  m_pNode10mSceneMgr->getRootSceneNode()->createChildSceneNode("MyEntity10");

  m_pNode10->attachObject(mCamera); 

  m_pNode10->setPosition(cameraNodePos);

  m_pNode10->lookAt(vPos,Node::TS_WORLD);//要使相机能绕m_pNode7节点转,必须在此设置lookAt

                   //但是此m_pNode10节点还是绕着自己所在点转

  Entity*pEnt10 =mSceneMgr->createEntity("MyEntity10","Sinbad.mesh");

  pEnt10->setMaterialName("OceanHLSL_GLSL");

  m_pNode10->attachObject(pEnt10);

}

 

void MyEntityFrameListener::createEntity4()//在各个空间的移动

{

  //下面两个节点的父节点,180度后,其自身的XZ坐标世界空间的 XZ 方向相反

  Entity*ent =mSceneMgr->createEntity("MyEntity11","Sinbad.mesh");

  ent->setMaterialName("Ogre/Skin");

  SceneNode*node =mSceneMgr->getRootSceneNode()->createChildSceneNode("Node11");

  node->attachObject(ent);

  node->setPosition(0,0,-100);

  node->yaw(Degree(180.0f));//180

 

  //此节点在父节点空间移动(translate(0,0,10)),即向世界空间的Z负方向移动,因为父节点转了180

  Entity*ent2 =mSceneMgr->createEntity("MyEntity12","Sinbad.mesh");

  SceneNode*node2 =node->createChildSceneNode("node12");

  node2->attachObject(ent2);

  node2->setPosition(10,0,0);

  node2->translate(0,0,10);

 

  //在自身空间移动Node::TS_LOCAL

  ent2mSceneMgr->createEntity("MyEntity13","Sinbad.mesh");

  ent2->setMaterialName("Examples/SphereMappedRustySteel");

  node2node->createChildSceneNode("node13");

  node2->attachObject(ent2);

  node2->yaw(Degree(45));

  node2->setPosition(10,0,0);

  node2->translate(0,0,10,Node::TS_LOCAL);

 

  //此节点在世界空间移动,向世界空间的Z正方向移动,即向父节点空间Z负方向移动

  Entity*ent3 =mSceneMgr->createEntity("MyEntity14","Sinbad.mesh");

  ent3->setMaterialName("OceanHLSL_GLSL");

  SceneNode*node3 =node->createChildSceneNode("node14");

  node3->setPosition(20,0,0);

  node3->translate(0,0,10,Node::TS_WORLD);

  node3->attachObject(ent3);

}

 

void MyEntityFrameListener::createEntity5()//在各个空间的转动

{

  Entity*ent =mSceneMgr->createEntity("MyEntity15","sinbad.mesh");

  SceneNode*node =mSceneMgr->getRootSceneNode()->createChildSceneNode("Node15");

  node->attachObject(ent);

 

  Entity*ent2 =mSceneMgr->createEntity("MyEntity16","sinbad.mesh");

  SceneNode*node2 =mSceneMgr->getRootSceneNode()->createChildSceneNode("Node16");

  node2->attachObject(ent2);

  node2->setPosition(10,0,0);

  node2->yaw(Degree(90));//在自身空间转动

  node2->roll(Degree(90));

 

  Entity*ent3 =mSceneMgr->createEntity("MyEntity17","Sinbad.mesh");

  SceneNode*node3 =node->createChildSceneNode("node17");

  node3->attachObject(ent3);

  node3->setPosition(20,0,0);

  node3->yaw(Degree(90),Node::TS_WORLD);//在世界空间转动

  node3->roll(Degree(90),Node::TS_WORLD);

}

        

 六:SecondOGRE.cpp的内容:

 #include "MyExampleApplication.h"

 

int main(){

 MyExampleApplication app;

 app.go();

 

 return 0;

}

       

三:通过面板(Plane)创建实体,灯光,阴影,相机,视口,简单移动模型等.

                                                (程序为游戏类编程/Ogre/Ogre1.73/ LightCameraShadow)

 1:新建一个空的 win32控制台应用程序, 命名为:LightCameraShadow

 2:添加一个 LightCameraShadow.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyExampleApplication

    MyExampleApplication.h

 #ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include "MyEntityFrameListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

  MyExampleApplication(void);

  ~MyExampleApplication(void);

 

public:

  voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

  voidcreateFrameListener(void);//创建帧监听

 

  voidcreateLinghtAndMesh();//创建Plane,灯光,Mesh

  voidcreateNewCamera();    //创建相机,添加视口

 

private:

  MyEntityFrameListener*m_pFrameLst;

  SceneNode*m_pSinbadNode;//模型实体节点

};

 

#endif

     

   MyExampleApplication.cpp

 #include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

m_pFrameLstNULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if (NULL !=m_pFrameLst){

    mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

    deletem_pFrameLst;

    m_pFrameLstNULL;

}

}

 

void MyExampleApplication::createScene(void)

{

/*

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f,0.5f, 0.5f));//设置环境光

Light *l =mSceneMgr->createLight("mainLight");

l->setPosition(20,80, 50);

 

Ogre::Vector3 pst =mCamera->getPosition();

Ogre::Quaternionort = mCamera->getOrientation();

mCamera->setPosition(0,100.0f, 100.0f); //设置摄像机位置

mCamera->setOrientation(Ogre::Quaternion(0.953763f,-0.3f, -0.00865638f, -0.0027f)); //设置摄像机方向

 

mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2", 50);//设置天空盒

*/

 

createLinghtAndMesh();//创建Plane,灯光,Mesh

createNewCamera();     //创建相机,添加视口

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(m_pSinbadNode,mWindow,mCamera,true,truetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

 

void MyExampleApplication::createLinghtAndMesh()//创建Plane,灯光,Mesh

{

//创建Plane

Ogre::Planeplane(Vector3::UNIT_Y,-10);//通过法向量与恒定数创建一个Plane

Ogre::MeshManager::getSingleton().createPlane("plane",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,

 1500, 1500,//宽度,高度

   200, 200,//x方向段值,y方向段值,即面板分成多少个三角形

    true,    //创建一个垂直的法向量到面板

    1, 5, 5, Vector3::UNIT_Z);//2D纹理坐标设置的数量,u,v方向重复的瓦片的数量,纹理方向

Ogre::Entity*pEnt = mSceneMgr->createEntity("plane1","plane");

mSceneMgr->getRootSceneNode()->createChildSceneNode("plane1")->attachObject(pEnt);

pEnt->setMaterialName("Examples/BeachStones");

 

//创建灯光1,点光源,点光源有位置,无方向,参与阴影计算

Ogre::Light *pLight1=mSceneMgr->createLight("Light1");

pLight1->setType(Ogre::Light::LT_POINT);//点光源

pLight1->setPosition(100, 20, 0);

pLight1->setDiffuseColour(1.0f, 1.0f, 1.0f);//漫反射颜色

 

Ogre::Entity *pLightEnt1=mSceneMgr->createEntity("sphere1","sphere.mesh");

Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");

Ogre::SceneNode *pLightNode1=pNode->createChildSceneNode("LightNode1");

pLightNode1->attachObject(pLightEnt1);

pLightNode1->setPosition(100, 20, 0);

pLightNode1->setScale(0.1f, 0.1f, 0.1f);

 

//创建灯光2,聚光灯,聚光灯有位置,有方向,参与阴影计算

Ogre::Light *pLight2=mSceneMgr->createLight("Light2");

pLight2->setType(Ogre::Light::LT_SPOTLIGHT);//聚光灯

pLight2->setPosition(0, 100, 0);//聚光灯的位置

pLight2->setDirection(Ogre::Vector3(1, -1, 0));//方向

pLight2->setSpotlightInnerAngle(Ogre::Degree(5.0f));//内角

pLight2->setSpotlightOuterAngle(Ogre::Degree(15.0f));//外角

pLight2->setSpotlightFalloff(0.0f);//衰减

pLight2->setDiffuseColour(Ogre::ColourValue(0.0f, 1.0f, 0.0f));//漫反射

 

Ogre::Entity *pLightEnt2=mSceneMgr->createEntity("sphere2","sphere.mesh");

Ogre::SceneNode *pLightNode2=pNode->createChildSceneNode("LightNode2");

pLightNode2->attachObject(pLightEnt2);//将实体关联到节点

//pLightNode2->attachObject(pLight2)将聚光灯关联到节点

pLightNode2->setPosition(0, 100, 0);//指定节点,也就是聚光灯的位置

pLightNode2->setScale(0.1f, 0.1f, 0.1f);

 

//创建灯光3,方向光,方向光没有位置,有方向,参与阴影计算

Ogre::Light *pLight3=mSceneMgr->createLight("Light3");

pLight3->setType(Ogre::Light::LT_DIRECTIONAL);//方向光

pLight3->setDiffuseColour(Ogre::ColourValue(1.0f, 0.0f, 0.0f));//漫反射

pLight3->setDirection(Ogre::Vector3(1, -1, 0));

 

//创建模型实体

Ogre::Entity *pSinbadEnt=mSceneMgr->createEntity("Sinbad1","Sinbad.mesh");

m_pSinbadNodepNode->createChildSceneNode("Sinbad1");

m_pSinbadNode->attachObject(pSinbadEnt);

m_pSinbadNode->setPosition(Ogre::Vector3(61.0f, 4.0f, 0.0f));

m_pSinbadNode->setScale(3.0, 3.0, 3.0);

 

//添加阴影

mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

}

 

void MyExampleApplication::createNewCamera()//创建相机,添加视口

{

Camera*mpNewCamera =mSceneMgr->createCamera("MyCamera1");

mpNewCamera->setPosition(0, 100, 200);

mpNewCamera->lookAt(0, 0, 0);

mpNewCamera->setNearClipDistance(5);//近距离...从圆台到近面板...

//mpNewCamera->setPolygonMode(Ogre::PM_WIREFRAME);//多线段模式,PM_WIREFRAME(线框模式)

//mpNewCamera->setPolygonMode(Ogre::PM_POINTS);   //点模式

//mpNewCamera->setPolygonMode(Ogre::PM_SOLID);    //实线模式,也是默认模式

 

//创建视口(viewport),要想添加视口不崩,必须给视口设置一个ZOrder,ZOrder全局唯一,

//当视口多余1个时,需要为每个视口指定left,top,width,height,否则ZOrder值大的会覆盖ZOrder值小的视口

 

Ogre::Viewport *pvp =mWindow->addViewport(mpNewCamera, 1, 0, 0, 0.2, 1);

pvp->setBackgroundColour(ColourValue(0.0f,0.0f, 1.0f));

mpNewCamera->setAspectRatio(Real(pvp->getActualWidth())/Real(pvp->getActualHeight()));

}

       

 5:添加一个类:MyEntityFrameListener

    MyEntityFrameListener.h

 #ifndef MyEntityFrameListener_H_

#define MyEntityFrameListener_H_

 

#include "ogre/exampleframelistener.h"

 

class MyEntityFrameListener:public ExampleFrameListener,publicOIS::KeyListener,public OIS::MouseListener

{

public:

MyEntityFrameListener(SceneNode *pSinbadNode,RenderWindow*win,Cameracambool bufferedKeys =falsebool bufferedMouse =false,boolbufferedJoyfalse);

~MyEntityFrameListener(void);

 

public:

virtualboolkeyPressed(constOIS::KeyEvent &arg);

virtualboolkeyReleased(constOIS::KeyEvent &arg);

 

virtualboolmouseMoved(constOIS::MouseEvent &arg);

virtualboolmousePressed(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

virtualboolmouseReleased(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

 

voidmoveCamera();//移动相机

virtualboolframeEnded(constFrameEvent&evt);//循环刷新界面

 

protected:

SceneNode*m_pSinbadNode;//模型实体节点

};

 

#endif

      

   MyEntityFrameListener.cpp

 #include "MyEntityFrameListener.h"

 

MyEntityFrameListener::MyEntityFrameListener(SceneNode*pSinbadNode,RenderWindow*win,Camera*cam,boolbufferedKeys,boolbufferedMouse,boolbufferedJoy)

  : ExampleFrameListener(win,cambufferedKeys,bufferedMouse,bufferedJoy),m_pSinbadNode(pSinbadNode)

{

  //启用了键鼠柄的缓冲,就能使用它们的回调函数

  mKeyboard->setEventCallback(this);

  mMouse->setEventCallback(this);

}

 

MyEntityFrameListener::~MyEntityFrameListener(void)

{

}

 

bool MyEntityFrameListener::keyPressed(constOIS::KeyEvent&arg)//键盘的键按下

{

  RealmoveScale = 0.2f;

 

  switch(arg.key){

  caseOIS::KC_A:

  caseOIS::KC_LEFT:

      mTranslateVector.x = -moveScale;//Move camera left

      break;

  caseOIS::KC_D:

  caseOIS::KC_RIGHT:

      mTranslateVector.x =moveScale//Move camera RIGHT

      break;

  caseOIS::KC_W:

  caseOIS::KC_UP:

      mTranslateVector.z = -moveScale;//Move camera forward

      break;

  caseOIS::KC_S:

  caseOIS::KC_DOWN:

      mTranslateVector.z =moveScale//Move camerabackward

      break;

  caseOIS::KC_PGUP:

      mTranslateVector.y =moveScale//Move camera up

      break;

  caseOIS::KC_PGDOWN:

      mTranslateVector.y = -moveScale;//Move camera down

      break;

  }

 

  returntrue;

}

 

bool MyEntityFrameListener::keyReleased(constOIS::KeyEvent&arg)//释放按下的键

{

  mTranslateVectorVector3::ZERO;//防止按键释放后还继续移动相机

  returntrue;

}

 

bool MyEntityFrameListener::mouseMoved(constOIS::MouseEvent&arg)

{

  constOIS::MouseState&ms =arg.state;

  if(ms.buttonDown(OIS::MB_Left)){

  } elseif(ms.buttonDown(OIS::MB_Right)) {

  } else{

      mRotXDegree(-ms.X.rel * 0.13);//转为弧度,如:Degree(180)

      mRotYDegree(-ms.Y.rel * 0.13);//转为弧度,如:Degree(180)

  }

 

  returntrue;

}

 

bool MyEntityFrameListener::mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

  returntrue;

}

 

 

bool MyEntityFrameListener::mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

  returntrue;

}

 

void MyEntityFrameListener::moveCamera() //移动相机

{

  mCamera->yaw(mRotX); //Y轴转动

  mCamera->pitch(mRotY);//X轴转动

  mCamera->moveRelative(mTranslateVector);//移动相机

 

  mRotXmRotY = 0; //防止鼠标不转动后继续转动相机

}

 

bool MyEntityFrameListener::frameEnded(constFrameEventevt)

{

  //ExampleFrameListener::frameEnded(evt);//可以不用

  

  m_pSinbadNode->translate(mTranslateVector);//模型移动

  moveCamera();//移动相机

  

  returntrue;

}

 

 6:LightCameraShadow.cpp的内容:

     #include "MyExampleApplication.h"

 

int main(){

  MyExampleApplicationapp;

  app.go();

 

  return0;

}

    

四:模型动画,走动,跳动,切换武器,攻击动画等和 相机跟踪,相机跟踪模型实体与跟踪旋转等,外带相机节点

绑定另一个模型实体,模型实体绕的是相机节点所在点转动, 而相机却是绕相机lookAt的点转动.

                                                          (程序为 游戏类编程/Ogre/Ogre1.73/ Animating)

 1:新建一个空的 win32控制台应用程序, 命名为:Animating

 2:添加一个 Animating.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyExampleApplication

    MyExampleApplication.h

 #ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include "MyEntityFrameListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

MyExampleApplication(void);

~MyExampleApplication(void);

 

public:

voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

voidcreateFrameListener(void);//创建帧监听

 

protected:

MyEntityFrameListener*m_pFrameLst;

};

 

#endif

       

   MyExampleApplication.cpp

 #include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

m_pFrameLstNULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if (NULL !=m_pFrameLst){

    mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

    deletem_pFrameLst;

    m_pFrameLstNULL;

}

}

 

void MyExampleApplication::createScene(void)

{

  mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));//设置环境光

  Light*l =mSceneMgr->createLight("mainLight");

  l->setPosition(20, 80, 50);

 

  Ogre::Vector3pst = mCamera->getPosition();

  Ogre::Quaternionort = mCamera->getOrientation();

  mCamera->setPosition(0, 100.0f, 100.0f);//设置摄像机位置

  mCamera->setOrientation(Ogre::Quaternion(0.953763f, -0.3f, -0.00865638f,-0.0027f));//设置摄像机方向

 

  mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2", 50);//设置天空盒

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(mWindow,mCameratruetruetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

       

 5:添加一个类:MyEntityFrameListener

    MyEntityFrameListener.h

 #ifndef MyEntityFrameListener_H_

#define MyEntityFrameListener_H_

 

#include "ogre/exampleframelistener.h"

using namespaceOgre;

 

class MyEntityFrameListener:public ExampleFrameListener,publicOIS::KeyListener,public OIS::MouseListener

{

public:

MyEntityFrameListener(RenderWindow*winCameracambool bufferedKeys =falsebool bufferedMouse = false,boolbufferedJoyfalse);

~MyEntityFrameListener(void);

 

public:

virtualboolkeyPressed(constOIS::KeyEvent &arg);

virtualboolkeyReleased(constOIS::KeyEvent &arg);

 

virtualboolmouseMoved(constOIS::MouseEvent &arg);

virtualboolmousePressed(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

virtualboolmouseReleased(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

 

voidmoveCamera();//移动相机

virtualboolframeEnded(constFrameEvent&evt);//循环刷新界面

 

voidcreateEntity();//创建实体

 

protected:

Entity    *m_pSinbadEnt;//模型实体

SceneNode*m_pSinbadNode;//模型节点

AnimationState*m_pAniState;//动画

 

Entity*m_pSword1;//武器剑1

Entity*m_pSword2;//武器剑2

 

RibbonTrail*m_pSwordTrail;//丝带

 

boolm_bUseSword;//默认情况下为true,即剑在手上

Realm_fUseSwordTime;//使用武器动画时长

boolm_bAttack;   //攻击动画是否启用

Realm_fAttackTime;//攻击时长

 

boolm_bJump;   //

Realm_fJumpTime;//跳动时长

 

SceneNode*m_pCameraNode;//关联相机节点

 

Vector3m_moveVector;//移动向量

};

 

#endif

       

   MyEntityFrameListener.cpp

 #include "MyEntityFrameListener.h"

 

MyEntityFrameListener::MyEntityFrameListener(RenderWindow*win,Camera*cam,bool bufferedKeys,boolbufferedMouse,boolbufferedJoy)

ExampleFrameListener(win,cambufferedKeys,bufferedMouse,bufferedJoy)

{

//启用了键鼠柄的缓冲,就能使用它们的回调函数

mKeyboard->setEventCallback(this);

mMouse->setEventCallback(this);

 

createEntity();    //创建实体

m_bAttackfalse//攻击动画不启用

m_fAttackTime= 0.0f;

 

m_bUseSwordtrue;//默认使用武器

m_fUseSwordTime= -1.0f; //防止动画重复,使用武器动画时长

 

m_bJumpfalse//默认不跳

m_fJumpTime= 0.0f;

 

m_moveVectorVector3::ZERO;

 }

 

MyEntityFrameListener::~MyEntityFrameListener(void)

{

}

 

bool MyEntityFrameListener::keyPressed(constOIS::KeyEvent&arg)//键盘的键按下

{

RealmoveScale = 0.2f;

 

switch(arg.key){

caseOIS::KC_A:

caseOIS::KC_LEFT:

   mTranslateVector.x =moveScale;//Move camera left

    break;

caseOIS::KC_D:

caseOIS::KC_RIGHT:

    mTranslateVector.x = -moveScale;//Move camera RIGHT    

    break;

caseOIS::KC_W:

caseOIS::KC_UP:

    mTranslateVector.z =moveScale;//Move camera forward

    break;

caseOIS::KC_S:

caseOIS::KC_DOWN:

    mTranslateVector.z = -moveScale;//Move camera backward

    break;

caseOIS::KC_PGUP:

    mTranslateVector.y =moveScale//Move camera up

    break;

caseOIS::KC_PGDOWN:

    mTranslateVector.y = -moveScale;//Move camera down

    break;

case  OIS::KC_E//使用武器

    {

       m_fUseSwordTime= 0.0f;

       if(m_bUseSword){//将武器放到背上

           m_bUseSwordfalse;

       } else//将武器放到手上

           m_bUseSwordtrue;

       }

    }

    break;

caseOIS::KC_SPACE://跳动

    m_bJumptrue;

    break;

}

 

if(0 != mTranslateVector.x || 0 != mTranslateVector.z){ //走动

    m_pAniStatem_pSinbadEnt->getAnimationState("RunBase");

    m_pAniState->setEnabled(true);

 

    m_pAniStatem_pSinbadEnt->getAnimationState("RunTop");

    m_pAniState->setEnabled(true);

}

 

returntrue;

}

 

bool MyEntityFrameListener::keyReleased(constOIS::KeyEvent&arg)//释放按下的键

{

RealmoveScale = 0.2f;

 

switch(arg.key){

caseOIS::KC_A:

caseOIS::KC_LEFT:

caseOIS::KC_D:

caseOIS::KC_RIGHT:

    mTranslateVector.x = 0.0f;

    break;

caseOIS::KC_W:

caseOIS::KC_UP:

caseOIS::KC_S:

caseOIS::KC_DOWN:

    mTranslateVector.z = 0.0f;

    break;

caseOIS::KC_PGUP:

caseOIS::KC_PGDOWN:

    mTranslateVector.y = 0.0f;

    break;

caseOIS::KC_SPACE://停止跳动

    m_bJumpfalse;

    break;

}

 

if(0 == mTranslateVector.x && 0 == mTranslateVector.z){ //停止走动

    m_pAniStatem_pSinbadEnt->getAnimationState("RunBase");

    m_pAniState->setEnabled(false);

 

    m_pAniStatem_pSinbadEnt->getAnimationState("RunTop");

    m_pAniState->setEnabled(false);

}

 

returntrue;

}

 

bool MyEntityFrameListener::mouseMoved(constOIS::MouseEvent&arg)

{

constOIS::MouseState&ms =arg.state;

if(ms.buttonDown(OIS::MB_Left)){

elseif(ms.buttonDown(OIS::MB_Right)) {

else{

    mRotXDegree(-ms.Y.rel * 0.13);//转为度数,如:Degree(180)

    mRotYDegree(-ms.X.rel * 0.13);//转为度数,如:Degree(180)

}

 

returntrue;

}

 

bool MyEntityFrameListener::mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

m_bAttacktrue;//开始攻击

returntrue;

}

 

bool MyEntityFrameListener::mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

m_bAttackfalse;//停止攻击

returntrue;

}

 

void MyEntityFrameListener::moveCamera() //移动相机

{

m_pSinbadNode->yaw(mRotY);//模型实体节点绕自身Y轴转动

 

m_pCameraNode->yaw(mRotY,Node::TS_WORLD);//m_pCameraNode节点绑定的相机会绕着m_pSinbadNode节点所在点转,但是

      //m_pCameraNode节点是绕着自己所在的点转,而不是m_pSinbadNode节点所在的点

m_pCameraNode->pitch(mRotX);

 

mRotXmRotY = Radian(0);//防止鼠标不转动后继续转动相机

}

 

bool MyEntityFrameListener::frameEnded(constFrameEventevt)

{

// *******************************换武器动画

m_pAniStatem_pSinbadEnt->getAnimationState("DrawSwords");

if(0.0f== m_fUseSwordTime){ //只要m_fUseSwordTime时间为0,就表示要切换武器

    m_pAniState->setEnabled(true);

}

if(0.0f<= m_fUseSwordTime && m_fUseSwordTime <= m_pAniState->getLength()){ //值在0.0f与动画时长之间,就运行动画,一个完整的动画

    m_pAniState->addTime(evt.timeSinceLastFrame);

    m_fUseSwordTime+= evt.timeSinceLastFrame;

}

if (m_fUseSwordTime >=m_pAniState->getLength()){//动画结束

m_pAniState->setEnabled(false);

    m_fUseSwordTime= -1.0f; //防止动画重复

 

    m_pSinbadEnt->detachAllObjectsFromBone();

    if(m_bUseSword){//使用武器

       m_pSinbadEnt->attachObjectToBone("Handle.L",m_pSword1);

       m_pSinbadEnt->attachObjectToBone("Handle.R",m_pSword2);

    } else//卸载武器

       m_pSinbadEnt->attachObjectToBone("Sheath.L",m_pSword1);

       m_pSinbadEnt->attachObjectToBone("Sheath.R",m_pSword2);

    }

}

//*******************************走动动画

if(0!= mTranslateVector.x|| 0 != mTranslateVector.z){

    m_pAniStatem_pSinbadEnt->getAnimationState("RunBase");

    m_pAniState->addTime(evt.timeSinceLastFrame);

 

    m_pAniStatem_pSinbadEnt->getAnimationState("RunTop");

    m_pAniState->addTime(evt.timeSinceLastFrame);

}

 

//*********************************攻击动画

if(0.0f== m_fAttackTime && m_bAttack){ //攻击开始

    m_pAniStatem_pSinbadEnt->getAnimationState("SliceVertical");

    m_pAniState->setEnabled(true);    

 

    m_pAniStatem_pSinbadEnt->getAnimationState("SliceHorizontal");

    m_pAniState->setEnabled(true);

 

    m_fAttackTimeevt.timeSinceLastFrame;

}

m_pAniStatem_pSinbadEnt->getAnimationState("SliceVertical");

if (m_pAniState->getLength()>m_fAttackTime && 0.0f < m_fAttackTime){ //一个完整的攻击

    m_pAniState->addTime(evt.timeSinceLastFrame);

 

    m_pAniStatem_pSinbadEnt->getAnimationState("SliceHorizontal");

    m_pAniState->addTime(evt.timeSinceLastFrame);

 

    m_fAttackTime+= evt.timeSinceLastFrame;

else{

    if(!m_bAttack && 0 !=m_fAttackTime){//停止攻击

       m_pAniStatem_pSinbadEnt->getAnimationState("SliceVertical");

        m_pAniState->setEnabled(false);

 

       m_pAniStatem_pSinbadEnt->getAnimationState("SliceHorizontal");

       m_pAniState->setEnabled(false);

 

       m_fAttackTime= 0.0f;

    } elseif(m_bAttack  && 0 !=m_fAttackTime){//重复攻击

       m_fAttackTimeevt.timeSinceLastFrame;

    }

}

 

//************************************************跳动

if(m_bJump && 0.0f ==m_fJumpTime){ //跳动开始

    m_pAniStatem_pSinbadEnt->getAnimationState("JumpLoop");

    m_pAniState->setEnabled(true);

 

    m_fJumpTimeevt.timeSinceLastFrame;

}

 

m_pAniStatem_pSinbadEnt->getAnimationState("JumpLoop");

if(m_pAniState->getLength()>m_fJumpTime && 0.0f < m_fJumpTime){ //一个完整的跳动

    m_pAniState->addTime(evt.timeSinceLastFrame);

 

    m_fJumpTime+= evt.timeSinceLastFrame;

 

    m_pSinbadNode->setPosition(m_pSinbadNode->getPosition() +Vector3(0.0f,m_fJumpTime/5, 0.0f));

else//模型实体下降,停止跳动

    if(0< m_pSinbadNode->getPosition().y){

       m_pSinbadNode->setPosition(m_pSinbadNode->getPosition() +Vector3(0.0f,-m_fJumpTime, 0.0f));

 

       m_pAniStatem_pSinbadEnt->getAnimationState("JumpLoop");

       m_pAniState->setEnabled(false);

    } else{

       m_pSinbadNode->setPosition(m_pSinbadNode->getPosition()*Vector3(1.0f,0.0f, 1.0f));

       m_fJumpTime= 0.0f;

    }

}

   

//****************走动

if(Vector3::ZERO!=mTranslateVector){ //有走动

    m_moveVectorVector3::ZERO;

    m_moveVector+= mTranslateVector.x*m_pSinbadNode->getOrientation().xAxis();//x方向的走动

    m_moveVector+= mTranslateVector.z*m_pSinbadNode->getOrientation().zAxis();//z方向的走动

    m_moveVector.y = 0.0f;

 

    m_pSinbadNode->translate(m_moveVector);

    m_pCameraNode->translate(m_moveVector);

}

 

moveCamera();//转动相机

 

returntrue;

}

 

void MyEntityFrameListener::createEntity()

{

//创建地面

Planeplane(Vector3::UNIT_Y, -15);//通过法向量与恒定数创建一个Plane

MeshManager::getSingleton().createPlane("GrassPlane",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,

    1500, 1500,//宽度,高度

    200, 200,  //x方向段值,y方向段值,即面板分成多少个三角形

    true,      //创建一个垂直的法向量到面板

    1, 5, 5, Vector3::UNIT_Z);//2D纹理坐标设置的数量,u,v方向重复的瓦片的数量,纹理方向

Entity*pEnt =mCamera->getSceneManager()->createEntity("GrassPlane","GrassPlane");

mCamera->getSceneManager()->getRootSceneNode()->createChildSceneNode("GrassPlane")->attachObject(pEnt);

pEnt->setMaterialName("Examples/BeachStones");//设置材质 Examples/GrassFloor

 

//添加阴影

mCamera->getSceneManager()->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

 

//创建模型实体

m_pSinbadEntmCamera->getSceneManager()->createEntity("Sinbad1","Sinbad.mesh");

m_pSinbadNodemCamera->getSceneManager()->getRootSceneNode()->createChildSceneNode("Sinbad1");

m_pSinbadNode->attachObject(m_pSinbadEnt);

m_pSinbadNode->setPosition(Vector3(500.0f,0.0f, 0.0f));//模型实体位置

m_pSinbadNode->setScale(3.0, 3.0, 3.0);

m_pSinbadEnt->getSkeleton()->setBlendMode(ANIMBLEND_CUMULATIVE);//骨架混合模式

 

//添加武器

m_pSword1mCamera->getSceneManager()->createEntity("Sword1","Sword.mesh");

m_pSword2mCamera->getSceneManager()->createEntity("Sword2","Sword.mesh");

m_pSinbadEnt->attachObjectToBone("Handle.L",m_pSword1);//将剑实体关联到骨骼

m_pSinbadEnt->attachObjectToBone("Handle.R",m_pSword2);//将剑实体关联到骨骼

 

//创建丝带

NameValuePairListparams;

params["numberOfChains"] ="2";

params["maxElements"] ="80";

m_pSwordTrail= (RibbonTrail*)mCamera->getSceneManager()->createMovableObject("RibbonTrail", &params);

m_pSwordTrail->setMaterialName("Examples/LightRibbonTrail");

m_pSwordTrail->setTrailLength(20);

mCamera->getSceneManager()->getRootSceneNode()->attachObject(m_pSwordTrail);//将丝带关联到Root节点

 

for(inti = 0; i < 2;i++){

    m_pSwordTrail->setInitialColour(i,1, 0.8, 0);

    m_pSwordTrail->setColourChange(i,0.75, 1.25, 1.25, 1.25);

    m_pSwordTrail->setWidthChange(i,1);

    m_pSwordTrail->setInitialWidth(i,0.5);

}

 

m_pSwordTrail->setVisible(true);

m_pSwordTrail->addNode(m_pSword1->getParentNode());

m_pSwordTrail->addNode(m_pSword2->getParentNode());

 

//迭代所有动画

AnimationStateSet*pAnimSet =m_pSinbadEnt->getAllAnimationStates();

AnimationStateIteratoranimIter =pAnimSet->getAnimationStateIterator();

while(animIter.hasMoreElements()){

    //std::cout<< animIter.getNext()->getAnimationName() << std::endl;

    //animIter.getNext()->setLoop(true);

    m_pAniStatepAnimSet->getAnimationState(animIter.getNext()->getAnimationName());

    m_pAniState->setLoop(true);    

}

m_pAniStatem_pSinbadEnt->getAnimationState("HandsClosed");

m_pAniState->setEnabled(true);

 

// **创建关联相机的节点

//确定相机节点位置,相机节点位置不是相机的位置

Vector3vPos =m_pSinbadNode->getPosition();

RealfRadius =m_pSinbadEnt->getBoundingRadius();

Vector3cameraNodePos(vPos.x,vPos.yvPos.z-fRadius);//相机节点位置在模型实体后面

 

m_pCameraNodemCamera->getSceneManager()->getRootSceneNode()->createChildSceneNode("myCameraNode");

m_pCameraNode->attachObject(mCamera);    //相机节点绑定相机

m_pCameraNode->setPosition(cameraNodePos);//相机节点位置

m_pCameraNode->lookAt(vPos,Node::TS_WORLD);//相机节点看的位置,要使相机能绕m_pSinbadNode节点转,必须在

                 //此设置lookAt,但是此m_pCameraNode节点还是绕着自己所在点转

m_pCameraNode->setFixedYawAxis(true);

mCamera->setFixedYawAxis(true);

 

//关联的实体在自己所处点转动,而相机绕着主实体运动

Entity*pSinbadEnt111 =mCamera->getSceneManager()->createEntity("Sinbad12122","Sinbad.mesh");

pSinbadEnt111->setMaterialName("drbunsen_head");

m_pCameraNode->attachObject(pSinbadEnt111);

}

       

 6:Animating.cpp的内容:

 #include "MyExampleApplication.h"

 

int main(){

MyExampleApplication app;

 app.go();

 

 return 0;

}

       

五:场景管理,创建一个与默认场景管理不同的管理,创建平板和实体,创建一个手工对象实体草叶等,使用三角形类型

创建实体,使用点索引构成三角形创建实体,使用静态几何类添加实体,  载入地图等.

(程序为游戏类编程/Ogre/Ogre1.73/SceneManagers)

 1:新建一个空的 win32控制台应用程序,命名为:SceneManagers

 2:添加一个 SceneManagers.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyEntityFrameListener

    MyEntityFrameListener.h

 #ifndef MyEntityFrameListener_H_

#define MyEntityFrameListener_H_

 

#include "ogre/exampleframelistener.h"

 

class MyEntityFrameListener:public ExampleFrameListener,publicOIS::KeyListener,public OIS::MouseListener

{

public

  MyEntityFrameListener(RenderWindow*winCameracambool bufferedKeys =falsebool bufferedMouse = false,boolbufferedJoyfalse);

  ~MyEntityFrameListener(void);

 

public:

  virtualboolkeyPressed(constOIS::KeyEvent &arg);

  virtualboolkeyReleased(constOIS::KeyEvent &arg);

 

  virtualboolmouseMoved(constOIS::MouseEvent &arg);

  virtualboolmousePressed(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

  virtualboolmouseReleased(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

 

  voidmoveCamera();//移动相机

  virtualboolframeEnded(constFrameEvent&evt);//循环刷新界面

};

 

#endif

     

   MyEntityFrameListener.cpp

 #include "MyEntityFrameListener.h"

 

MyEntityFrameListener::MyEntityFrameListener(RenderWindow*win,Camera*cam,bool bufferedKeys,boolbufferedMouse,boolbufferedJoy)

ExampleFrameListener(win,cambufferedKeys,bufferedMouse,bufferedJoy)

{

//启用了键鼠柄的缓冲,就能使用它们的回调函数

mKeyboard->setEventCallback(this);

mMouse->setEventCallback(this);

}

 

MyEntityFrameListener::~MyEntityFrameListener(void)

{

}

 

bool MyEntityFrameListener::keyPressed(constOIS::KeyEvent&arg)//键盘的键按下

{

RealmoveScale = 0.2f;

 

switch(arg.key){

caseOIS::KC_A:

caseOIS::KC_LEFT:

    mTranslateVector.x = -moveScale;//Move camera left

    break;

caseOIS::KC_D:

caseOIS::KC_RIGHT:

    mTranslateVector.x =moveScale//Move camera RIGHT

    break;

caseOIS::KC_W:

caseOIS::KC_UP:

    mTranslateVector.z = -moveScale;//Move camera forward

    break;

caseOIS::KC_S:

caseOIS::KC_DOWN:

    mTranslateVector.z =moveScale//Move camerabackward

    break;

caseOIS::KC_PGUP:

    mTranslateVector.y =moveScale//Move camera up

    break;

caseOIS::KC_PGDOWN:

    mTranslateVector.y = -moveScale;//Move camera down

    break;

}

 

returntrue;

}

 

bool MyEntityFrameListener::keyReleased(constOIS::KeyEvent&arg)//释放按下的键

{

mTranslateVectorVector3::ZERO;//防止按键释放后还继续移动相机

returntrue;

}

 

bool MyEntityFrameListener::mouseMoved(constOIS::MouseEvent&arg)

{

constOIS::MouseState&ms =arg.state;

if(ms.buttonDown(OIS::MB_Left)){

elseif(ms.buttonDown(OIS::MB_Right)) {

else{

    mRotXDegree(-ms.X.rel * 0.13);//转为弧度,如:Degree(180)

    mRotYDegree(-ms.Y.rel * 0.13);//转为弧度,如:Degree(180)

}

 

returntrue;

}

 

bool MyEntityFrameListener::mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

returntrue;

}

 

bool MyEntityFrameListener::mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

returntrue;

}

 

void MyEntityFrameListener::moveCamera() //移动相机

{

mCamera->yaw(mRotX);  //Y轴转动

mCamera->pitch(mRotY);//X轴转动

mCamera->moveRelative(mTranslateVector);//移动相机

 

mRotXmRotY = 0; //防止鼠标不转动后继续转动相机

}

 

bool MyEntityFrameListener::frameEnded(constFrameEventevt)

{

//ExampleFrameListener::frameEnded(evt);//可以不用

moveCamera();//移动相机

 

returntrue;

}

       

 5:添加一个类:MyExampleApplication

    MyExampleApplication.h

 #ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include "MyEntityFrameListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

MyExampleApplication(void);

~MyExampleApplication(void);

 

public:

voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

voidcreateFrameListener(void);//创建帧监听

 

virtualvoidchooseSceneManager(void);//创建一个与默认场景管理不同的管理

 

voidcreatePlaneAndEntity();//创建平板和实体,创建一个手工对象实体草叶等

voidcreateEntity1();//使用三角形类型创建实体

voidcreateEntity2();//使用点索引构成三角形创建实体,使用静态几何类添加实体.

 

private:

MyEntityFrameListener*m_pFrameLst;

};

 

#endif

       

    MyExampleApplication.cpp

#include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

m_pFrameLstNULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if (NULL !=m_pFrameLst){

    mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

    deletem_pFrameLst;

    m_pFrameLstNULL;

}

}

 

void MyExampleApplication::createScene(void)

{

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));//设置环境光

Light*l =mSceneMgr->createLight("mainLight");

l->setPosition(20, 80, 50);

 

Ogre::Vector3pst = mCamera->getPosition();

Ogre::QuaternionortmCamera->getOrientation();

mCamera->setPosition(0, 100.0f, 100.0f);//设置摄像机位置

mCamera->setOrientation(Ogre::Quaternion(0.953763f, -0.3f, -0.00865638f,-0.0027f));//设置摄像机方向

 

mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2", 50);//设置天空盒

 

std::cout <<mSceneMgr->getTypeName() <<"::"<< mSceneMgr->getName() <<std::endl;

//打印出场景管理类型名称和场景名称

 

createPlaneAndEntity();//创建平板和实体,创建一个手工对象实体草叶等

createEntity1();//使用三角形类型创建实体

createEntity2();//使用点索引构成三角形创建实体,使用静态几何类添加实体

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(mWindow,mCamera,truetruetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

 

void MyExampleApplication::chooseSceneManager(void)//创建一个与默认场景管理不同的管理,BspSceneManager

{

//ResourceGroupManager::getSingleton().addResourceLocation("media/packs/Sinbad.zip","Zip", "Popular");

//ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

constStringresGroupNameResourceGroupManager::getSingleton().getWorldResourceGroupName();

ResourceGroupManager::getSingleton().addResourceLocation("media/packs/chiropteraDM.pk3","Zip",ResourceGroupManager::getSingleton().getWorldResourceGroupName(),true);

ResourceGroupManager::getSingleton().initialiseResourceGroup(ResourceGroupManager::getSingleton().getWorldResourceGroupName());

mSceneMgrmRoot->createSceneManager("BspSceneManager");//默认为:mRoot->createSceneManager(ST_GENERIC,"ExampleSMInstance");

mSceneMgr->setWorldGeometry("maps/chiropteradm.bsp");   //载入地图

}

 

void MyExampleApplication::createPlaneAndEntity()//创建平板和实体,创建一个手工对象实体草叶等

{

//创建plane(面板)

Ogre::Planeplane(Vector3::UNIT_Y,-10);//通过法向量与恒定数创建一个Plane

Ogre::MeshManager::getSingleton().createPlane("GrassPlane",ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,plane,

    1500, 1500,//宽度,高度

    200, 200,  //x方向段值,y方向段值,即面板分成多少个三角形

    true,      //创建一个垂直的法向量到面板

    1, 5, 5, Vector3::UNIT_Z);//2D纹理坐标设置的数量,u,v方向重复的瓦片的数量,纹理方向

 

Ogre::Entity*pEnt = mSceneMgr->createEntity("GrassPlane","GrassPlane");

mSceneMgr->getRootSceneNode()->createChildSceneNode("GrassPlane")->attachObject(pEnt);

pEnt->setMaterialName("Examples/BeachStones");//设置材质 Examples/GrassFloor

}

 

void MyExampleApplication::createEntity1()//使用三角形类型创建实体

{

Ogre::ManualObject *pManual=mSceneMgr->createManualObject("GrassBlades1");//创建一个手工对象草叶

pManual->begin("Examples/GrassBlades",RenderOperation::OT_TRIANGLE_LIST);//三角类型

 

//添加第一个三角形

pManual->position(5.0, 0.0, 0.0);

pManual->textureCoord(1,1);

pManual->position(-5.0, 10.0, 0.0);

pManual->textureCoord(0,0);

pManual->position(-5.0, 0.0, 0.0);

pManual->textureCoord(0,1);

 

//添加第二个三角形

pManual->position(5.0, 0.0, 0.0);

pManual->textureCoord(1,1);

pManual->position(5.0, 10.0, 0.0);

pManual->textureCoord(1,0);

pManual->position(-5.0, 10.0, 0.0);

pManual->textureCoord(0,0);

 

//添加第三个三角形

pManual->position(2.5, 0.0, 4.3);

pManual->textureCoord(1,1);

pManual->position(-2.5, 10.0, -4.3);

pManual->textureCoord(0,0);

pManual->position(-2.0, 0.0, -4.3);

pManual->textureCoord(0,1);

 

//添加第四个三角形

pManual->position(2.5, 0.0, 4.3);

pManual->textureCoord(1,1);

pManual->position(2.5, 10.0, 4.3);

pManual->textureCoord(1,0);

pManual->position(-2.5, 10.0, -4.3);

pManual->textureCoord(0,0);

 

//添加第五个三角形

pManual->position(2.5, 0.0, -4.3);

pManual->textureCoord(1,1);

pManual->position(-2.5, 10.0, 4.3);

pManual->textureCoord(0,0);

pManual->position(-2.0, 0.0, 4.3);

pManual->textureCoord(0,1);

 

//添加第六个三角形

pManual->position(2.5, 0.0, -4.3);

pManual->textureCoord(1,1);

pManual->position(2.5, 10.0, -4.3);

pManual->textureCoord(1,0);

pManual->position(-2.5, 10.0, 4.3);

pManual->textureCoord(0,0);

 

pManual->end();

 

//Ogre::SceneNode*pGrassNode =mSceneMgr->getRootSceneNode()->createChildSceneNode("GrassBlades");

//pGrassNode->attachObject(pManual);

 

pManual->convertToMesh("BladesOfGrass1");//将一个手工对象转为网格

for(inti=0; i<20; i++){

    for(intj=0; j<20; j++){

       Ogre::Entity *pEnt =mSceneMgr->createEntity("BladesOfGrass1");//通过转换的网格创建实体

       Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(i*3,-10,j*3));

        pNode->attachObject(pEnt);

    }

}

}

 

void MyExampleApplication::createEntity2()//使用点索引构成三角形创建实体,使用静态几何类添加实体.

{

Ogre::ManualObject *pManual=mSceneMgr->createManualObject("GrassBlades2");//创建一个手工对象草叶

pManual->begin("Examples/GrassBlades",RenderOperation::OT_TRIANGLE_LIST);//三角类型

 

pManual->position(5.0, 0.0, 0.0);

pManual->textureCoord(1,1);

pManual->position(-5.0, 10.0, 0.0);

pManual->textureCoord(0,0);

pManual->position(-5.0, 0.0, 0.0);

pManual->textureCoord(0,1);

 

pManual->position(5.0, 10.0, 0.0);

pManual->textureCoord(1,0);

pManual->position(2.5, 0.0, 4.3);

pManual->textureCoord(1,1);

pManual->position(-2.5, 10.0, -4.3);

pManual->textureCoord(0,0);

 

pManual->position(-2.0, 0.0, -4.3);

pManual->textureCoord(0,1);

pManual->position(2.5, 10.0, 4.3);

pManual->textureCoord(1,0);

pManual->position(2.5, 0.0, -4.3);

pManual->textureCoord(1,1);

 

pManual->position(-2.5, 10.0, 4.3);

pManual->textureCoord(0,0);

pManual->position(-2.0, 0.0, 4.3);

pManual->textureCoord(0,1);

pManual->position(2.5, 10.0, -4.3);

pManual->textureCoord(1,0);

 

pManual->index(0);

pManual->index(1);

pManual->index(2);

pManual->index(0);

pManual->index(3);

pManual->index(1);

 

pManual->index(4);

pManual->index(5);

pManual->index(6);

pManual->index(4);

pManual->index(7);

pManual->index(5);

pManual->index(8);

pManual->index(9);

pManual->index(10);

pManual->index(8);

pManual->index(11);

pManual->index(9);

 

pManual->end();

 

//Ogre::SceneNode*pGrassNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("GrassBlades");

//pGrassNode->attachObject(pManual);

 

pManual->convertToMesh("BladesOfGrass2");//将一个手工对象转为网格

Ogre::StaticGeometry *pField=mSceneMgr->createStaticGeometry("FieldOfGrass");//静态几何类

for(inti=30;i<50;i++){

    for(intj=30;j<50;j++){

       Ogre::Entity *pEnt =mSceneMgr->createEntity("BladesOfGrass2");

       pField->addEntity(pEnt,Ogre::Vector3(i*3,-10,j*3));

    }

}

pField->build();

}

       

 6:SceneManagers.cpp的内容:

 #include "MyExampleApplication.h"

 

int main(){

  MyExampleApplicationapp;

  app.go();

  

  return0;

}

       

六:材质 (程序为游戏类编程/Ogre/Ogre1.73/Materials)

1:新建一个空的 win32控制台应用程序,命名为:Materials

 2:添加一个 Materials.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyEntityFrameListener,内容与 五 中的MyEntityFrameListener一致

 5:添加一个类:MyExampleApplication

    MyExampleApplication.h

 #ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include "MyEntityFrameListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

MyExampleApplication(void);

~MyExampleApplication(void);

 

public:

voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

voidcreateFrameListener(void);//创建帧监听

 

voidcreateManual();//重复纹理,边缘纹理,边框纹理,镜像纹理,滚动纹理

voidcreateManual1();//旋转纹理

 

voidcreateShader1();//纹理着色

voidcreateShader2();//颜色着色

 

voidsetEntMaterial();//给实体设置自定义的材质

 

private:

MyEntityFrameListener*m_pFrameLst;

};

 

#endif

 

   MyExampleApplication.cpp

 #include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

m_pFrameLstNULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if (NULL !=m_pFrameLst){

    mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

    deletem_pFrameLst;

    m_pFrameLstNULL;

}

}

 

void MyExampleApplication::createScene(void)

{

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));//设置环境光

Light*l =mSceneMgr->createLight("mainLight");

l->setPosition(20, 80, 50);

 

Ogre::Vector3pst = mCamera->getPosition();

Ogre::QuaternionortmCamera->getOrientation();

mCamera->setPosition(0, 100.0f, 100.0f);//设置摄像机位置

mCamera->setOrientation(Ogre::Quaternion(0.953763f, -0.3f, -0.00865638f,-0.0027f));//设置摄像机方向

 

//mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2", 50);//设置天空盒

 

//createManual();//重复纹理,边缘纹理,边框纹理,镜像纹理,滚动纹理

//createManual1();//旋转纹理

 

//createShader1();//纹理着色

//createShader2();//颜色着色

 

setEntMaterial();//给实体设置自定义的材质

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(mWindow,mCamera,truetruetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

 

void MyExampleApplication::createManual()//重复纹理,边缘纹理,边框纹理,镜像纹理,滚动纹理

{

Ogre::ManualObject *pManual=mSceneMgr->createManualObject("Quad");

pManual->begin("myMaterial5",RenderOperation::OT_TRIANGLE_LIST);//BaseWhiteNoLighting

 

/*

//构造四个点,以及四个点的纹理,用于重复纹理,边缘纹理,边框纹理,镜像纹理,纹理坐标大于1,2

pManual->position(5.0,0.0, 0.0);

pManual->textureCoord(0,2);

pManual->position(-5.0,10.0, 0.0);

pManual->textureCoord(2,0);

pManual->position(-5.0,0.0, 0.0);

pManual->textureCoord(2,2);

pManual->position(5.0,10.0, 0.0);

pManual->textureCoord(0,0);

*/

 

//纹理坐标小于1块纹理,用于滚动纹理

pManual->position(5.0, 0.0, 0.0);

pManual->textureCoord(0,0.2);

pManual->position(-5.0, 10.0, 0.0);

pManual->textureCoord(0.2,0);

pManual->position(-5.0, 0.0, 0.0);

pManual->textureCoord(0.2,0.2);

pManual->position(5.0, 10.0, 0.0);

pManual->textureCoord(0,0);

 

//通过点索引构造两个三角形

pManual->index(0);

pManual->index(1);

pManual->index(2);

pManual->index(0);

pManual->index(3);

pManual->index(1);

 

pManual->end();

pManual->convertToMesh("Quad");//将手工对象转为Mesh

 

//通过Mesh创建实体

Ogre::Entity *pEnt =mSceneMgr->createEntity("Quad");

Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");

pNode->attachObject(pEnt);

}

 

void MyExampleApplication::createManual1()//旋转纹理

{

Ogre::ManualObject *pManual=mSceneMgr->createManualObject("Quad");

pManual->begin("myMaterial6",RenderOperation::OT_TRIANGLE_LIST);

 

pManual->position(5.0, 0.0, 0.0);

pManual->textureCoord(0,1);

pManual->position(-5.0, 10.0, 0.0);

pManual->textureCoord(1,0);

pManual->position(-5.0, 0.0, 0.0);

pManual->textureCoord(1,1);

pManual->position(5.0, 10.0, 0.0);

pManual->textureCoord(0,0);

 

pManual->index(0);

pManual->index(1);

pManual->index(2);

pManual->index(0);

pManual->index(3);

pManual->index(1);

 

pManual->end();

pManual->convertToMesh("Quad");

 

Ogre::Entity *pEnt =mSceneMgr->createEntity("Quad");

//pEnt->setMaterialName("myMaterial7");

Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");

pNode->attachObject(pEnt);

}

 

void MyExampleApplication::createShader1() //纹理着色

{

Ogre::ManualObject *pManual=mSceneMgr->createManualObject("Quad");

pManual->begin("myMaterial9",RenderOperation::OT_TRIANGLE_LIST);

 

pManual->position(5.0, 0.0, 0.0);

pManual->textureCoord(0,1);//纹理坐标

pManual->position(-5.0, 10.0, 0.0);

pManual->textureCoord(1,0);

pManual->position(-5.0, 0.0, 0.0);

pManual->textureCoord(1,1);

pManual->position(5.0, 10.0, 0.0);

pManual->textureCoord(0,0);

 

pManual->index(0);

pManual->index(1);

pManual->index(2);

pManual->index(0);

pManual->index(3);

pManual->index(1);

 

pManual->end();

pManual->convertToMesh("Quad");

 

Ogre::Entity *pEnt =mSceneMgr->createEntity("Quad");

Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");

pNode->attachObject(pEnt);

}

 

void MyExampleApplication::createShader2()//颜色着色

{

Ogre::ManualObject *pManual=mSceneMgr->createManualObject("Quad");

pManual->begin("myMaterial10",RenderOperation::OT_TRIANGLE_LIST);

 

pManual->position(5.0, 0.0, 0.0);

pManual->colour(0, 0, 1);

pManual->position(-5.0, 10.0, 0.0);

pManual->colour(0, 1, 0);

pManual->position(-5.0, 0.0, 0.0);

pManual->colour(0, 1, 0);

pManual->position(5.0, 10.0, 0.0);

pManual->colour(0, 0, 1);

 

pManual->index(0);

pManual->index(1);

pManual->index(2);

pManual->index(0);

pManual->index(3);

pManual->index(1);

 

pManual->end();

pManual->convertToMesh("Quad");

 

Ogre::Entity *pEnt =mSceneMgr->createEntity("Quad");

Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");

pNode->attachObject(pEnt);

}

 

void MyExampleApplication::setEntMaterial()//给实体设置自定义的材质

{

Ogre::Entity *pEnt =mSceneMgr->createEntity("Entity1","Sinbad.mesh");

pEnt->setMaterialName("myMaterial11");

Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");

 

pNode->attachObject(pEnt);

pNode->scale(6.0, 6.0, 6.0);

}

 

//myMaterial.material, Ogre3DBeginnersGuideShaders.cg

       

 6:myMaterial.material的内容:

//材质

 

//给材质命名

material myMaterial

{

  //技术

  technique

  {

    //通道

    pass

    {

      //关闭灯光

      lighting off

      //场景混合,alpha混合

      scene_blend alpha_blend

      depth_write off

      //漫反射顶点颜色

      diffuse vertexcolor

     

      texture_unit

      {

        texture terr_rock6.jpg//leaf.png

        tex_address_mode clamp

      }

    }

  }

}

 

/*四块纹理,用于重复纹理,边缘纹理,边框纹理,镜像纹理,纹理坐标大于1,为2

textureCoord(0,2);

textureCoord(2,0);

textureCoord(2,2);

textureCoord(0,0);

*/

//在大于1块纹理时,多余的纹理部分,重复模式纹理(重复绘制纹理)

material myMaterial1

{

  technique

  {

    pass

    {

      texture_unit

      {

        texture leaf.png

      }

    }

  }

}

 

//在大于1块纹理时,多余的纹理部分,材质不拉伸,材质边缘延伸填充

material myMaterial2

{

  technique

  {

    pass

    {

      texture_unit

      {

        texture terr_rock6.jpg

        //材质不拉伸,材质边缘延伸填充

        tex_address_mode clamp

      }

    }

  }

}

 

//在大于1块纹理时,多余的纹理部分由纹理边框产生

material myMaterial3

{

  technique

  {

    pass

    {

      texture_unit

      {

        texture leaf.png

        //边框模式,多余的纹理部分由边框产生

        tex_address_modeborder

        tex_border_colour 1.00.0 0.0

      }

    }

  }

}

 

//在大于1块纹理时,多余的纹理部分,镜像产生

material myMaterial4

{

  technique

  {

    pass

    {

      texture_unit

      {

        texture leaf.png

        //镜像模式

        tex_address_modemirror

      }

    }

  }

}

 

/*纹理坐标小于1块纹理,用于滚动纹理

textureCoord(0,0.2);

textureCoord(0.2,0);

textureCoord(0.2,0.2);

textureCoord(0,0);

*/

//滚动纹理

material myMaterial5

{

  technique

  {

    pass

    {

      texture_unit

      {

        texture leaf.png

        scroll  0.8 0.8

        scroll_anim 0.1 0.1

      }

    }

  }

}

 

/*

textureCoord(0,1);

textureCoord(1,0);

textureCoord(1,1);

textureCoord(0,0);

*/

//旋转纹理

material myMaterial6

{

  technique

  {

    pass

    {

      texture_unit

      {

        texture leaf.png

        rotate_anim 0.1

      }

    }

  }

}

 

//材质可以继承,继承上一期纹理的滚动属性

material myMaterial7 : myMaterial6

{

  set_texture_alias texture1Water02.jpg

}

 

 

//******************纹理着色1*************************************************//

//片段着色

fragment_program MyFragmentShader1 cg

{

  source      Ogre3DBeginnersGuideShaders.cg

  entry_pointMyFragmentShader1A

  profiles    ps_2_0 arbfp1

}

 

//顶点着色

vertex_program MyVertexShader1 cg

{

  //嵌入一段cg程序

  source  Ogre3DBeginnersGuideShaders.cg

  //指出该cg程序的入口函数,按cg标准,缺省入口为main

  entry_point MyVertexShader1A

  //D3D vs_1_1 标准,或openglarbvp1标准,Ogre自动检查是硬件是否支持

  profiles vs_2_0 arbvp1

 

  default_params

  {

    param_named_auto worldViewMatrixworldviewproj_matrix

    /**

    //下列参数为传入顶点的参数

    param_named_autoworldViewProj worldviewproj_matrix  //世界坐标矩阵

    param_named_auto ambientambient_light_colour        //环境光

    param_named_autoobjSpaceLight light_position_object_space 0 //灯的位置

    param_named_autolightColour light_diffuse_colour 0  //灯的颜色

    param_named_auto offsetcustom 999  //offset特定参数,由程序设定

    **/

  }

}

 

material myMaterial8

{

  technique

  {

    pass

    {

       vertex_program_refMyVertexShader1

       {

       }

      

       fragment_program_refMyFragmentShader1

       {

       }

      

       /*    

       alpha_rejection greater150  //alpha 使用的距离范围

       scene_blendalpha_blend      //场景混合方式为alpha

       cull_hardware none    //关闭硬件精细化

       cull_software none    //关闭软件精细化

       */

      

       //贴图

       texture_unit

       {

         texturegrass_1024.jpg

       }

    }

  }

 

  //如果显示卡不支持顶点程序,系统会选择使用下面的技术通道(普通贴图)

  technique

  {

    pass

    {

      alpha_rejection greater150

      scene_blend alpha_blend

      cull_hardware none

      cull_software none

     

      texture_unit

      {

        texture gras_02.png

      }

    }

  }

}

 

//******************纹理着色2*************************************************//

vertex_program MyVertexShader2 cg

{

  source  Ogre3DBeginnersGuideShaders.cg

  entry_point MyVertexShader2A

  profiles vs_2_0 arbvp1

 

  default_params

  {

    param_named_autoworldViewMatrix worldviewproj_matrix

  }

}

 

material myMaterial9

{

  technique

  {

    pass

    {

       vertex_program_refMyVertexShader2

       {

       }

 

       fragment_program_refMyFragmentShader1

       {

       }

 

       texture_unit

       {

         textureterr_rock6.jpg

       }

    }

  }

}

 

//******************颜色着色3*************************************************//

/**

pManual->colour(0, 0, 1);

pManual->colour(0, 1, 0);

pManual->colour(0, 1, 0);

pManual->colour(0, 0, 1);

**/

fragment_program MyFragmentShader3 cg

{

  source      Ogre3DBeginnersGuideShaders.cg

  entry_pointMyFragmentShader3A

  profiles    ps_2_0 arbfp1

}

 

vertex_program MyVertexShader3 cg

{

  source      Ogre3DBeginnersGuideShaders.cg

  entry_point MyVertexShader3A

  profiles    vs_2_0 arbvp1

 

  default_params

  {

    param_named_auto worldViewMatrixworldviewproj_matrix

  }

}

 

material myMaterial10

{

  technique

  {

    pass

    {

       vertex_program_refMyVertexShader3

       {

       }

 

       fragment_program_refMyFragmentShader3

       {

       }

    }

  }

}

 

//******************用于模型材质着色*************************************************//

fragment_program MyFragmentShader4 cg

{

  source      Ogre3DBeginnersGuideShaders.cg

  entry_pointMyFragmentShader4A

  profiles    ps_2_0 arbfp1

}

 

vertex_program MyVertexShader4 cg

{

  source      Ogre3DBeginnersGuideShaders.cg

  entry_point MyVertexShader4A

  profiles    vs_2_0 arbvp1

 

  default_params

  {

    param_named_autoworldViewMatrix worldviewproj_matrix

    //添加脉冲,系统内部变量使用param_named_auto

    param_named_auto pulseTimetime

    //自定义变量offset,前面只能用param_named

    param_named offset float40.3 0.85 0.7 1

  }

}

 

material myMaterial11

{

  technique

  {

    pass

    {

       vertex_program_refMyVertexShader4

       {

       }

      

       fragment_program_refMyFragmentShader4

       {

       }

      

       texture_unit

       {

         texture leaf.png

       }

     }

   }

}

   

 7:Ogre3DBeginnersGuideShaders.cg的内容:

//****************纹理着色1*************************************//

//***片段着色

//half4 MyFragmentShader1A() : COLOR //这个是可以的,当有无纹理时都可以使用

//{

//  half4 oColour =float4(0.0f, 0.0f, 1.0f, 0.0f);

//  return oColour;

//}

 

//void MyFragmentShader1A(out float4 color:COLOR) //这个是可以的,当有无纹理时都可以使用

//{

//  color = float4(0.0f, 0.5f,0.0f, 0.0f);

//}

 

void MyFragmentShader1A(float2 uv:TEXCOORD0, out float4 color:COLOR,uniform sampler2D texture)

{

  float4 temp_color =tex2D(texture, uv);

  color =float4(temp_color.r+0.2, temp_color.g+0.3, temp_color.b+0.7, 0);

}

//***片段着色

 

//***顶点着色

void MyVertexShader1A(float4 position : POSITION, out float4oPosition : POSITION,

                       uniformfloat4x4 worldViewMatrix)

{

  oPosition =mul(worldViewMatrix, position);

  oPosition.z += oPosition.x;

  oPosition.y += oPosition.x;

}

 

//****************纹理着色2*************************************//

void MyVertexShader2A(float4 position:POSITION, out float4oPosition:POSITION,

           float2uv:TEXCOORD0, out float2 oUv:TEXCOORD0, uniform float4x4 worldViewMatrix)

{

  oPosition = mul(worldViewMatrix,position);

  oPosition.z += oPosition.x;

  oPosition.y += oPosition.x;

 

  oUv = uv+0.1;

}

 

//******************颜色着色3*************************************************//

void MyFragmentShader3A(float4 color : COLOR, out float4 oColor :COLOR)

{

  oColor = color;

  oColor.b = 0.5;

}

 

void MyVertexShader3A(float4 position:POSITION, out float4oPosition:POSITION,

            float4color:COLOR, out float4 ocolor:COLOR, uniform float4x4 worldViewMatrix)

{

  oPosition =mul(worldViewMatrix, position);

  ocolor = color;

  ocolor.b = 0.2;

}

 

//******************用于模型材质着色*************************************************//

void MyFragmentShader4A(float2 uv:TEXCOORD0, out float4 color:COLOR,uniform sampler2D texture)

{

  float4 temp_color =tex2D(texture, uv);

  color =float4(temp_color.r+0.7, temp_color.g+0.5, temp_color.b+0.2, 0);

}

 

void MyVertexShader4A(uniform float pulseTime, float4position:POSITION, out float4 oPosition:POSITION,

                 float2uv:TEXCOORD0, out float2 oUv:TEXCOORD0, uniform float4x4 worldViewMatrix

                 ,uniformfloat4 offset)

{

  oPosition =mul(worldViewMatrix, position);

  oPosition.x *=(2+sin(pulseTime));

  oPosition *= offset;

  oUv = uv;

}

 

//******************其它程序用于计算顶点摇摆的,在此不使用,保留****************************************//

//对每个顶点计算摇摆位置及颜色

/**

void grass_vp(float4 position : POSITION,  //程序入口,参数在材料脚本确定

     float3 normal   : NORMAL,

     float2 uv    : TEXCOORD0,

     out float4 oPosition :POSITION,

     out float2 oUv    : TEXCOORD0,

     out float4 colour    : COLOR,

     uniform float4x4worldViewProj,

     uniform float4 ambient,

     uniform float4objSpaceLight,

     uniform float4lightColour,

     uniform float4 offset)

{

float4 mypos = position;    //取得点的位置

//offset = float4(0.5, 0, 0, 0);

mypos = mypos + offset * mypos.yyyy; //位置偏移随y高度线性增加

oPosition = mul(worldViewProj, mypos);   //变换为全局坐标

oUv = uv;  //贴图UV

// get vertex light direction (support directional and point)

float3 light = normalize(

  objSpaceLight.xyz -  (position.xyz * objSpaceLight.w)); //计算入射光,主要反映用于Grass场景中的动态灯光

float diffuseFactor = max(dot(normal, light), 0);  //由法线及入射光夹角,计算出反射光强度

 

colour = ambient + diffuseFactor * lightColour;   //由场景光,及反射光强及颜色,计算出最终的顶点色彩

    //这样,图形GPU将运行该CG程序,快速计算出顶点的位置及颜色及贴图坐标。

}

**/

  

七:组合材质以及视口的实现,组合材质设置参数,组合监听等

(程序为游戏类编程/Ogre/Ogre1.73/CompositorFramework)

1:新建一个空的 win32控制台应用程序,命名为:CompositorFramework

 2:添加一个 CompositorFramework.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyEntityFrameListener,内容与 五 中的MyEntityFrameListener一致

 5:添加一个 材质组合类,用于设置材质参数等:MyCompositorListener

    MyCompositorListener.h

 //材质组合监听类,组合材质仅仅针对视口使用

#ifndef _MyCompositorListener_H_

#define _MyCompositorListener_H_

 

#include <ogre/OgreCompositorInstance.h>

 

using namespaceOgre;

 

class MyCompositorListenerpublic CompositorInstance::Listener

{

public:

MyCompositorListener(void);

~MyCompositorListener(void);

 

voidnotifyMaterialSetup(uint32pass_id,MaterialPtr&mat);

//virtualvoid notifyMaterialRender(uint32 pass_id, MaterialPtr &mat);

 

protected:

int m_index;

};

 

#endif

      

   MyCompositorListener.cpp

 #include <ogre/OgreTechnique.h>

#include "MyCompositorListener.h"

 

MyCompositorListener::MyCompositorListener(void)

{

m_index= 0;

}

 

MyCompositorListener::~MyCompositorListener(void)

{

}

 

void MyCompositorListener::notifyMaterialSetup(uint32pass_id,MaterialPtr&mat)

{

if(1 == m_index){//第二个pass里面才有下面两个参数,两个passpass_id都是0???

mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters()->setNamedConstant("numpixels",1250.0f);

mat->getBestTechnique()->getPass(pass_id)->getFragmentProgramParameters()->setNamedConstant("factors",Vector3(1.0f, 0.0f, 0.0f));

}

 

m_index++;

}

      

 6:添加一个类:MyExampleApplication

    MyExampleApplication.h

 #ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include "MyEntityFrameListener.h"

#include "MyCompositorListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

MyExampleApplication(void);

~MyExampleApplication(void);

 

public:

voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

voidcreateFrameListener(void);//创建帧监听

 

voidcompositor();//组合,组合材质仅仅针对视口使用

voidcreateCamera();  //添加分屏,添加2个相机

voidcreateViewports();//添加分屏,添加3个视口

 

private:

MyEntityFrameListener*m_pFrameLst;

MyCompositorListener  *m_pCompositorLst;

 

Ogre::Camera *mCamera2;

Ogre::Viewport *pVp1;

Ogre::Viewport *pVp2;

Ogre::Viewport *pVp3;

};

 

#endif

       

   MyExampleApplication.cpp

 #include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

m_pFrameLstNULL;

m_pCompositorLstNULL;

 

pVp1NULL;

pVp2NULL;

pVp3NULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if (NULL !=m_pFrameLst){

    mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

    deletem_pFrameLst;

    m_pFrameLstNULL;

}

 

if (NULL !=m_pCompositorLst){

    deletem_pCompositorLst;

    m_pCompositorLstNULL;

}

 

//视口不在本类中释放空间

if (NULL !=pVp1){

    pVp1NULL;

}

 

if (NULL !=pVp2){

    pVp2NULL;

}

 

if (NULL !=pVp3){

    pVp3NULL;

}

}

 

void MyExampleApplication::createScene(void)

{

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));//设置环境光

Light*l =mSceneMgr->createLight("mainLight");

l->setPosition(20, 80, 50);

 

Ogre::Vector3pst = mCamera->getPosition();

Ogre::QuaternionortmCamera->getOrientation();

mCamera->setPosition(0, 100.0f, 100.0f);//设置摄像机位置

mCamera->setOrientation(Ogre::Quaternion(0.953763f, -0.3f, -0.00865638f,-0.0027f));//设置摄像机方向

 

mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2", 50);//设置天空盒

 

compositor();//组合,组合材质仅仅针对视口使用

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(mWindow,mCamera,truetruetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

 

void MyExampleApplication::compositor() //组合,组合材质仅仅针对视口使用,myMaterial.material, myCg.cg

{

Ogre::Entity *pEnt =mSceneMgr->createEntity("Entity1","Sinbad.mesh");

Ogre::SceneNode *pNode=mSceneMgr->getRootSceneNode()->createChildSceneNode("Node1");

pNode->attachObject(pEnt);

pNode->scale(3.0f, 3.0f, 3.0f);

 

CompositorManager::getSingleton().addCompositor(pVp1,"Compositor4");

CompositorManager::getSingleton().setCompositorEnabled(pVp1,"Compositor4",true);

 

//为视口的材质组合添加监听

m_pCompositorLstnew MyCompositorListener();

CompositorInstance*pComp =CompositorManager::getSingleton().getCompositorChain(pVp1)->getCompositor("Compositor4");

pComp->addListener(m_pCompositorLst);

}

 

void MyExampleApplication::createCamera()//添加分屏,添加2个相机

{

mCameramSceneMgr->createCamera("MyCamera1");

mCamera->setPosition(0,10,20);

mCamera->lookAt(0,0,0);

mCamera->setNearClipDistance(5);

 

mCamera2mSceneMgr->createCamera("MyCamera2");

mCamera2->setPosition(20,10,0);

mCamera2->lookAt(0,0,0);

mCamera2->setNearClipDistance(5);

}

 

void MyExampleApplication::createViewports()//添加分屏,添加3个视口

{

//一个相机mCamera可以创建多个视口,并且添加的各个视口的ZOrder必须唯一

pVp1mWindow->addViewport(mCamera, 0, 0.0, 0.0, 0.5, 0.5);

pVp1->setBackgroundColour(ColourValue(0.0f,0.0f, 0.0f));

 

pVp2mWindow->addViewport(mCamera, 1, 0.0, 0.5, 0.5, 1.0);

pVp2->setBackgroundColour(ColourValue(0.0f,0.0f, 0.0f));

 

pVp3mWindow->addViewport(mCamera2, 3, 0.5, 0.0, 0.5, 1.0);

    pVp3->setBackgroundColour(ColourValue(0.0f,0.0f, 0.0f));

 

//设置相机长宽比

mCamera->setAspectRatio(Real(pVp1->getActualWidth())/Real(pVp1->getActualHeight()));

mCamera2->setAspectRatio(Real(pVp3->getActualWidth())/Real(pVp3->getActualHeight()));

}

 

//myMaterial.material, myCg.cg

       

 7:myMaterial.material的内容:

//****片段着色与 材质 与 组合

fragment_program MyFragmentShader1 cg

{

   source      myCg.cg

   entry_pointMyFragmentShader1A

   profiles    ps_2_0 arbfp1

}

 

material Ogre3DBeginnersGuide/Comp1

{

  technique

  {

    pass

    {

      fragment_program_refMyFragmentShader1

      {

      }

     

      texture_unit

      {

      }

    }

  }

}

 

compositor Compositor1

{

  technique

  {

     //定义可以修改的对象

     texture scenetarget_width target_height PF_R8G8B8

     //继承先前的场景,没有先前的场景会一片空白,targetscene的scene对应texture scene的scene

     target scene

     {

       input previous

     }

     //定义合成语言的输出

     target_output

     {

       //不需要任何输入

       input none

       //渲染,需要材质和场景

       pass render_quad

       {

          materialOgre3DBeginnersGuide/Comp1

          input    0 scene

       }

     }

  }

}

 

 

//****片段着色与 材质 与 多个组合和在一起

fragment_program MyFragmentShader2 cg

{

   source      myCg.cg

   entry_pointMyFragmentShader2A

   profiles    ps_2_0 arbfp1

}

 

material Ogre3DBeginnersGuide/Comp2

{

  technique

  {

    pass

    {

      fragment_program_refMyFragmentShader2

      {

      }

     

      texture_unit

      {

      }

    }

  }

}

 

compositor Compositor2

{

  technique

  {

    texture scene target_widthtarget_height PF_R8G8B8

    texture temp  target_width target_height PF_R8G8B8

   

    target scene

    {

      input previous

    }

    target temp

    {

      pass render_quad

      {

        materialOgre3DBeginnersGuide/Comp1

        input    0 scene

      }

    }

   

    target_output

    {

      input none

      pass  render_quad

      {

        materialOgre3DBeginnersGuide/Comp2

        input    0 temp

      }

    }

  }

}

 

 

//****片段着色与 材质 与 自身重复组合

fragment_program MyFragmentShader3 cg

{

   source      myCg.cg

   entry_pointMyFragmentShader3A

   profiles    ps_2_0 arbfp1

}

 

material Ogre3DBeginnersGuide/Comp3

{

  technique

  {

    pass

    {

      fragment_program_refMyFragmentShader3

      {

      }

 

      texture_unit

      {

      }

    }

  }

}

 

compositor Compositor3

{

  technique

  {

    texture scene target_widthtarget_height PF_R8G8B8

    target scene

    {

      input previous

    }

 

    target scene

    {

       pass render_quad

       {

         material Ogre3DBeginnersGuide/Comp2

         input    0 scene

       }

    }

 

    target_output

    {

      input none

      pass render_quad

      {

         materialOgre3DBeginnersGuide/Comp3

         input    0 scene

      }

    }

  }

}

 

 

//****片段着色与 材质 与 组合,在材质中添加像素数量等参数*******//

fragment_program MyFragmentShader4 cg

{

   source      myCg.cg

   entry_pointMyFragmentShader4A

   profiles    ps_2_0 arbfp1

  

   //传递给MyFragmentShader4A的参数,数字越大越清晰

   default_params

   {

     param_named numpixelsfloat  50

     param_named factors   float4 0.2 0.6 0.3 0

   }

}

 

material Ogre3DBeginnersGuide/Comp4

{

  technique

  {

    pass

    {

      fragment_program_refMyFragmentShader4

      {

      }

     

      texture_unit

      {

      }

    }

  }

}

 

compositor Compositor4

{

  technique

  {

    texture scene target_widthtarget_height PF_R8G8B8

    target scene

    {

      input previous

    }

   

    target scene

    {

       input none

       pass render_quad

       {

         materialOgre3DBeginnersGuide/Comp2

         input    0 scene

       }

    }

   

    target_output

    {

      input none

      pass render_quad

      {

         materialOgre3DBeginnersGuide/Comp4

         input    0 scene

      }

    }

  }

}

 

 8:myCg.cg的内容:

//以下为片段着色程序,片断着色程序对每个片断进行独立的颜色计算,最后输出颜色值的就是该片段最终显示的颜色。

//可以这样说,顶点着色程序主要进行几何方面的运算,而片段着色程序主要针对最终的颜色值进行计算。

void MyFragmentShader1A(float2 uv:TEXCOORD0, out float4 color:COLOR,uniform sampler2D texture)

{

  float4 temp_color =tex2D(texture, uv);

  color =float4(1.0-temp_color.r, 1.0-temp_color.g, 1.0-temp_color.b, 0);

}

 

void MyFragmentShader2A(float2 uv:TEXCOORD0, out float4 color:COLOR,uniform sampler2D texture)

{

  float4 temp_color =tex2D(texture, uv);

  float greyvalue =temp_color.r*0.3 + temp_color.g*0.59 + temp_color.b*0.11;

  color =float4(greyvalue,greyvalue,greyvalue,0);

}

 

void MyFragmentShader3A(float2 uv:TEXCOORD0, out float4 color:COLOR,uniform sampler2D texture)

{

  float4 temp_color = tex2D(texture,uv);

  color =float4(temp_color.r+0.5, temp_color.g+0.2, temp_color.b+0.3, 0);

}

 

//在材质中添加像素数量numpixels和一个颜色通道(修改颜色值)

void MyFragmentShader4A(float2 uv:TEXCOORD0, out float4 color:COLOR,uniform sampler2D texture, uniform float numpixels, uniform float4 factors)

{

  //float  num = 50;

  float  num = numpixels;

  float  stepsize = 1.0/ num;

  //floor楼面处理,numpixels越大越清晰,越小越不清晰

  float2 fragment =float2(stepsize*floor(uv.x*num), stepsize*floor(uv.y*num));

 

  color = tex2D(texture,fragment);

  color *= factors;

}

   

八:实现类似于 Ogre的 ExampleApplication 与 ExampleFrameListener 的类

                                (程序为 游戏类编程/Ogre/Ogre1.73/Startup)

1:新建一个空的 win32控制台应用程序,命名为:Startup

 2:添加一个 Startup.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyFrameListener

    MyFrameListener.h

 #ifndef _MyFrameListener_H_

#define _MyFrameListener_H_

 

#include <ogre/Ogre.h>

using namespaceOgre;

 

#define OIS_DYNAMIC_LIB

#include <OIS/OIS.h>

 

class MyFrameListener:public FrameListener,publicOIS::KeyListener,public OIS::MouseListener,public WindowEventListener

{

public:

  MyFrameListener(RenderWindow*win,  Cameracambool bufferedKeys =false,bool bufferedMousefalsebool bufferedJoy = false);

  ~MyFrameListener(void);

 

public:

  //键盘事件

  virtualboolkeyPressed(constOIS::KeyEvent &arg);

  virtualboolkeyReleased(constOIS::KeyEvent &arg);

 

  //鼠标事件

  virtualboolmouseMoved(constOIS::MouseEvent &arg);

  virtualboolmousePressed(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

  virtualboolmouseReleased(constOIS::MouseEvent &arg,OIS::MouseButtonIDid);

 

  //帧事件

  virtualboolframeStarted(constOgre::FrameEvent&evt);

  virtualboolframeRenderingQueued(constOgre::FrameEvent&evt);

  virtualboolframeEnded(constOgre::FrameEvent&evt);

 

  //移动相机

  virtualvoidmoveCamera();

 

  //渲染窗口事件

  virtualvoidwindowResized(RenderWindow*rw);

  virtualvoidwindowClosed(RenderWindow*rw);

 

protected:

  // OIS输入控制对象

  OIS::InputManager *m_pInputMgr;

  OIS::Keyboard *m_pKeyboard;

  OIS::Mouse    *m_pMouse;

  OIS::JoyStick *m_pJoy;

 

  //渲染窗口和相机

  Ogre::RenderWindow *m_pWindow;

  Ogre::Camera      *m_pCamera;

 

  //相机移动转动事件

  Ogre::Vector3m_TranslateVector;

  Ogre::Radianm_RotX;

  Ogre::Radianm_RotY;

 

       bool m_bSysMouseShowFlag;//是否显示鼠标

};

 

#endif

     

   MyFrameListener.cpp

 #include "MyFrameListener.h"

 

MyFrameListener::MyFrameListener(RenderWindow*win,  Camera*cambool bufferedKeysboolbufferedMouse,boolbufferedJoy)

  : m_pWindow(win),m_pCamera(cam),m_TranslateVector(0.0f,0.0f, 0.0f), m_RotY(0), m_RotX(0)

{

        m_bSysMouseShowFlag = false;//用于解决鼠标独占

        ShowCursor(0);             //用于解决鼠标独占

 

  //创建OIS键盘,鼠标,手柄等对象

  unsignedintwindowHandle= 0;

  std::ostringstreamwindowHandleString;

  win->getCustomAttribute("WINDOW",&windowHandle);

  windowHandleString<< windowHandle;

 

  OIS::ParamListparameters;

  parameters.insert(std::make_pair(std::string("WINDOW"),windowHandleString.str()));

  

       parameters.insert(std::make_pair(std::string("w32_mouse"),

std::string("DISCL_FOREGROUND")));  //用于解决鼠标独占

       parameters.insert(std::make_pair(std::string("w32_mouse"),

std::string("DISCL_NONEXCLUSIVE")));//用于解决鼠标独占

 

 

  m_pInputMgrOIS::InputManager::createInputSystem(parameters);

 

  m_pKeyboardstatic_cast<OIS::Keyboard*>(m_pInputMgr->createInputObject(OIS::OISKeyboard,bufferedKeys));

  m_pMousestatic_cast<OIS::Mouse*>(m_pInputMgr->createInputObject(OIS::OISMouse,bufferedMouse));

  try{

    m_pJoystatic_cast<OIS::JoyStick*>(m_pInputMgr->createInputObject(OIS::OISJoyStick,bufferedJoy));

  } catch(...){

     m_pJoy= 0;

  }

 

  //以下键盘,鼠标回调函数需要在子类中被调用到,才会有keyPressed,mouseMoved等事件

  m_pKeyboard->setEventCallback(this);

  m_pMouse->setEventCallback(this);

 

  //监听渲染窗口

  WindowEventUtilities::addWindowEventListener(m_pWindow,this);

}

 

MyFrameListener::~MyFrameListener(void)

{

WindowEventUtilities::removeWindowEventListener(m_pWindow,this);//虚构时删除窗口的监听,渲染窗口关闭后,m_pWindow对应的值已经不存在

  windowClosed(m_pWindow);

}

 

bool MyFrameListener::keyPressed(constOIS::KeyEvent&arg)

{

  RealmoveScale = 0.2f;

 

  switch(arg.key){

  caseOIS::KC_A:

  caseOIS::KC_LEFT:

     m_TranslateVector.x = -moveScale;//Move camera left

     break;

  caseOIS::KC_D:

  caseOIS::KC_RIGHT:

     m_TranslateVector.x =moveScale//Move camera RIGHT

     break;

  caseOIS::KC_W:

  caseOIS::KC_UP:

     m_TranslateVector.z = -moveScale;//Move camera forward

     break;

  caseOIS::KC_S:

  caseOIS::KC_DOWN:

     m_TranslateVector.z =moveScale;//Move camera backward

     break;

  caseOIS::KC_PGUP:

     m_TranslateVector.y =moveScale;   //Move camera up

     break;

  caseOIS::KC_PGDOWN:

     m_TranslateVector.y = -moveScale;//Move camera down

     break;

  }

 

  returntrue;

}

 

bool MyFrameListener::keyReleased(constOIS::KeyEvent&arg)

{

  m_TranslateVectorVector3::ZERO;//防止键释放后,相机还在移动

 

  returntrue;

}

 

bool MyFrameListener::mouseMoved(constOIS::MouseEvent&arg)

{

//用于解决鼠标独占

if(arg.state.X.abs <m_pWindow->getViewport(0)->getActualLeft()+1 

     ||(arg.state.Y.abs <m_pWindow->getViewport(0)->getActualTop()+1) 

     ||(arg.state.X.abs >m_pWindow->getViewport(0)->getActualLeft()+m_pWindow->getViewport(0)->getActualWidth()) 

     ||(arg.state.Y.abs >m_pWindow->getViewport(0)->getActualTop()+m_pWindow->getViewport(0)->getActualHeight())){ 

        if(!m_bSysMouseShowFlag){//鼠标移出界面

            ShowCursor(1);

            m_bSysMouseShowFlag=true

        } 

else//鼠标进入界面

     if(m_bSysMouseShowFlag){

        ShowCursor(0);

        m_bSysMouseShowFlagfalse

     } 

}

 

if(!m_bSysMouseShowFlag){

  constOIS::MouseState&ms =arg.state;

  if(ms.buttonDown(OIS::MB_Left)){

  } elseif(ms.buttonDown(OIS::MB_Right)) {

  } else{

      m_RotXDegree(-ms.Y.rel * 0.13);//转为弧度,如:Degree(180)

      m_RotYDegree(-ms.X.rel * 0.13);//转为弧度,如:Degree(180)

  }

}

 

returntrue;

}

 

bool MyFrameListener::mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

  returntrue;

}

 

bool MyFrameListener::mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

  returntrue;

}

 

bool MyFrameListener::frameStarted(constOgre::FrameEvent&evt)

{

  if(NULL ==m_pWindow)returnfalse//当窗口为NULL,返回false,退出循环(Root->startRendering())

 

  returntrue;

}

 

bool MyFrameListener::frameRenderingQueued(constOgre::FrameEvent&evt)

{

  if(NULL !=m_pInputMgr){//捕捉键,,手柄事件

     m_pKeyboard->capture();

     m_pMouse->capture();

     if(m_pJoy)m_pJoy->capture();

  }

 

  returntrue;

}

 

bool MyFrameListener::frameEnded(constOgre::FrameEvent&evt)

{

  moveCamera();//移动相机

 

  returntrue;

}

 

void MyFrameListener::moveCamera()//移动相机

{

  m_pCamera->pitch(m_RotX);

  m_pCamera->yaw(m_RotY);

  m_pCamera->moveRelative(m_TranslateVector);

 

  m_RotXm_RotY = 0.0f;

}

 

void MyFrameListener::windowResized(RenderWindow*rw)

{

}

 

void MyFrameListener::windowClosed(RenderWindow*rw)

{

  if(rw ==m_pWindow)

  {

     if(m_pInputMgr)//释放键,,手柄等对象

     {

         m_pInputMgr->destroyInputObject(m_pMouse);

         m_pInputMgr->destroyInputObject(m_pKeyboard);

         m_pInputMgr->destroyInputObject(m_pJoy);

 

         OIS::InputManager::destroyInputSystem(m_pInputMgr);

         m_pInputMgrNULL;

     }

 

     m_pWindowNULL;//窗口关闭时,此值置为NULL,用于退出循环(Root->startRendering())

  }

}

     

 5:添加一个类:MyApplication

    MyApplication.h

 #ifndef _MyApplication_H_

#define _MyApplication_H_

 

#include "MyFrameListener.h"

#include <ogre/Ogre.h>

using namespaceOgre;

 

class MyApplication

{

public:

  MyApplication(void);

  ~MyApplication(void);

 

public:

  voidgo();

  virtualvoidcreateScene();   //创建场景

  virtualvoidcreateListener();//创建监听

 

protected:

  Ogre::Root        *m_pRoot;

  Ogre::RenderWindow *m_pWindow;

  Ogre::SceneManager *m_pSceneManager;

  Ogre::Camera      *m_pCamera;

  Ogre::Viewport    *m_pViewport;

 

  Entity*m_pEnt;

 

  MyFrameListener*m_pFrameLst;

};

 

#endif

     

   MyApplication.cpp

 #include "MyApplication.h"

 

MyApplication::MyApplication(void)

{

  m_pRootNULL;

  m_pWindowNULL;

  m_pSceneManagerNULL;

  m_pCameraNULL;

  m_pViewportNULL;

 

  m_pEntNULL;

 

  m_pFrameLstNULL;

}

 

MyApplication::~MyApplication(void)

{

  m_pSceneManager->destroyAllEntities();

  m_pEntNULL;

 

  m_pSceneManager->getRootSceneNode()->removeAndDestroyAllChildren();

 

  if(NULL !=m_pRoot){//释放root资源

     m_pRoot->removeFrameListener(m_pFrameLst);

 

     deletem_pRoot;

     m_pRootNULL;

 

     m_pFrameLstNULL;

  }

}

 

void MyApplication::go()

{

  //创建Root,窗口,场景管理

  m_pRootnew Ogre::Root("plugins_d.cfg","ogre.cfg","ogre.log");

      

if(!m_pRoot->restoreConfig()){//启动时不显示Ogre的配置窗口,要求必须有ogre.cfg

  if(!m_pRoot->showConfigDialog()){//启动时显示Ogre的配置窗口,如果没有ogre.cfg

return;

  } else{

    m_pRoot->saveConfig();//保存一个 ogre.cfg

  }

}

      

  m_pWindowm_pRoot->initialise(true,"渲染窗口");

  m_pSceneManagerm_pRoot->createSceneManager(Ogre::ST_GENERIC,"ExampleSMInstance");

 

  //创建相机与视口

  m_pCameram_pSceneManager->createCamera("Camera");

  m_pCamera->setPosition(Vector3(0.0f,0.0f, 50.0f));

  m_pCamera->lookAt(Vector3(0.0f,0.0f, 0.0f));

  m_pCamera->setNearClipDistance(5);

 

  m_pViewportm_pWindow->addViewport(m_pCamera);

  m_pViewport->setBackgroundColour(ColourValue(0.0f,0.0f, 0.0f));

m_pCamera->setAutoAspectRatio(Real(m_pViewport->getActualWidth())/Real(m_pViewport->getActualHeight()));

 

  //载入单个资源

  //ResourceGroupManager::getSingleton().addResourceLocation("media/packs/Sinbad.zip","Zip", "Popular");

  //ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

 

  //从文件载入资源

  ConfigFilecf;

  cf.load("resources_d.cfg");

  ConfigFile::SectionIteratorsectionItercf.getSectionIterator();

  StringsectionName,typeName,dataName;

  while(sectionIter.hasMoreElements()){

     sectionNamesectionIter.peekNextKey();

 

     ConfigFile::SettingsMultiMap *settings=sectionIter.getNext();

     ConfigFile::SettingsMultiMap::iteratormultiMapIter;

     for(multiMapIter =settings->begin();multiMapIter!= settings->end();multiMapIter++){

         typeNamemultiMapIter->first;

         dataNamemultiMapIter->second;

 

         ResourceGroupManager::getSingleton().addResourceLocation(dataName,typeName,sectionName);

     }

  }

  ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

 

  createScene();   //创建场景

  createListener();//创建监听

 

  m_pRoot->startRendering();//开始渲染,需要FrameListener类的frameStartedframeRenderingQueuedframeEnded函数返回false才会退出循环

}

 

void MyApplication::createScene()//创建场景

{

  m_pEntm_pSceneManager->createEntity("Sinbad.mesh");//创建实体

  m_pSceneManager->getRootSceneNode()->attachObject(m_pEnt);

}

 

void MyApplication::createListener()//创建监听,Root类必须有帧监听类,否则startRendering无法退出,其它看上面的startRendering后的解释

{

  m_pFrameLstnew MyFrameListener(m_pWindow,m_pCamera,true,truetrue);

  m_pRoot->addFrameListener(m_pFrameLst);

}

     

 6:Startup.cpp的内容:

#include "MyApplication.h"

 

int main(){

  MyApplicationapp;

  app.go();

 

  return0;

}

     

九:粒子系统和扩展Ogre3D  (程序为 游戏类编程/Ogre/Ogre1.73/ParticleSystems)

 1:新建一个空的 win32控制台应用程序,命名为:ParticleSystems

 2:添加一个 ParticleSystems.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:添加一个类:MyEntityFrameListener,内容与 五 中的MyEntityFrameListener一致

 5:添加一个类:MyExampleApplication

    MyExampleApplication.h

 #ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include "MyEntityFrameListener.h"

 

class MyExampleApplication:public ExampleApplication

{

public:

MyExampleApplication(void);

~MyExampleApplication(void);

 

public:

voidcreateScene(void);//创建屏幕(设置灯光,材质,相机,创建实体节点等)

voidcreateFrameListener(void);//创建帧监听

 

voidcreateParticle();//创建粒子系统

 

private:

MyEntityFrameListener*m_pFrameLst;

};

 

#endif

      

   MyExampleApplication.cpp

 #include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

m_pFrameLstNULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

if (NULL !=m_pFrameLst){

    mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

    deletem_pFrameLst;

    m_pFrameLstNULL;

}

}

 

void MyExampleApplication::createScene(void)

{

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));//设置环境光

Light*l =mSceneMgr->createLight("mainLight");

l->setPosition(20, 80, 50);

 

Ogre::Vector3pst = mCamera->getPosition();

Ogre::Quaternionort = mCamera->getOrientation();

mCamera->setPosition(0, 100.0f, 500.0f);//设置摄像机位置

mCamera->setOrientation(Ogre::Quaternion(0.953763f, -0.3f, -0.00865638f,-0.0027f));//设置摄像机方向

 

mSceneMgr->setSkyBox(true,"Examples/SceneSkyBox2", 50);//设置天空盒

 

createParticle();//创建粒子系统

}

 

void MyExampleApplication::createFrameListener(void)

{

m_pFrameLstnew MyEntityFrameListener(mWindow,mCameratrue,truetrue);//启用各输入设备的缓冲

mRoot->addFrameListener(m_pFrameLst);

}

 

void MyExampleApplication::createParticle()//创建粒子系统

{

//通过模板创建粒子系统,粒子系统需要一个发射器,粒子,颜色修改器

Ogre::ParticleSystem*partSystemmSceneMgr->createParticleSystem("Smoke","MySwarm");//MySmokePoint Examples/Smoke Examples/Fireworks

SceneNode*pNode =mSceneMgr->getRootSceneNode()->createChildSceneNode();

pNode->attachObject(partSystem);

pNode->setPosition(1, 10, 0);

}

 

//myParticle.particle,myMaterial.material

      

 6:myMaterial.material的内容:

//材质

 

//给材质命名

material myMaterial

{

  //技术

  technique

  {

    //通道

    pass

    {

      //关闭灯光

      lighting off

      //场景混合,alpha混合

      scene_blend alpha_blend

      depth_write off

      //漫反射顶点颜色

      diffuse vertexcolor

     

      texture_unit

      {

        texture smoke.png

        //tex_address_modeclamp,//材质不拉伸,材质边缘延伸填充,具体看材质方面的实例

      }

    }

  }

}

   

7:myParticle.particle的内容:

//粒子系统:需要一个发射器,粒子,颜色修改器等

//billboard_type        point 粒子的头尾与XZ面是垂直的

//billboard_type oriented_self 粒子的头尾连线是指向原点的,即与XZ平面有夹角,(激光射线,焰火,隨着粒子改变方向,公告板也重定向它自己面向这个方向)

//billboard_type oriented_common:粒子的头尾连线都是平行于XY(粒子面向一个共同的固定的方向向量),(暴风雨,流星,oriented_self略快)

//perpendicular_common:粒子垂直于一个共同的固定的方向向量

//perpendicular_self 粒子垂直于它们自己的方向向量

//billboard_type oriented_commoncommon_direction 0 -1 0改变粒子在Y轴的方向,common_direction好像无法与billboard_type point结合

 

//***************************点粒子系统***************************//

particle_system MySmoke_Point_oriented_self

{

  material Examples/Flare2

  particle_width  5

  particle_height 5

 

  quota          5000

  billboard_type oriented_self

 

  emitter Point

  {

    emission_rate 100

    direction     0 1 0

    angle         30

    velocity      20

    time_to_live  10

 

    colour_range_start       1 0 0 1

    colour_range_end          0.5 0.5 0.5 0.1

  }

}

 

particle_system MySmoke_Point_point

{

  //粒子材质名称,粒子宽度,粒子高度myMaterial

  material Examples/Flare2

  particle_width  5

  particle_height 5

 

  //粒子配额(数量)和 类型  point 与 oriented_self的区别是,point粒子的头尾与XZ面是垂直的,

  //而oriented_self的头尾连线是指向原点的,即与XZ平面有夹角

  quota          500

  billboard_type point

 

  //点发射器

  emitter Point

  {

    //每秒发出10个

    emission_rate 100

    //发射方向

    direction     0 1 0

    //速度

    velocity   20

    //最小速度和最大速度

    //velocity_min 50

               //velocity_max80

 

               //角度,粒子存活时长10秒,顶点颜色

               angle 30

               //time_to_live10//粒子存活时长10秒

               //粒子存活最短时长和最大时长

               time_to_live_min1

               time_to_live_max6

               //colour 1 0 0 1//顶点颜色

               //顶点起始颜色和结束颜色

               //colour_range_start       1 0 0 1

               //colour_range_end          0.5 0.5 0.5 0.1

 

               //连续发射时长,和等待发射时长,发1秒,隔1秒

               //duration 1

               //repeat_delay 1

  }

 

  //在粒子存活时段,放大5倍大小

  affector Scaler

  {

    rate 5

  }

 

  //导流面板,粒子碰到此面板,会向面板的法向量方向运动

  affector DeflectorPlane

  {

    //面板点,面板法向量

    plane_point  00 80 0

    plane_normal -1 -1 0

    bounce       1.0

  }

 

  //颜色图片,给材质加颜色,相当于colour等

  affector ColourImage

      {

               imagesmokecolors.png

      }

 

      //添加随机???

      //affectorDirectionRandomiser

      //{

      //  randomness 100

        //1代表100%,0代表0%, 保持速度,即速度不改变

      //  scope 1

      //  keep_velocity true

      //}

 

  //不同时段,粒子颜色不同

  /*

  affector ColourInterpolator

  {

    time0   0

    colour0 1 0 0

   

    time1   0.25

    colour1 0 1 0

   

    time2   0.5

    colour2 0 0 1

   

    time3   0.75

    colour3 0 0.5 1

   

    time4   1

    colour4 0.5 0.5 0

  }*/

 

  /*

  //颜色推子,可以改变粒子颜色度

  affector ColourFader

  {

    red   -0.25

    green -0.25

    blue  -0.25

  }

 

  affector ColourFader2

  {

    red1   -1

    green1 -1

    blue1  -1

    state_change 2

    red2   +1

    green2 +1

    blue2  +1

  }

  */

}

 

particle_system MySmoke_Point_oriented_common

{

  material Examples/Flare2

  particle_width  5

  particle_height 5

 

  quota          5000

  billboard_typeoriented_common

 

  emitter Point

  {

    emission_rate 100

    direction     0 1 0

    angle         30

    velocity      20

    time_to_live  10

 

    colour_range_start       1 0 0 1

    colour_range_end          0.5 0.5 0.5 0.1

  }

}

 

//***************************盒子粒子系统***************************//

particle_system MySmoke_Box_oriented_self

{

  material Examples/Flare2

  particle_width  5

  particle_height 5

 

  quota          5000

  billboard_type oriented_self

 

  emitter Box

  {

    height 10

    width 10

    depth 10

 

    emission_rate 100

    direction     0 1 0

    velocity      20

 

    //angle  30

  }

}

 

particle_system MySmoke_Box_point

{

  //粒子材质名称,粒子宽度,粒子高度

  material Examples/Flare2

  particle_width  5

  particle_height 5

 

  //粒子配额(数量)和点类型

  quota          5000

  billboard_type point

 

  //盒子发射器

  emitter Box

  {

    //定义盒子,高宽深

    height 10

    width 10

    depth 10

 

    //每秒发出100个,发射方向,速度

    emission_rate 100

    direction     0 1 0

    velocity      20

 

    //angle  30

  }

}

 

particle_system MySmoke_Box_oriented_common

{

  material Examples/Flare2

  particle_width  5

  particle_height 5

 

  quota          5000

  billboard_typeoriented_common

 

  emitter Box

  {

    height 10

    width  10

    depth  10

 

    emission_rate 100

    direction     0 1 0

    velocity      20

 

    //angle  30

  }

}

 

//***************************环状粒子系统***************************//

particle_system MySmoke_Ring_oriented_self

{

  material myMaterial

  particle_width  5

  particle_height 5

 

  quota          5000

  billboard_type oriented_self

 

  emitter Ring

  {

    height 50

    width  50

   

    inner_height 0.9

    inner_width  0.9

 

    emission_rate 100

    direction     0 1 0

    velocity      20

   

    //angle  30

  }

}

 

particle_system MySmoke_Ring_point

{

  //粒子材质名称,粒子宽度,粒子高度

  material myMaterial

  particle_width  5

  particle_height 5

  sorted          true

 

  //粒子配额(数量)和点类型

  quota          500

  billboard_type point

 

  emitter Ring

  {

    //高宽

    height 10

    width  10

 

    //内部90%部分不发射粒子(百分比)

    inner_height 0.9

    inner_width  0.9

 

    //每秒发出10个,发射方向,速度

    emission_rate 50

    direction     0 1 0

    velocity      20

    time_to_live  10

    //angle  30

  }

 

  //不同时间段,颜色不同

  affector ColourInterpolator

  {

    time0    0.00

    colour0  1 0 0

    time1    0.50

    colour1  0 1 0

    time2    0.70

    colour2  0 0 1

  }

}

 

particle_system MySmoke_Ring_oriented_common

{

  material myMaterial

  particle_width  5

  particle_height 5

 

  quota          5000

  billboard_typeoriented_common

 

  emitter Ring

  {

    height 50

    width  50

 

    inner_height 0.9

    inner_width  0.9

 

    emission_rate 100

    direction     0 1 0

    velocity      20

 

    //angle  30

  }

}

 

//***************************粒子系统实例***************************//

//一烟冲天

particle_system MySmoke

{

  material        myMaterial

  particle_width  5

  particle_height 5

  sorted          true

 

  quota          500

  billboard_type point

 

  emitter Point

  {

    emission_rate 25

    direction     0 1 0

    velocity      20

    time_to_live  10

  }

 

  affector ColourInterpolator

  {

    time0    0.00

    colour0  1 0 0

    time1    0.50

    colour1  0 1 0

    time2    0.70

    colour2  0 0 1

  }

 

  affector Scaler

  {

    rate 3

  }

 

  affector ColourFader2

  {

    red1   -0.25

    green1 -0.25

    blue1  -0.25

    state_change 2

    red2   +0.25

    green2 +0.25

    blue2  +0.25

  }

}

 

//烟花爆竹粒子系统(使用了多点发射器)

particle_system myFirework

{

   material        myMaterial

   particle_width  5

   particle_height 5

   quota           1000

   billboard_type  point

 

   point_rendering    false

   cull_each          false

   //每次发射的数量

   emit_emitter_quota 10

 

   //发射器(emitterBox)使用多点发射:explosion

   emitter Box

   {

     height 50

     width  50

     depth  50

   

     name          mainEmitter

     emit_emitter  explosion

 

     time_to_live  3

     direction     0 100 0

     velocity      200

   }

 

   //explosion:通过Box发射器,爆炸之后得emitterPoint....

   emitter Point

   {

     name     explosion

     duration 0.1

 

     repeat_delay_min 2

     repeat_delay_max 3

 

     emission_rate 1000

     direction     0 100 0

     velocity      80

     angle         90

 

     colour_range_start 0.50.6 0.7

     colour_range_end   1  0.7 0.8

   }

 

   //下坠向量

   affector LinearForce

   {

     force_vector      0 -100 0

     force_application add

   }

 

   //不同时间段,颜色不同

   affector ColourInterpolator

   {

     time0    0.00

     colour0  1 0 0

     time1    0.25

     colour1  0 1 0

     time2    0.50

     colour2  0 0 1

   }

}

 

//下雨粒子系统

particle_system myRain

{

  //粒子材质名称,粒子宽度,粒子高度

  material        Examples/Droplet

  particle_width  50

  particle_height 100

 

  //粒子配额(数量)和点类型

  quota           500

 

  //直线下坠,直线方向沿Y轴方向(common_direction0 -1 0向Y轴方向)

  billboard_type   oriented_common

  common_direction 0 -1 0

 

  //盒子发射器,

  emitter Box

  {

    angle 0

 

    //定义盒子,高宽深

    height 500

    width  500

    depth  500

 

    //每秒发出10个,发射方向,速度

    emission_rate 100

    direction     0 -10 0

    velocity      200

  }

 

  //下落或上升,取决于force_vector的值

  affector LinearForce

  {

    force_vector      0 -100 0

    force_application add

  }

}

 

//billboard_type oriented_self + angle          360 + affector DeflectorPlane实现

//在粒子在Box里面随机方向运动加碰撞转向运动

particle_system MySwarm

{

  material Examples/Flare2

  particle_width  12

  particle_height 24

 

  quota          500

  billboard_type oriented_self

 

  emitter Box

  {

    angle     360

 

    height 100

    width  100

    depth  100

 

    emission_rate 50

    direction     0 1 0

    velocity      20

  }

 

  affector DeflectorPlane

      {

               plane_point      0 -50 0

               plane_normal  0 1 0

               bounce     1

      }

 

      affector DeflectorPlane

      {

               plane_point      0 50 0

               plane_normal  0 -1 0

               bounce     1

      }

 

      affector DeflectorPlane

      {

               plane_point      50 0 0

               plane_normal  -1 0 0

               bounce     1

      }

 

      affector DeflectorPlane

      {

               plane_point      -50 0 0

               plane_normal  1 0 0

               bounce     1

      }

 

      affector DeflectorPlane

      {

               plane_point      0 0 50

               plane_normal  0 0 -1

               bounce     1

      }

 

      affector DeflectorPlane

      {

               plane_point      0 0 -50

               plane_normal  0 0 1

               bounce     1

      }

}

      

十:主角实体运动与 障碍物判断,怪物实体向  主角 实体 方向 运动等

                                      (程序为 游戏类编程/Ogre/Ogre1.73/AITest(简单的测试))

 1:新建一个空的 win32控制台应用程序,命名为:AITest

 2:添加一个 AITest.cpp文件.

 3:配置跟 FirstOGRE3,4,5项一样.

 4:代码 看:AITest(简单的测试)

   

   

十一:地形编程(读取地形配置文件的地形编程)。(程序为游戏类编程/Ogre/Ogre1.73/TerrainCfgFile)

 1:新建一个空的 win32控制台应用程序, 命名为:TerrainCfgFile

 2:添加一个 TerrainCfgFile.cpp文件,内容:

 #include "MyExampleApplication.h"

 

int main(){

   MyExampleApplicationapp;

   app.go();

  

   return 0;

}

        

 3:配置跟 FirstOGRE3,4,5项一样.

 4:在3的基础上,需要添加Ogre目录:

   

5:需要多引入一个地形库:OgreTerrain_d.lib

6:添加一个类:MyExampleApplication

   MyExampleApplication.h

 #ifndef _MyExampleApplication_H_

#define _MyExampleApplication_H_

 

#include <OGRE/ExampleApplication.h>

#include <ogre/Terrain/OgreTerrain.h>

#include <ogre/Terrain/OgreTerrainGroup.h>

#include "MyEntityFrameListener.h"

 

using namespaceOgre;

 

class MyExampleApplication :public ExampleApplication

{

public:

  MyExampleApplication(void);

  ~MyExampleApplication(void);

 

public:

  virtual void chooseSceneManager(void);//创建屏幕管理

  virtual void createCamera(void);     //创建相机

  void createScene(void);        //创建屏幕(设置灯光,材质,相机,创建实体节点等)

  void createFrameListener(void);//创建帧监听

 

protected:

  MyEntityFrameListener *m_pFrameLst;

  RaySceneQuery        *m_pRaySceneQuery;//射线碰撞查询器

  TerrainGlobalOptions  *m_pTerrainGlobals;//地形全局配置

  TerrainGroup         *m_pTerrainGroup//地形分组对象

};

 

#endif

        

   MyExampleApplication.cpp

#include "MyExampleApplication.h"

 

MyExampleApplication::MyExampleApplication(void)

{

   m_pFrameLst = NULL;

}

 

MyExampleApplication::~MyExampleApplication(void)

{

   if (NULL !=m_pFrameLst){

       mRoot->removeFrameListener(m_pFrameLst);//删除监听

 

       delete m_pFrameLst;

       m_pFrameLst = NULL;

   }

}

 

void MyExampleApplication::chooseSceneManager(void)//创建屏幕管理

{

   mSceneMgr = mRoot->createSceneManager(ST_EXTERIOR_CLOSE,"ExampleSMInstance2");//室外封闭场景

}

 

void MyExampleApplication::createCamera(void)

{

   mSceneMgr = mRoot->getSceneManager("ExampleSMInstance2");//根据管理器名称获取屏幕管理器

   mCamera = mSceneMgr->createCamera("plyerCam2");//创建摄像机

   mCamera->setPosition(Vector3(707.0f, 150.0f, 528.0f));//摄像机位置

   mCamera->lookAt(Vector3(0.0f, 0.0f, -300.0f));//摄像机的目标点

   mCamera->setNearClipDistance(1); //摄像机近距

   mCamera->setFarClipDistance(1000);//摄像机远距

}

 

void MyExampleApplication::createScene(void)

{

   //地形相关

   mSceneMgr = mRoot->getSceneManager("ExampleSMInstance2");

   mSceneMgr->setAmbientLight(ColourValue(0.5f, 0.5f, 0.5f));//设置场景的环境光

 

   Light *l =mSceneMgr->createLight("MainLight");//创建灯光

   l->setPosition(20.0f,80.0f, 50.0f);          //设置灯光位置

 

   mSceneMgr->setFog(FogMode::FOG_LINEAR,ColourValue(0.93f, 0.16f, 0.76f), 0.001,500, 1000);//设置雾

   mWindow->getViewport(0)->setBackgroundColour(ColourValue(0.93f,0.86f, 0.76f));//设置视口背景

 

   //***************地形块的全局配置

   m_pTerrainGlobals = newOgre::TerrainGlobalOptions();

   m_pTerrainGlobals->setLayerBlendMapSize(64);//设置地形层混合图大小为64x64

 

 

   m_pTerrainGlobals->setMaxPixelError(8);

   m_pTerrainGlobals->setCompositeMapDistance(3000);

   m_pTerrainGlobals->setLightMapDirection(l->getDerivedDirection());//设置光线方向,所有地形均采用同一个方向的光

   m_pTerrainGlobals->setCompositeMapAmbient(mSceneMgr->getAmbientLight());//设置环境光

   m_pTerrainGlobals->setCompositeMapDiffuse(l->getDiffuseColour());//设置漫反射光

   m_pTerrainGlobals->setLightMapSize(1500);//设置光线图的大小,这个数字越小,地图的阴影将越粗糙

 

   //***************创建地形分组对象,该对象用于创建以及管理地形块

   m_pTerrainGroup = newTerrainGroup(mSceneMgr,Terrain::ALIGN_X_Z,1500, 1500);

   m_pTerrainGroup->setOrigin(Vector3(750, 0, 750));

 

   //***************通过地形分组创建地形块

   //设置地形默认属性

   Terrain::ImportData&defalutImp =m_pTerrainGroup->getDefaultImportSettings();

   defalutImp.terrainSize= 1500;

   defalutImp.worldSize   = 1500;

   defalutImp.inputScale  = 1;

   defalutImp.minBatchSize=33;

   defalutImp.maxBatchSize=65;

   //设置纹理

   defalutImp.layerList.resize(1);

   defalutImp.layerList[0].worldSize = 8;//每层贴图wordsize8为佳

 

 

   defalutImp.layerList[0].textureNames.push_back("terrain_texture.jpg");

   //defalutImp.layerList[0].textureNames.push_back(750);

   //设置地形默认属性

   Terrain::ImportData&defaultimp =m_pTerrainGroup->getDefaultImportSettings();

   defalutImp.terrainSize= 1500;

   defalutImp.worldSize   = 1500;

   defalutImp.inputScale  = 1;

   defalutImp.minBatchSize=33;

   defalutImp.maxBatchSize=65;

 

   m_pTerrainGroup->defineTerrain(100,100, 10.0f);

 

 

   //mSceneMgr->setWorldGeometry("myTerrain.cfg"); //设置世界几何体

 

   //是否支持无限远的面投影

   mCamera = mSceneMgr->getCamera("plyerCam2");//获取相机

   if (mRoot->getRenderSystem()->getCapabilities()->hasCapability(RSC_INFINITE_FAR_PLANE)){

       mCamera->setFarClipDistance(0);

   }

 

   //创建射线碰撞查询器,由摄像机位置向Y轴负向发射线进行查询

   m_pRaySceneQuery = mSceneMgr->createRayQuery(Ray(mCamera->getPosition(),Vector3::NEGATIVE_UNIT_Y));

}

 

void MyExampleApplication::createFrameListener(void)

{

  m_pFrameLst = new MyEntityFrameListener(m_pRaySceneQuery,mWindow,mCamera,truetruetrue);//启用各输入设备的缓冲

   mRoot->addFrameListener(m_pFrameLst);

}

       

 7:添加一个类:MyEntityFrameListener

   MyEntityFrameListener.h

 #ifndef MyEntityFrameListener_H_

#define MyEntityFrameListener_H_

 

#include "ogre/exampleframelistener.h"

using namespaceOgre;

 

class MyEntityFrameListener :public ExampleFrameListener,publicOIS::KeyListener,public OIS::MouseListener

{

public:

MyEntityFrameListener(RaySceneQuery*pRaySceneQuery,RenderWindow*win,Cameracambool bufferedKeys = false,bool bufferedMouse=false,bool bufferedJoy = false);

~MyEntityFrameListener(void);

 

public:

virtual bool keyPressed(constOIS::KeyEvent &arg);

virtual bool keyReleased(constOIS::KeyEvent &arg);

 

virtual bool mouseMoved(constOIS::MouseEvent &arg);

virtual bool mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid);

virtual bool mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid);

 

void moveCamera();//移动相机

virtual bool frameEnded(constFrameEventevt);//循环刷新界面

 

protected:

SceneManager *mSceneMgr;

    RaySceneQuery *m_pRaySceneQuery;//射线碰撞查询器

};

 

#endif

        

   MyEntityFrameListener.cpp

 #include "MyEntityFrameListener.h"

 

MyEntityFrameListener::MyEntityFrameListener(RaySceneQuery *pRaySceneQuery,RenderWindow*win,Camera*cam,bool bufferedKeys,boolbufferedMouse,bool bufferedJoy)

ExampleFrameListener(win,cam,bufferedKeys,bufferedMouse,bufferedJoy)

{

//启用了键鼠柄的缓冲,就能使用它们的回调函数

mKeyboard->setEventCallback(this);

mMouse->setEventCallback(this);

 

m_pRaySceneQuery = pRaySceneQuery;//射线碰撞查询器

mSceneMgr = cam->getSceneManager();

}

 

MyEntityFrameListener::~MyEntityFrameListener(void)

{

}

 

bool MyEntityFrameListener::keyPressed(constOIS::KeyEvent&arg)//键盘的键按下

{

Real moveScale= 0.2f;

 

switch(arg.key){

case OIS::KC_A:

case OIS::KC_LEFT:

    mTranslateVector.x= -moveScale;//Movecamera left

    break;

case OIS::KC_D:

case OIS::KC_RIGHT:

    mTranslateVector.x=moveScale//Move camera RIGHT

    break;

case OIS::KC_W:

case OIS::KC_UP:

    mTranslateVector.z= -moveScale;//Movecamera forward

    break;

case OIS::KC_S:

case OIS::KC_DOWN:

    mTranslateVector.z=moveScale//Move camera backward

    break;

case OIS::KC_PGUP:

    mTranslateVector.y=moveScale//Move camera up

    break;

case OIS::KC_PGDOWN:

    mTranslateVector.y= -moveScale;//Movecamera down

    break;

}

 

return true;

}

 

bool MyEntityFrameListener::keyReleased(constOIS::KeyEvent&arg)//释放按下的键

{

mTranslateVector = Vector3::ZERO;//防止按键释放后还继续移动相机

return true;

}

 

bool MyEntityFrameListener::mouseMoved(constOIS::MouseEvent&arg)

{

const OIS::MouseState &ms=arg.state;

if(ms.buttonDown(OIS::MB_Left)) {

else if(ms.buttonDown(OIS::MB_Right)){

else {

    mRotX = Degree(-ms.Y.rel * 0.13);//转为弧度,如:Degree(180)

    mRotY = Degree(-ms.X.rel * 0.13);//转为弧度,如:Degree(180)

}

 

return true;

}

 

bool MyEntityFrameListener::mousePressed(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

return true;

}

 

bool MyEntityFrameListener::mouseReleased(constOIS::MouseEvent&arg,OIS::MouseButtonIDid)

{

return true;

}

 

void MyEntityFrameListener::moveCamera() //移动相机

{

mCamera->yaw(mRotY); //Y轴转动

mCamera->pitch(mRotX);//X轴转动

mCamera->moveRelative(mTranslateVector);//移动相机

mRotX = mRotY =Radian(0); //防止鼠标不转动后继续转动相机

}

 

bool MyEntityFrameListener::frameEnded(constFrameEventevt)

{

moveCamera(); //移动相机

 

static Ray updateRay;//定义一个射线变量

updateRay.setOrigin(mCamera->getPosition());//设置原点为摄像机的位置

updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);//设置方向为Y轴方向

 

m_pRaySceneQuery->setRay(updateRay);//碰撞查询器设置射线

 

RaySceneQueryResult &qryResult=m_pRaySceneQuery->execute();//执行碰撞查询

 

//遍历查询结果

RaySceneQueryResult::iteratoritrRaySQRst =qryResult.begin();

if(itrRaySQRst !=qryResult.end()&&itrRaySQRst->worldFragment){

     mCamera->setPosition(mCamera->getPosition().x,itrRaySQRst->worldFragment->singleIntersection.y

        +100, mCamera->getPosition().z);//将摄像机设置成地表的位置偏移10

}

 

return true;

}

       

 8:添加一个地形配置文件:myTerrain.cfg,放在Media目录下,内容为:

#WorldTexture,DetailTexture仅用作纹理

#主世界纹理,通过纹理管理器创建一个材质

WorldTexture=terrain_texture.jpg

#详细纹理,通过纹理管理器创建一个材质 waves2.dds

DetailTexture=terrain_detail.jpg

#平铺的瓦片数

DetailTile=3

 

#高位图资源(相当于模型),指定的高位图,图片为png格式

PageSource=Heightmap

Heightmap.image=terrain.png

#图片大小,图片顶点数,尺寸必须是方形,必须是(2^n)+1

PageSize=513

#每一个瓦块大小,必须是(2^n)+1

TileSize=65

 

#Heightmap.image=waveNM1.raw

#如果使用的是RAW格式的图片,指定RAW格式图片大小,必须是(2^n)+1

#Heightmap.raw.size=513

#指定使用的像素bit(1 = 8bit, 2=16bit)

#Heightmap.raw.bpp=1

#如果设置为true,则翻转高度图

#Heightmap.flip=true

 

#LOD时允许最大的误差,过高会导致地形撕裂,过低则会影响性能

MaxPixelError=3

 

#在世界单元中一个地形页的大小

PageWorldX=1500

PageWorldZ=1500

#地形的最大高度,用于相乘

MaxHeight=200

 

#渲染地形使用的细节层次的数目。地形的远处和平坦处会以低细节渲染

MaxMipMapLevel=5

 

#VertexNormals=yes

#VertexColors=yes

#UseTriStrips=yes

 

#使用顶点端变形LODs

VertexProgramMorph=yes

 

#The proportional distance range at which the LODmorph starts to take effect

#This is as a proportion of the distance betweenthe current LODs effective range,

#and the effective range of the next lower LOD

#LOD融合开始点:高低LOD之间距离之比

LODMorphStart=0.2

 

#This following section is for if you want toprovide your own terrain shading routine

#Note that since you define your textures withinthe material this makes the

#WorldTexture and DetailTexture settingsredundant

 

#The name of the vertex program parameter youwish to bind the morph LOD factor to

#this is 0 when there is no adjustment (highest)to 1 when the morph takes it completely

#to the same position as the next lower LOD

#USE THIS IF YOU USE HIGH-LEVEL VERTEX PROGRAMSWITH LOD MORPHING

#MorphLODFactorParamName=morphFactor

 

#The index of the vertex program parameter youwish to bind the morph LOD factor to

#this is 0 when there is no adjustment (highest)to 1 when the morph takes it completely

#to the same position as the next lower LOD

#USE THIS IF YOU USE ASSEMBLER VERTEX PROGRAMSWITH LOD MORPHING

#MorphLODFactorParamIndex=4

 

#The name of the material you will define toshade the terrain

#CustomMaterialName=Ogre/Skin

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值