Thứ Ba, 30 tháng 12, 2014

Ogre3D: Tutorial 2 - Ogre Wiki Tutorial Framework

(Bahao247) - Chào mừng bạn đã đến với Blog của tôi. Ở bài hướng dẫn này chúng ta sẽ tìm hiểu về Ogre3D Framework. 

Quick Download

Dành cho Ogre 1.9 ("Ghadamon")
 Ogre Wiki Tutorial Framework 1.9 - (Windows line endings)
 Ogre Wiki Tutorial Framework 1.9 - (Unix line endings)

Dành Ogre 1.10 ("Xalafu")
 Ogre Wiki Tutorial Framework 1.10 - (Windows line endings)
 Ogre Wiki Tutorial Framework 1.10 - (Unix line endings)



Giới thiệu

Đây là những bước cơ bản để tạo nên một Ogre Wiki Tutorial Framework, chúng ta cùng bắt đầu nhé!

Motivation

Bạn có thể sử dụng các framework chuẩn được cung cấp ở trên hoặc sử dụng Ogre AppWizard (mới có bản Ogre AppWizard 1.8 dành cho VS 2010 và Code::Blocks) và build projects của bạn bằng CMake.

Tổng quát

Framework bao gồm 2 classes: BaseApplication and TutorialApplication.
BaseApplication có chức năng tạo ra hàm createScene() để lớp ứng dụng sử dụng. Nó chỉ là lớp cơ sở và không thể khởi tạo riêng biệt.
TutorialApplication có nguồn gốc từ lớp BaseApplication, và implement những function của createScene().

Cơ chế hoạt động

BaseApplication hoạt động như năm giác quan trong một lớp:
class BaseApplication : public Ogre::FrameListener, public Ogre::WindowEventListener, public OIS::KeyListener, public OIS::MouseListener, OgreBites::SdkTrayListener
  1. Các ứng dụng được tạo từ FrameListener, bao gồm các hàm: frameStarted(), frameRenderingQueued()frameEnded(). Xem thêm tại Basic Tutorial 4.
  2. WindowEventListener là khu vực làm việc của ứng dụng, nó bắt mọi sự kiện  di chuyển / thay đổi kích cỡ và đóng cửa sổ.
  3. OIS library được sử dụng để xử lý đầu vào, bắt sự kiện chính và sự kiện chuột bằng hàm tiếp nhận OIS (KeyListener và MouseListener).
  4. Ngoài ra, còn OgreBites dùng cho GUI widgetscamera handling, GUI.

Vòng đời của 1 ứng dụng

  1. Một Ogre::Root mới được tạo ra.
  2. Đường dẫn tới các tài nguyên (Resource) được đọc từ một tập tin cấu hình (resources_d.cfg).
  3. Cửa sổ cấu hình ứng dụng hiện lên cho phép bạn lựa chọn các thông số và độ phân giải, vv...
  4. Cảnh được được tạo ra.
  5. Camera được tạo ra và thiết lập.
  6. The OgreBites dùng để điều khiển camera được kết nối với các camera.
  7. Một khung nhìn được tạo ra và thiết lập.
  8. Tất cả các nhóm tài nguyên được khởi tạo.
  9. Cảnh được tạo ra.
  10. OIS được khởi tạo và thiết lập.
  11. Ứng dụng tự động bắt các sự kiện chuột và bàn phím.
  12. Ứng dụng tự động bắt các sự kiện từ cửa sổ như đóng hoặc resized.
  13. OgreBites SDKTrays được thiết lập.
  14. Ứng dụng tự động bắt các sự kiện.
  15. Vòn lặp render sẽ được bắt đầu và tiếp tục chạy đến khi thoát ứng dụng.

Walkthrough

MinimalOgre

