?? jichu4.txt
字號:
目錄 [隱藏]
1 先決條件
2 介紹
3 從這開始
4 幀監聽
4.1 介紹
4.2 注冊一個幀監聽
5 建立場景
5.1 介紹
5.2 代碼
6 幀監聽指南
6.1 變量
6.2 構造器
6.3 幀啟動方法
[編輯]先決條件
本教程假定你已經擁有了c++程序設計的知識,并且已經安裝和編譯了一個Ogre的應用程序(如果你在設置你的應用程序中有困難,請參考this guide獲得更詳細的編譯步驟)。這個教程同時也是建立在上一章基礎上的,因此默認你已經了解了上個教程的內容。
[編輯]介紹
這一章我們將介紹Ogre中最有用的構造:幀監聽(FrameListener)。在本指南最后你將了解幀監聽,怎樣運用幀監聽去實現一些要求每一幀更新的東西,怎樣去用Ogre的無緩沖輸入系統。
代碼你都可以在這篇指南中找到。當你看完這篇教程以后,你應該試著慢慢的添加一些代碼到你自己的工程里,然后看看結果。
[編輯]從這開始
像上一個教程一樣,我們將使用一個先前建立的代碼作為我們出發的起點。在編譯器中創建一個工程,添加如下的源代碼:
#include "ExampleApplication.h"
class TutorialFrameListener : public ExampleFrameListener
{
public:
TutorialFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneMgr)
: ExampleFrameListener(win, cam, false, false)
{
}
bool frameStarted(const FrameEvent &evt)
{
return ExampleFrameListener::frameStarted(evt);
}
protected:
bool mMouseDown; // Whether or not the left mouse button was down last frame
Real mToggle; // The time left until next toggle
Real mRotate; // The rotate constant
Real mMove; // The movement constant
SceneManager *mSceneMgr; // The current SceneManager
SceneNode *mCamNode; // The SceneNode the camera is currently attached to
};
class TutorialApplication : public ExampleApplication
{
public:
TutorialApplication()
{
}
~TutorialApplication()
{
}
protected:
void createCamera(void)
{
}
void createScene(void)
{
}
void createFrameListener(void)
{
}
};
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
#else
int main(int argc, char **argv)
#endif
{
// Create application object
TutorialApplication app;
try {
app.go();
} catch(Exception& e) {
#if OGRE_PLATFORM == PLATFORM_WIN32 || OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox(NULL, e.getFullDescription().c_str(), "An exception has occurred!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
fprintf(stderr, "An exception has occurred: %s\n",
e.getFullDescription().c_str());
#endif
}
return 0;
}
如果你是在Windows下使用OgreSDK的,請確定添加“"[OgreSDK_DIRECTORY]\samples\include”目錄到這個工程(ExampleApplication.h文件所在的位置)除了標準包含以外。如果使用的是Ogre的源代碼包,這個文件應該在“"[OgreSource_DIRECTORY]\Samples\Common\include”目錄中。不要試著去運行程序,因為我們還沒有定義鍵盤的行為。如果你有問題,請查看這個Wiki頁獲得設置你編譯器的信息,如果仍然有問題請試著去看看幫助欄。
我們將在這章中定義程序控制器。
[編輯]幀監聽
[編輯]介紹
在前面的指南中當我們添加代碼到創建場景方法時候,我們僅僅考慮我們可以做什么。在Ogre中我們可以注冊一個類去接收消息當一幀被渲染到屏幕之前和之后。FrameListener接口定義兩個函數:
bool frameStarted(const FrameEvent& evt)
bool frameEnded(const FrameEvent& evt)
Ogre的主循環(Root::startRendering)類似這樣:
Root object調用frameStarted方法在所有已經注冊的FrameListeners中。
Root object渲染一幀。
Root object調用frameEnded方法在所有已經注冊的FrameListeners中。
這個循環直到有任意一個FrameListener的frameStarted或者frameEnded函數返回false時終止。這些函數返回值的主要意思是“保持渲染”。如果你返回否,這個程序將退出。FrameEvent實體包含兩個參數,但是只有timeSinceLastFrame在幀監聽中是有用的。這個變量了解frameStarted或者frameEnded最近被激活時間。注意在frameStarted方法中,FrameEvent::timeSinceLastFrame將包含frameStarted時間最近被激活的時間(而不是最近被激活的frameEnded方法)。
一個重要的概念你不能決定那個FrameListener被調用的次序。如果你需要確定FrameListeners被調用的準確順序,你應該只注冊一個FrameListener,然后用適當的順序來調用所有的物體。
你應該也會注意到主循環事實上做了三件事,在frameEnded方法和frameStarted方法被調用中間什么都沒有發生,你甚至可以換著用。你的代碼也可以隨你放哪。你可以放到一個大的frameStarted或者frameStarted方法中,也可以插到兩者之間。
[編輯]注冊一個幀監聽
現在上面的代碼是可以編譯通過的,但是因為我們沒有考慮在ExampleApplication和createCamera中創建幀監聽,因此如果你運行這個程序你就無法結束她。在繼續本指南其他內容之前我們將先解決這個問題。
找到TutorialApplication::createCamera方法添加如下代碼:
// create camera, but leave at default position
mCamera = mSceneMgr->createCamera("PlayerCam");
mCamera->setNearClipDistance(5);
除了最基本的之外我們什么都沒有做。之所以我們要用ExampleApplication中的createCamera方法是因為createCamera方法可以用來移動相機和改變相機位置,這里我們詳細討論這個。
因為Root類是要每幀更新的,他也了解FrameListeners。我們首先要創建TutorialFrameListener的實例,然后把他注冊到Root對象中。代碼如下:
// Create the FrameListener
mFrameListener = new TutorialFrameListener(mWindow, mCamera, mSceneMgr);
mRoot->addFrameListener(mFrameListener);
mRoot和mFrameListener變量是在ExampleApplication類中定義的。addFrameListener方法添加一個幀監聽者,removeFrameListener方法移除幀監聽者(也就是說FrameListener就不用在更新了)。注意add|removeFrameListener方法僅僅是得到一個指向FrameListener的指針(也就是說FrameListener并沒有一個名字你可以移除她)。這就意味著你需要對每一個FrameListener持有一個指針,讓你隨后可以移除他們。
這個ExampleFrameListener(我們的TutorialFrameListener是從它繼承來的),還提供了一個showDebugOverlay(bool)方法,用來告訴ExampleApplication是否要在左下角顯示幀率的提示框。我們會把它打開:
// Show the frame stats overlay
mFrameListener->showDebugOverlay(true);
確定你可以編譯和運行這個應用程序再繼續。
[編輯]建立場景
[編輯]介紹
在我們對代碼的深入研究之前,我將簡單介紹一下我將做什么,這樣你可以了解當我們創建和添加一些東西到場景中去的目的。
我們將把一個物體(一個忍者)放到屏幕中,并在場景中加上點光源。當你點擊鼠標左鍵,燈光會打開或關閉。按住鼠標右鍵,則開啟“鼠標觀察”模式(也就是你用攝像機四處觀望)。我們將在場景里放置場景節點,來讓作用于不同視口的攝像機附在上面。按下1、2鍵,以選擇從哪一個視口來觀看場景。
[編輯]代碼
找到TutorialApplication::createScene方法。首先我們需要把場景的環境光設置的很低。我們想要場景中物體在燈光關閉情況下仍然可見,而且我們仍然想做到在燈光開關時場景有所變化:
mSceneMgr->setAmbientLight(ColourValue(0.25, 0.25, 0.25));
現在把一個忍者加到屏幕中去:
Entity *ent = mSceneMgr->createEntity("Ninja", "ninja.mesh");
SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaNode");
node->attachObject(ent);
現在我們創建一個白色燈讓后放到場景中,和忍者有一個相對小距離:
Light *light = mSceneMgr->createLight("Light1");
light->setType(Light::LT_POINT);
light->setPosition(Vector3(250, 150, 250));
light->setDiffuseColour(ColourValue::White);
light->setSpecularColour(ColourValue::White);
現在需要創建場景節點供攝像機綁定:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -