我的OGRE学习记录

ogre cookbook:

experience

linux 下环境搭建:

http://blog.sina.com.cn/s/blog_753f4e5f010141th.html

windows下:

http://www.cppblog.com/Cunch/archive/2011/03/01/140770.html


一、basic tutorial1:

ogre三大基础class:Ogre::SceneManager, Entity, SceneNode

SceneManager记录该场景中创建的各种对象的位置并track them(plane, entity, light, billboard...),scenemanager有很多类型,适合于不同场景,具体见 http://www.ogre3d.org/tikiwiki/tiki-index.php?page=SceneManagersFAQ

scenenode和entity相互依靠,由scenenode建立树形的场景信息,由entity负责可视化物体的信息。entity较为简单,操作很少(getParentNode, getName, setVisible等),移动的信息主要靠scenenode实现


二、basic tutorial2: camera light and shadow

1. camera是用来提供一个视点来裁剪场景中的物体。camera是和scene manager一一对应的,一个Ogre程序中可以有超过一个scene manager,相应的camera也可以有多个。但是为了显示一个camera中裁剪的物体,必须提供一个viewport。

camera的设置:setPosition, lookAt, setNearClipDistance。从函数名字就可以知道用处,Ogre默认的远裁剪面是无穷远处。

根据viewport的宽高比,camera也需要进行这样的设置来保证场景不失真。

2.viewport的设置,需要设置背景色:setBackgroundColour

3.shadows

shadows其实就是纹理,但是难点在于如何产生这个纹理。现在已经有很多的算法和论文在讨论,但是大多数都不是很理想,因为需要在效果和效率之间取得一个平衡是一件比较困难的事情。

ogre支持三种类型的shadows:

Ogre::SHADOWTYPE_TEXTURE_MODULATIVE:花销最小的shadow类型,会产生一个黑白的RTT纹理应用于场景;

Ogre::SHADOWTYPE_STENCIL_MODULATIVE:“调整”类型的shadow,它会在所有非透明的物体绘制完毕后才开始绘制,效果不是很理想;

Ogre::SHADOWTYPE_STENCIL_ADDITIVE:这种类型的shadow产生的效果最好,但是开销也较大。它需要为每个光照一个pass来处理场景中的所有物体的纹理。

如何使用shadows:

先需要为场景增加光线,没有光线shadow是虚谈;然后需要设置投影类型,就是上面介绍的三种类型,如果三种类型都不符合自己的想法,则需要自己写shader程序来产生自己想要的效果。

mSceneMgr->setAmbientLight(Ogre::ColourValue(0, 0, 0));
mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);

然后需要为需要产生投影的entity进行设置:

entNinja->setCastShadows(true);

4.light

光照是一个非常值得研究的一个issue,各种引擎中非常值得炫耀的一个部分就是光照效果的处理。各种论文也是层出不穷。OpenGL中提供了三种不同类型的光照,分别是点光源,聚光灯光源和直线型光源。这三种类型的光源是非常具有代表性的,Ogre也是默认提供了这三种类型的光照。

Ogre支持的光照类型:

Ogre::Light::LT_POINT:点光源,这个是模拟太阳的效果,各个方向都是相同强度的光照;

Ogre::Light::LT_SPOTLIGHT:聚光灯类型,这个是模拟手电筒类型的光照,一个圆锥形式的光照区域;

Ogre::Light::LT_DIRECTIONAL:方向型光照,这个是模拟激光灯的效果的光照。

光照的使用:设置光照的类型,方向和颜色

Ogre::Light* pointLight = mSceneMgr->createLight("pointLight");
    pointLight->setType(Ogre::Light::LT_POINT);
    pointLight->setPosition(Ogre::Vector3(0, 150, 250));
pointLight->setDiffuseColour(1.0, 0.0, 0.0);
    pointLight->setSpecularColour(1.0, 0.0, 0.0);


旋转的三个函数有点难记住,使用这个图可以记住。




animation

http://blog.csdn.net/leonwei/article/details/5819248


node animation

node animation的使用涉及到了oge组织动画的整个细节:一个animation由多个track组成,一个track中可以有多个keyframe, 通过创建一个与animation同名的animationstate对象来控制创建的动画对象。

anim = mSceneMgr->createAnimation(name, len);

anim->setInterpolationMode(Animation::IM_SPLINE);

key0 = anim->createNodeKeyFrame(time);

key0->setTranslate(...)...

animationState = mSceneMgr->createAnimationState(name);


skeleton animation

http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Intermediate+Tutorial+1&structure=Tutorials


skeleton animation需要有mesh 和 skeleton文件的支持,动画信息是在mesh里面的;使skeleton animation动起来很简单,就是获取Ogre::AnimationState对象的指针,然后setEnable, setLoop, 最后在frameQueued函数脸面addTime(evt.timeSinceLastFrame)


morph animation

http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Morph+animation

morph animation属于vertex animation, morph animation信息是在mesh里面的,使用morph animaion只需要通过entity获取其animation state指针,然后通过这个指针setEnable, addTime即可


ogre model info

http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Ogre+Models

里面有各个model的详细信息,包括face数目,vertex数目以及动画的名称,备查看


ogre 如何设置摄像头的方向始终正确

http://blog.csdn.net/kira8dao7/article/details/6309671

在第一场景类的游戏中,CAMERA的操作应该只有两种,一种是移动,平移,当然可以上下左右平移;另一种是yaw,即绕着自己的y轴进行旋转。

所以,对摄像头的操作应该只有translate和yaw.

但是有时候,场景中的地图文件的坐标系和ogre默认的坐标系并不是相同的,比如说Quake3地图,其中的坐标系是z轴朝上,此时若调用yaw则势必会引起view的混乱

解决办法:使用Camare类的void setFixedYawAxis( bool useFixed, const Vector3& fixedAxis = Vector3::UNIT_Y )方法进行设置yaw函数的默认操作,useFixed设置为true, fixedAxis设置为Vector3::UNIT_Z即可满足要求。

还有一个通用的要求是保持摄像机的位置始终在地面上,并且在地面上面的某个位置,这种要求可以通过在frameQueued函数里面通过光线查询来实现。

http://www.4ucode.com/Study/Topic/1489657

我在tutorial3中实现了该功能,确实好玩

首先定义 RaySceneQuery* raySceneQuery = 0;(TutorialApplication.h中) 

1. 在CreateScene时候,创建场景查询
2. frameRenderingQueued事件中,进行射线查询,设定摄像机位置
1. createScene中创建
  raySceneQuery = mSceneMgr->createRayQuery(

            Ray(mCamera->getPosition(), Vector3::NEGATIVE_UNIT_Y));//光线的位置和方向,垂直向下

2.  然后在TutorialApplication.cpp中重写frameRenderingQueued函数,其中加入对摄像机的检测,若低于地面则将camera拉到地面上面10个单位处

    bool frameRenderingQueued(const FrameEvent& evt)

    {

        if( ExampleFrameListener::frameRenderingQueued(evt) == false )

         return false;

        // clamp to terrain

        static Ray updateRay;

        updateRay.setOrigin(mCamera->getPosition());

        updateRay.setDirection(Vector3::NEGATIVE_UNIT_Y);

        raySceneQuery->setRay(updateRay);

        RaySceneQueryResult& qryResult = raySceneQuery->execute();

        RaySceneQueryResult::iterator i = qryResult.begin();

        if (i != qryResult.end() && i->worldFragment)

        {//和场景相交,并且得到的迭代器不为空

            mCamera->setPosition(mCamera->getPosition().x,

                i->worldFragment->singleIntersection.y + 10,

                mCamera->getPosition().z);

        }

    

        return true;

 }

这样就把摄像机设在离地形高10个单位的地方。

ogre 射线场景查询

http://blog.csdn.net/xiaozhi0999/article/details/3062910

http://blog.csdn.net/lsldd/article/details/5424970


OIS 鼠标非独占(调试程序的时候有用,强制关机了3次)

在BaseApplication中加入一些语句就可以实现了

http://blog.csdn.net/yacper/article/details/5277351/

linux版本和windows版本均有实现


ogre scenemanager的选取:

ST_GENERIC:最简单的场景管理器的构造器类型,其场景管理器没有对场景内容和结构做任何优化。在极其简单的场景中(例如菜单界面)中才有其价值

ST_INTERIOR:这种场景管理器的构造器所产生的管理器,优化了室内近距离的渲染,比较适合高密度的场景

ST_EXTERIOR_CLOSE:优化了室外场景里面的中近距离可视体,比较适合用一个简单模型或者高度场产生的场景地图

ST_EXTERIOR_REAL_FAR:这种类型的场景管理器特别适合那种需要动态加载的地形或者场景。动态加载的地形通常都非常巨大,甚至可能描绘了个星球的地貌



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值