Cùng bắt đầu với 'MinimalOgre':
MinimalOgre-h
MinimalOgre-cpp
Nó giống với Tutorial Framework Ogre Wiki, nhưng nó chỉ có một lớp là go().
//-----------------------------------------------------------------------------------------------------------------------
bool MinimalOgre::go(void)
{
#ifdef _DEBUG
    mResourcesCfg = "resources_d.cfg";//tập tin chứa đường dẫn tài nguyên
    mPluginsCfg = "plugins_d.cfg";//tập tin cấu hình chứa đường dẫn các plugins
#else
    mResourcesCfg = "resources.cfg";//debug ở chế độ release sẽ dùng 2 tập này
    mPluginsCfg = "plugins.cfg";
#endif
 
    // construct Ogre::Root
    mRoot = new Ogre::Root(mPluginsCfg);//Khởi tạo gốc Root
 
//-------------------------------------------------------------------------------------
    // setup resources
    // Load resource paths from config file
    Ogre::ConfigFile cf;//Load tài nguyên
    cf.load(mResourcesCfg);
 
    // Go through all sections & settings in the file
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
 //Quét qua tất cả các phần và các thiết lập trong tập tin gồm 3 thông số là archName, typeName, secName: VD: "Popular", "FileSystem", "Media/fonts"
//secName là tên của từng phần: khái quát, phổ biến, chung
//typeName là loại tài nguyên được xác định: hệ thống tập tin (thư mục) hoặc //file Zip
//archName là một đường dẫn tuyệt đối đến tài nguyên
    Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
//-------------------------------------------------------------------------------------
    // configure
    // Show the configuration dialog and initialise the system
    // You can skip this and use root.restoreConfig() to load configuration
    // settings if you were sure there are valid ones saved in ogre.cfg
    if(mRoot->restoreConfig() || mRoot->showConfigDialog())
    {
        // If returned true, user clicked OK so initialise
        // Here we choose to let the system create a default rendering window by passing 'true'
        mWindow = mRoot->initialise(true, "MinimalOgre Render Window"); 
//Khởi tạo cửa sổ ứng dụng, tham số thứ 2 là title của cửa sổ
 }
    else
    {
        return false;
    }
//-------------------------------------------------------------------------------//------thiết lập cảnh gắn vào Root----
    // choose scenemanager
    // Get the SceneManager, in this case a generic one
    mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
//-------------------------------------------------------------------------------//------Khởi tạo Overlay---
 // initialize the OverlaySystem (changed for 1.9)
 mOverlaySystem = new Ogre::OverlaySystem();
    mSceneMgr->addRenderQueueListener(mOverlaySystem);
//-------------------------------------------------------------------------------//------Tạo camera và cấu hình các thông số----
    // create camera
    // Create the camera
    mCamera = mSceneMgr->createCamera("PlayerCam");//tên Camera
 
    // Position it at 500 in Z direction
    mCamera->setPosition(Ogre::Vector3(0,0,80));//Vị trí
    // Look back along -Z
    mCamera->lookAt(Ogre::Vector3(0,0,-300));//tầm nhìn
    mCamera->setNearClipDistance(5);//khoảng dịch chuyển
 
    mCameraMan = new OgreBites::SdkCameraMan(mCamera);   // create a default camera controller
//-------------------------------------------------------------------------------------
    // create viewports
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);//Tạo khung nhìn đầu tiên
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));//nền màu đen
 
    // Alter the camera aspect ratio to match the viewport
    mCamera->setAspectRatio(
        Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
//-------------------------------------------------------------------------------------
    // Set default mipmap level (NB some APIs ignore this)
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
//-------------------------------------------------------------------------------------
    // Create any resource listeners (for loading screens)
    //createResourceListener();
//-------------------------------------------------------------------------------------
    // load resources
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
//-------------------------------------------------------------------------------------
    // Create the scene
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
 
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
 
    // Set ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
 
    // Create a light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");
    l->setPosition(20,80,50);
//-------------------------------------------------------------------------------------
    //create FrameListener
    Ogre::LogManager::getSingletonPtr()->logMessage("*** Initializing OIS ***");
    OIS::ParamList pl;
    size_t windowHnd = 0;
    std::ostringstream windowHndStr;
 
    mWindow->getCustomAttribute("WINDOW", &windowHnd);
    windowHndStr << windowHnd;
    pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str()));
 
    mInputManager = OIS::InputManager::createInputSystem( pl );
 
    mKeyboard = static_cast<OIS::Keyboard*>(mInputManager->createInputObject( OIS::OISKeyboard, true ));
    mMouse = static_cast<OIS::Mouse*>(mInputManager->createInputObject( OIS::OISMouse, true ));
 
    mMouse->setEventCallback(this);
    mKeyboard->setEventCallback(this);
 
    //Set initial mouse clipping size
    windowResized(mWindow);
 
    //Register as a Window listener
    Ogre::WindowEventUtilities::addWindowEventListener(mWindow, this);
 
    mInputContext.mKeyboard = mKeyboard;
    mInputContext.mMouse = mMouse;
    mTrayMgr = new OgreBites::SdkTrayManager("InterfaceName", mWindow, mInputContext, this);
    mTrayMgr->showFrameStats(OgreBites::TL_BOTTOMLEFT);
    mTrayMgr->showLogo(OgreBites::TL_BOTTOMRIGHT);
    mTrayMgr->hideCursor();
 
    // create a params panel for displaying sample details
    Ogre::StringVector items;
    items.push_back("cam.pX");
    items.push_back("cam.pY");
    items.push_back("cam.pZ");
    items.push_back("");
    items.push_back("cam.oW");
    items.push_back("cam.oX");
    items.push_back("cam.oY");
    items.push_back("cam.oZ");
    items.push_back("");
    items.push_back("Filtering");
    items.push_back("Poly Mode");
 
    mDetailsPanel = mTrayMgr->createParamsPanel(OgreBites::TL_NONE, "DetailsPanel", 200, items);
    mDetailsPanel->setParamValue(9, "Bilinear");
    mDetailsPanel->setParamValue(10, "Solid");
    mDetailsPanel->hide();
 
    mRoot->addFrameListener(this);
