OGRE基礎教程一:OGRE最基本的組成結構:SceneManager,SceneNode和Entity objects

文獻來源網址:http://www.ogre3d.org/tikiwiki/tiki-index.php?page=Basic+Tutorial+1&structure=Tutorials

    導言:

    在本節教程中,我們將會向您介紹OGRE最基本的組成結構:場景管理器(SceneManager),場景節點(SceneNode)和實體對象(Entity objects),我們不會涉及大量的源代碼,相反地,由於開始學習OGRE,我們會着重給你介紹幾本概念。

    當您瀏覽本教程的時候,你可以慢慢地將代碼加入到你自己的項目,然後查看編譯結果。沒有比實際編程更好的方法去熟悉這些概念,如果你僅僅是閱讀,我勸你還是打住你的念頭吧。(個人注:實踐是學習編程最好的方法)

    預備知識:

    1,本教程假設你已經擁有C++知識和能夠建立和編譯OGRE運用程序

     2,本教程假設你已經用 Ogre Wiki Tutorial Framework創建了一個工程,或者,手動地,用CMake或者Ogre運用程序嚮導--請查看Setting Up An Application 使用說明  

開始:

    從這裏開始在這篇教程裏,我們將使用已經寫好的代碼作爲模版。除了我們將要在createScene函數裏面添加的代碼之外,您可以暫時忽略其他的東西。在後面的教程裏我會深入講解OGRE程序是如何工作的,現在我們只需要從最簡單的地方學起就行了。在您的IDE創建一個名叫Tutorial工程,然後把教程運用程序框架(tutorial application framework)下面的代碼添加進去:

BaseApplication.h
BaseApplication.cpp
TutorialApplication.h
TutorialApplication.cpp

    從這裏獲取以上文件: Ogre Wiki Tutorial Framework 
    或者,使用Ogre AppWizard(external link).

    TutorialApplication.cpp是本教程中我們唯一使用的文件,並且我們只在成員函數createScene()進行工作。

    TutorialApplication.cpp應當包含以下代碼 

   

#include "TutorialApplication.h"
 
TutorialApplication::TutorialApplication(void)
{
}
 
TutorialApplication::~TutorialApplication(void)
{
}
 
//-------------------------------------------------------------------------------------
void TutorialApplication::createScene(void)
{
    // Set the scene's ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));
 
    // Create an Entity
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
 
    // Create a SceneNode and attach the Entity to it
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");
    headNode->attachObject(ogreHead);
 
    // Create a Light and set its position
    Ogre::Light* light = mSceneMgr->createLight("MainLight");
    light->setPosition(20.0f, 80.0f, 50.0f);
}
 
 
 
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif
 
#ifdef __cplusplus
extern "C" {
#endif
 
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
    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( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
            MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR| MB_TASKMODAL);
#else
            std::cerr << "An exception has occured: " << e.getFullDescription().c_str() << std::endl;
#endif
        }
 
        return 0;
    }
 
#ifdef __cplusplus
}
#endif


    繼續編譯和運行這個程序,當然你要保證你的環境配置正確的,一旦你的程序是正常運行起來,使用WASD鍵移動,鼠標鍵用來環顧四周,ESC鍵退出程序。

   

    個人注:在IDE中創建工程時,可以選擇控制檯,也可以選擇win32。

    小細節:上面可以看出,average  fps 有個fps重疊的字符串fps,這應該是個bug,修改文件SdkTray.h,將2768行與2774行中的 values.push_back(s); 改爲values.push_back(str);修改後運行的截圖:多出來的fps字符串沒有了,感覺清爽多了,微笑

   

