我的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:這種類型的場景管理器特別適合那種需要動態加載的地形或者場景。動態加載的地形通常都非常巨大,甚至可能描繪了個星球的地貌



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章