//-------------------------------------------------------------------------------------
    mRoot->startRendering();
 
    return true;
}
//-------------------------------------------------------------------------------

TinyOgre

TinyOgre-h
TinyOgre-cpp
Tiny Ogre không kế thừa bất cứ thứ gì và .
Nó chỉ sử dụng OIS để lấy đầu vào và bắt sự kiện:

//-------------------------------------------------------------------------------
 
bool TinyOgre::go(void)
{
#ifdef _DEBUG
    mResourcesCfg = "resources_d.cfg";
    mPluginsCfg = "plugins_d.cfg";
#else
    mResourcesCfg = "resources.cfg";
    mPluginsCfg = "plugins.cfg";
#endif
 
    // construct Ogre::Root
    mRoot = new Ogre::Root(mPluginsCfg);
 
//-------------------------------------------------------------------------------------
    // set up resources
    // Load resource paths from config file
    Ogre::ConfigFile cf;
    cf.load(mResourcesCfg);
 
    // Go through all sections & settings in the file
    Ogre::ConfigFile::SectionIterator seci = cf.getSectionIterator();
 
    Ogre::String secName, typeName, archName;
    while (seci.hasMoreElements())
    {
        secName = seci.peekNextKey();
        Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
        Ogre::ConfigFile::SettingsMultiMap::iterator i;
        for (i = settings->begin(); i != settings->end(); ++i)
        {
            typeName = i->first;
            archName = i->second;
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
                archName, typeName, secName);
        }
    }
//-------------------------------------------------------------------------------------
    // configure
    // Show the configuration dialog and initialise the system
    // You can skip this and use root.restoreConfig() to load configuration
    // settings if you were sure there are valid ones saved in ogre.cfg
    if(mRoot->restoreConfig() || mRoot->showConfigDialog())
    {
        // If returned true, user clicked OK so initialise
        // Here we choose to let the system create a default rendering window by passing 'true'
        mWindow = mRoot->initialise(true, "TinyOgre Render Window");
    }
    else
    {
        return false;
    }
//-------------------------------------------------------------------------------------
    // choose scenemanager
    // Get the SceneManager, in this case a generic one
    mSceneMgr = mRoot->createSceneManager(Ogre::ST_GENERIC);
//-------------------------------------------------------------------------------------
    // create camera
    // Create the camera
    mCamera = mSceneMgr->createCamera("PlayerCam");
 
    // Position it at 500 in Z direction
    mCamera->setPosition(Ogre::Vector3(0,0,80));
    // Look back along -Z
    mCamera->lookAt(Ogre::Vector3(0,0,-300));
    mCamera->setNearClipDistance(5);
 
//-------------------------------------------------------------------------------------
    // create viewports
    // Create one viewport, entire window
    Ogre::Viewport* vp = mWindow->addViewport(mCamera);
    vp->setBackgroundColour(Ogre::ColourValue(0,0,0));
 
    // Alter the camera aspect ratio to match the viewport
    mCamera->setAspectRatio(
        Ogre::Real(vp->getActualWidth()) / Ogre::Real(vp->getActualHeight()));
//-------------------------------------------------------------------------------------
    // Set default mipmap level (NB some APIs ignore this)
    Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(5);
//-------------------------------------------------------------------------------------
    // Create any resource listeners (for loading screens)
    //createResourceListener();
//-------------------------------------------------------------------------------------
    // load resources
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
//-------------------------------------------------------------------------------------
    // Create the scene
    Ogre::Entity* ogreHead = mSceneMgr->createEntity("Head", "ogrehead.mesh");
 
    Ogre::SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
    headNode->attachObject(ogreHead);
 
    // Set ambient light
    mSceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
 
    // Create a light
    Ogre::Light* l = mSceneMgr->createLight("MainLight");
    l->setPosition(20,80,50);