解決問題:

    如果你有問題,請檢查下運用程序的設置使你的編譯器配置正確,或者查看Ogre.log文件獲取更多的詳細信息。如果你需要幫助。可以去搜索論壇(http://www.ogre3d.org/forums/search.php),可能你的問題,別人已經遇到了很多次。如果這是一個新的問題,閱讀論壇規則,然後再問。確保從您的Ogre.log提供相關細節,異常,錯誤消息,和/或調試後的痕跡。

    需要注意的是以後的教程中,將不包含此類問題解決的信息,所以請如果您有問題,要特別注意以下幾個部分。

    1,MessageBox的問題

    如果你使用支持UNICODE字符集的VS,你可能會遇到如下問題:

error C2664: 'MessageBoxW' : cannot convert parameter 2 from 'const char *' to 'LPCWSTR'
         Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or  function-style cast

    這個問題是MessageBox函數(在這種情況下)是期待的是Unicode類型的字符串(個人注:此時的形參的類型必須是寬字符類型的),而我們給的是你ANSI字符串,修正這個錯誤,我們只需要修改下面的代碼

MessageBox( NULL, e.what(), "An exception has occurred!", MB_OK |   MB_IConerror  | MB_TASKMODAL);

爲:

MessageBoxA( NULL, e.what(), "An exception has occurred!", MB_OK |   MB_IConerror  | MB_TASKMODAL);

     或者,你也可以將編譯器的字符集從Unicode改爲ANSI,然後,你這樣做,會失去國際語言的支持。

    這樣做的原因是,"MessageBox "將被自動解析爲,要麼是MessageBoxA(ANSI),要麼是MessageBoxW(寬/ Unicode),根據項目配置,我們明確它使用ANSI修復該錯誤。

   2,缺失配置文件或者dll

    如果你試圖啓動你剛生成的應用程序,但該程序報錯,缺少DLL或配置文件(*.cfg),,那麼你可能沒有將它們從OgreSDK的文件夾中複製過來,在VS中,當你在release模式下編譯你的運用程序,它將release版的可執行文件放在[ProjectFolder]\ BIN \ release文件夾中,debug版的可執行文件放在[ProjectFolder] \ BIN \ debug文件夾中。你必須從OgreSDK中複製所有的".dll",".cfg" 的文件到相應的文件夾中。也就是說,將這些文件從[OgreSDK]\ BIN \release 文件夾複製到[ProjectFolder]\ BIN\release文件夾,從[OgreSDK] \ BIN \debug文件夾複製到[ProjectFolder] \ BIN \debug文件夾。您還需要編輯的resources.cfg文件以便指向正確的路徑。想獲取更多信息,請參閱下一節。

    3,資源或插件問題

    確保你有一個plugins.cfg和resources.cfg文件在與可執行文件相同的目錄中。Plugins.cfg告訴OGRE哪個渲染庫是可用的(Direct3D9,OpenGL等)。resources.cfg被ExampleApplication使用,用於指定紋理,網格模型和腳本的路徑。它們兩個都是文本文件,所以可以編輯它們以保證這些路徑是正確的。否則,您的OGRE設置對話框可能沒有任何渲染庫,或者您可能會收到一個錯誤,在你的屏幕上或在Ogre.log文件中,看起來像這樣:

Description: ../../Media/packs/OgreCore.zip - error whilst opening archive: Unable to read zip file

    如果是這種情況,打開你的resources.cfg文件,修改它包含的路徑,使它指向Media文件夾(附帶有食人魔(Ogre))的位置。注意:您不能使用環境變量在這些路徑上,例如$(SomeVariable)。

ogre是怎麼工作的?

    OGRE是怎樣工作的這是一個很廣的話題,我們將從場景管理器開始然後進一步瞭解場景節點和實體。這三個類是所有OGRE程序的基石。

     1,場景管理器基礎:

     在屏幕上顯示的所有東西都是由場景管理器來管理。當您在場景中添加物體時,場景管理器會記錄這些物體的位置。當您添加攝像機來觀看某個場景時,場景管理器會記錄攝像機的位置。當您添加平面、廣告牌、燈光時,場景管理器同樣會管理他們。 OGRE裏有很多種場景管理器。有的場景管理器渲染地面,有的場景管理器渲染BSP表等等。在後面,我們將進一步瞭解場景管理器。

     2,實體基礎:

    一個實體是可以在場景中渲染的物體之一。您可以把實體理解爲任何一個3D模型。一個機器人可以是一個實體,一條魚可以是一個實體,大地草原可以是一個非常大的實體。燈光,攝像機,粒子,廣告牌等不能成爲實體。

    關於OGRE需要注意的一點是,它從對象的位置和方向分離出渲染對象,這就意味着,在 Ogre中你不能夠直接將一個實體放入到場景中,而是將實體與場景節點綁在一起,這個場景節點則包括了實體的方位信息。

     3,場景節點基礎:

    場景節點將持續跟蹤與它綁在一起的實體的方位。當你創建了一個實體時,它直到與一個場景節點綁定後纔會被渲染。同樣,一個場景節點也不能單獨的在屏幕上顯示出來,只有與一個實體綁定後才能在屏幕上顯示。

    場景節點可以綁定多個實體。例如在屏幕上有在行走的一個人物對象,並且希望這個對象產生髮光效果,要實現這些,首先你需要創建一個場景節點,然後再創建一個人物對象的實體並與場景節點綁定在一起,之後你還需要創建一個光照模型也與這個場景節點綁定在一起。場景節點同樣可以與其它場景節點綁定以描述更完整的對象。我們在後續的章節中介紹場景節點更多的用法。

    在場景中,場景節點的位置總是與它的父節點相關。每一個場景管理器都包含一個根節點。

你的第一個OGRE程序

    返回到我們剛纔創建的代碼,找到 TutorialApplication::createScene成員函數。首先需要爲整個場景設置環境光,這樣纔可以看到要顯示的內容,通過調用setAmbientLight函數並指定環境光的顏色就可以做到這些。指定的顏色由紅、綠、藍三種顏色組成,且每種色數值範圍在01之間。將下一句添加到 createScene 中:

mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5f, 0.5f, 0.5f));

    下一步創建一個 Entity,通過調用 SceneManager createEntity 方法來創建:

Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");

    好的,一些問題需要提出來,首先,mSceneMgr來自哪裏?我們調用函數的參數是什麼?mSceneMgr變量是當前場景管理器對象(這個是BaseApplication類爲我們做的)。createEntity函數的第一個參數是我們創建實體對象的名字,所有的實體必須有唯一的名字,如果你創建兩個名字相同的實體對象,你會得到一個錯誤,第二個參數 "ogrehead.mesh" 指明我們用於實體的網格模型,"ogrehead.mesh"是一個來自Ogre SDK的資源。資源加載和網格模型將會在後面的教程中涉及,現在,我們直接使用具有資源加載能力的BaseApplication類。我們已經創建了一個實體,但還需要創建一個場景節點來與它綁定在一起。既然每個場景管理器都有一個根節點,那我們就在根節點下創建一個場景節點。

Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("HeadNode");

    這句代碼首先調用場景管理器的 getRootSceneNode方法來獲取根節點,再使用根節點的 createChildSceneNode方法創建一個名爲"HeadNode"的場景節點。與實體一樣,場景節點的名字也是唯一的。

    然後,將實體綁定到場景節點,指定了Ogre Head渲染位置

headNode->attachObject(ogreHead);

    儘管燈光知道下一個章節纔會涉及,但是,我們在這裏添加一個燈光,這樣我們看到模型帶有適當的陰影,而不是來自自然光的平坦陰影,當我們創建燈光時,我們也要給一個唯一的名字。

Ogre::Light* light = mSceneMgr->createLight( "MainLight" );

    一旦燈光被創建,可以用setPosition函數設置它的位置,。給定的這三個參數是要設置的新的位置的X,Y和Z座標。座標將在下面詳細討論。

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

    編譯運行你的程序,你將會在屏幕中看到食人魔的頭像。

   

座標與向量

    待續.....

 

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