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