//-------------------------------------------------------------------------------------
 
    while(true)
    {
        // Pump window messages for nice behaviour
        Ogre::WindowEventUtilities::messagePump();
 
        if(mWindow->isClosed())
        {
            return false;
        }
 
        // Render a frame
        if(!mRoot->renderOneFrame()) return false;
    }
 
    // We should never be able to reach this corner
    // but return true to calm down our compiler
    return true;
}

//-------------------------------------------------------------------------------

LowLevelOgre

LowLevelOgre-h
LowLevelOgre-cpp

Cài đặt

//-------------------------------------------------------------------------------
 
// construct Ogre::Root : no plugins filename, no config filename, using a custom log filename
mRoot = new Ogre::Root("", "", "LowLevelOgre.log");
 
// A list of required plugins
Ogre::StringVector required_plugins;
required_plugins.push_back("GL RenderSystem");
required_plugins.push_back("Octree & Terrain Scene Manager");
 
// List of plugins to load
Ogre::StringVector plugins_toLoad;
plugins_toLoad.push_back("RenderSystem_GL");
plugins_toLoad.push_back("Plugin_OctreeSceneManager");
 
// Load the OpenGL RenderSystem and the Octree SceneManager plugins
for (Ogre::StringVector::iterator j = plugins_toLoad.begin(); j != plugins_toLoad.end(); j++)
{
#ifdef _DEBUG
    mRoot->loadPlugin(*j + Ogre::String("_d"));
#else
    mRoot->loadPlugin(*j);
#endif;
}
 
// Check if the required plugins are installed and ready for use
// If not: exit the application
Ogre::Root::PluginInstanceList ip = mRoot->getInstalledPlugins();
for (Ogre::StringVector::iterator j = required_plugins.begin(); j != required_plugins.end(); j++)
{
    bool found = false;
    // try to find the required plugin in the current installed plugins
    for (Ogre::Root::PluginInstanceList::iterator k = ip.begin(); k != ip.end(); k++)
    {
        if ((*k)->getName() == *j)
        {
            found = true;
            break;
        }
    }
    if (!found)  // return false because a required plugin is not available
    {
        return false;
    }
}

//-------------------------------------------------------------------------------

Danh sách plugin names and render system names:
BSPSceneManager PluginName = "BSP Scene Manager"
OgreCgPlugin PluginName = "Cg Program Manager"
OgreOctreePlugin PluginName = "Octree & Terrain Scene Manager"
OctreeZone PluginName = "Octree Zone Factory"
OgreParticleFXPlugin PluginName = "ParticleFX"
PCZSceneManager PluginName = "Portal Connected Zone Scene Manager"
Direct3D10 PluginName = "D3D10 RenderSystem"
OgreD3D11Plugin PluginName = "D3D11 RenderSystem"
OgreD3D9Plugin PluginName = "D3D9 RenderSystem"
OgreGLPlugin PluginName = "GL RenderSystem"
OgreGLESPlugin PluginName = "OpenGL ES 1.x RenderSystem"

OgreD3D10RenderSystem Name = "Direct3D10 Rendering Subsystem"
Direct3D11 Name = "Direct3D11 Rendering Subsystem"
Direct3D9 Name = "Direct3D9 Rendering Subsystem"
GL Name = "OpenGL Rendering Subsystem"
GLES Name = "OpenGL ES 1.x Rendering Subsystem"
OgreOctreePlugin PluginName = "Octree Scene Manager"

Tài  nguyên

// setup resources
// Only add the minimally required resource locations to load up the Ogre head mesh
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/materials/programs", "FileSystem", "General");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/materials/scripts", "FileSystem", "General");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/materials/textures", "FileSystem", "General");
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("../../media/models", "FileSystem", "General");

Cấu hình

Chúng ta có thể sử dụng OpenGL Rendering Subsystem, với độ phân giải màn hình là 800x600 với vsync tắt:
// configure
// Grab the OpenGL RenderSystem, or exit
Ogre::RenderSystem* rs = mRoot->getRenderSystemByName("OpenGL Rendering Subsystem");
if(!(rs->getName() == "OpenGL Rendering Subsystem"))
{
    return false; //No RenderSystem found
}
// configure our RenderSystem
rs->setConfigOption("Full Screen", "No");
rs->setConfigOption("VSync", "No");
rs->setConfigOption("Video Mode", "800 x 600 @ 32-bit");
 
mRoot->setRenderSystem(rs);
 
mWindow = mRoot->initialise(true, "LowLevelOgre Render Window");

Tổng  kết

Đây là nội dung cơ bản về Ogre Wiki Tutorial Framework. Ở bài tới, ta sẽ bắt tay vào xây dựng ứng dụng đầu tiên. :-)

Đăng nhận xét

Credits Credits