Базове керівництво 6, ogre3d

КОРОТКИЙ ВСТУП

У цьому туторіали в дізнаєтесь як написати просте Ogre додаток з нуля.

необхідні знання

Це керівництво має на увазі, що у вас є знання програмування на C ++, і ви в змозі встановити і скомпілювати програму за допомогою Ogre.
Це керівництво також має на увазі, що ви створили проект, використовуючи Ogre Wiki Tutorial Framework, або вручну, використовуючи CMake або Ogre AppWizard.
Цей підручник базується на попередніх і має на увазі, що ви працювали з ними.

Початковий код

У цьому туторіали порожній каркас стане для нас відправною точкою.

ПОПЕРЕДЖЕННЯ

Перш ніж продовженням переконайтесь, що проект налаштований, і що він має два файли: заголовки і cpp.
Якщо ви використовували Ogre Tutorial Wiki Framework, видаліть з нього BaseApplication.h і BaseApplication.cpp.

  1. class BasicTutorial6
  2. public:
  3. BasicTutorial6 (void);
  4. virtual
  1. #include "BasicTutorial6.h"
  2. #include
  3. // -----------------------------
  4. BasicTutorial6 :: BasicTutorial6 (void)
  5. >
  6. // -----------------------------
  7. BasicTutorial6 ::
BasicTutorial6 (void)
  • >
  • bool BasicTutorial6 :: go (void)
  • return true;
  • >
  • #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
  • BasicTutorial6 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: " <
  • #endif
  • >
  • return 0;
  • >
  • #ifdef __cplusplus
  • >
  • #endif
  • Переконайтеся, що ви можете скомпілювати цей код, перш ніж продовжувати. Код буде взагалі нічого не робити - програма буде виходити відразу після запуску.

    Не хвилюйтеся, після того як пройдемо через це керівництво, ми вийдемо на повнофункціональні Ogre додаток.

    Процес запуску зсередини

    Як тільки ви зрозумієте, що за процеси приховані від ваших очей, працювати з Ogre стане набагато легше. Каркас прикладу буде виглядати досить складним, оскільки він намагається зробити багато речей, які можуть бути і не потрібні для вашого застосування, але це тільки на перший погляд. Після завершення цього уроку, ви зможете вибрати те, що дійсно необхідно для вашого застосування. Перш ніж заглибитися в усі це, ми спочатку зробимо короткий огляд того, як працює процес запуску.

    Базовий життєвий цикл Ogre виглядає подібно до цього:

    1. Створити кореневої об'єкт (root)
    2. Визначити ресурси які Ogre буде використовувати
    3. Вибрати і налаштувати систему рендеринга (DirectX, OpenGL, і так далі)
    4. Створити вікно рендеринга (RenderWindow) (вікно, яке використовує Ogre для відображення)
    5. Ініціалізувати всі ресурси які ви будете використовувати
    6. Створити сцену з цих ресурсів
    7. Налаштувати всі інші бібліотеки та плагіни
    8. Створити будь-яку кількість обробників кадрів
    9. Запустити цикл відображення

    У цьому уроці ми пройдемося по кожному пункту поглиблено.

    запуск Ogre

    Створення кореневого об'єкта

    Кореневої об'єкт є ядром движка OGRE, і повинен бути створений перш ніж ви почнете щось робити з двигуном.

    Нам потрібно додати наступні члени в клас BasicTutorial6:

    1. private:
    2. Ogre :: Root * mRoot;
    3. Ogre :: String mPluginsCfg;
    1. bool BasicTutorial6 :: go (void)
    2. #ifdef _DEBUG
    3. mPluginsCfg = "plugins_d.cfg";
    4. #else
    5. mPluginsCfg = "plugins.cfg";
    6. #endif
    7. // Ogre :: Root
    8. mRoot = new Ogre :: Root (mPluginsCfg);
    9. return true;
    10. >

    Конструктор класу Ogre :: Root приймає три параметри:

    pluginFileName ( "plugins.cfg") - повний шлях до файлу де прописані всі плагіни.
    configFileName ( "ogre.cfg") - повний шлях до файлу конфігурації
    logFileName ( "Ogre.log") - повний шлях до файлу журналу движка в який OGRE записує все що відбувається всередині.

    Ми могли б залишити ці значення за замовчуванням, але для того щоб наш додаток працювало з попередньо зібраним Ogre SDK, де ім'я файлу конфігурації плагінів відрізняється в залежності від того в отладочном режимі (Debug) зібраний движок або остаточному (Release), ми повинні передати наш параметр mPluginsCfg в конструктор, так як ім'я конфігураційного файлу буде 'plugins_d.cfg' при запуску в режимі налагодження.

    Йдемо далі - компілюємо і запускаємо наш додаток.
    Виглядає так ніби нічого не відбувається, але якщо ви відкриєте Ogre.log, то ви побачите те що Ogre запустився, ініціалізувати і завершив роботу. Також ви повинні побачити що він проаналізував знайдені і встановлені плагіни, перераховані в 'plugins.cfg'.

    Примітка: Для вас цей розділ буде мати набагато більше сенсу, якщо ви відкриєте "resources.cfg" і погляньте на нього, перш ніж продовжите. Ви можете знайти його в каталозі bin / release вашого SDK. Наступна річ яку ми повинні зробити - визначити ресурси використовуються нашим додатком. Це можуть бути текстури, моделі, скрипти та інше.

    У цьому керівництві ми не будемо заглиблюватися в тему про ресурси. А поки просто майте на увазі, що спочатку необхідно визначити всі ресурси, які будете використовувати в додатку, а потім ініціалізувати ті, якими Ogre скористається. На даному етапі, ми визначаємо ресурси які будуть використовуватися нашим додатком. Для цього ми додамо кожен каталог з ресурсами в ResourceGroupManager.

    Додайте наступний член класу в клас BasicTutorial6:

    Тепер потрібно додати OIS в налаштування нашого проекту:

    Include Directory $ (OGRE_HOME) / include / OIS
    Input Library OIS_d.lib / OIS.lib

    Директорія з бібліотекою повинна бути на місці.
    Переконайтеся, що після додавання OIS в проект, можете його скомпілювати.

    Додавання OIS

    OIS використовує головний модуль InputManager, який трохи складно налаштувати, але якщо він створений правильно, його легко використовувати. OIS НЕ інтегрується в Ogre; це - автономна бібліотека, що означає, що Ви повинні будете надати йому деяку інформацію спочатку, щоб він працював належним чином. На практиці цього потребує тільки дескриптор вікна, в якому Ogre відображає об'єкти. На щастя нам буде набагато простіше, так як ми використовували створення вікна за замовчуванням.

    Перейдіть до функції BasicTutorial6 :: go і додайте цей код перед нашим циклом відображення:

    1. Ogre :: LogManager :: getSingletonPtr () -> logMessage ( "*** Initializing OIS ***");
    2. OIS :: ParamList pl;
    3. size_t windowHnd = 0;
    4. std :: ostringstream windowHndStr;
    5. mWindow-> getCustomAttribute ( "WINDOW". windowHnd);
    6. windowHndStr <
    7. pl.insert (std :: make_pair (std :: string ( "WINDOW"), windowHndStr.str ()));
    8. mInputManager = OIS :: InputManager :: createInputSystem (pl);

    Це налаштовує InputManager для використання, але фактично для використання OIS. Для отримання даних клавіатури, миші, або джойстика, ви повинні будете створити ці об'єкти:

    1. mKeyboard = static_cast (MInputManager-> createInputObject (OIS :: OISKeyboard, false));
    2. mMouse = static_cast (MInputManager-> createInputObject (OIS :: OISMouse, false));

    Ми передаємо false в функцію createInputObject, тому що хочемо зробити наші миша і клавіатурі не буферизованного.

    Примітка: Якщо Ви хочете використовувати буферізованние вхід (тобто ви отримуєте зворотний виклик подій mouseMoved, mousePressed, keyReleased, і так далі), то ви повинні задати другий параметр createInputObject, як true.

    відключення OIS

    OIS трохи складний, щоб відключати його правильно. Найбезпечніший спосіб зробити це - використовувати WindowEventListener.

    По-перше, помістіть цей рядок в список підключень (includes) BasicTutorial6.h:

    1. class BasicTutorial6. public Ogre :: WindowEventListener
    1. // Ogre :: WindowEventListener
    2. virtual void windowResized (Ogre :: RenderWindow * rw);
    3. virtual void windowClosed (Ogre :: RenderWindow * rw);

    Тепер відкрийте BasicTutorial6.cpp і додайте в нього наступне:

    1. // Adjust mouse clipping area
    2. void BasicTutorial6 :: windowResized (Ogre :: RenderWindow * rw)
    3. unsigned int width, height, depth;
    4. int left, top;
    5. rw-> getMetrics (width, height, depth, left, top);
    6. const OIS :: MouseState ms = mMouse-> getMouseState ();
    7. ms.width = width;
    8. ms.height = height;
    9. >
    10. // Unattach OIS before window shutdown (very important under Linux)
    11. void BasicTutorial6 :: windowClosed (Ogre :: RenderWindow * rw)
    12. // Only close for window that created OIS (the main window in these demos)
    13. if (rw == mWindow)
    14. if (mInputManager)
    15. mInputManager-> destroyInputObject (mMouse);
    16. mInputManager-> destroyInputObject (mKeyboard);
    17. OIS :: InputManager :: destroyInputSystem (mInputManager);
    18. mInputManager = 0;
    19. >
    20. >
    21. >

    windowResized викликають щоразу, коли вікно змінило розміри, і засвідчується, що положення OIS миші синхронізовано з поточною величиною вікна.
    windowClosed ліквідує OIS, коли вікно закривається.

    Щоб змусити наш додаток діяти як WindowEventListener, ми повинні зареєструвати їх разом.
    Так що додайте наступні рядки в функцію BasicTutorial6 :: go:

    1. // Set initial mouse clipping size windowResized (mWindow);
    2. // Register as a Window listener Ogre :: WindowEventUtilities :: addWindowEventListener (mWindow, this);

    Є ще одна річ, яку ми повинні зробити.
    Знайдіть деструктор BasicTutorial6 і зробіть його таким:

    1. // Remove ourself as a Window listener
    2. Ogre :: WindowEventUtilities :: removeWindowEventListener (mWindow, this);
    3. windowClosed (mWindow);
    4. delete mRoot;

    Налаштування кадрових оброблювачів

    Незалежно від того, ви використовуєте буферізованние або НЕ буферізірованний введення, кожен фрейм, ви повинні викликати метод захоплення на всі об'єкти, які ви використовуєте: клавіатура, миша, або джойстик ...

    Для НЕ Буферізірованний входу це - все, що ви повинні зробити.
    Кожен фрейм ви можете викликати різні функції клавіатури і миші, щоб запросити положення цих об'єктів.

    Отже, ми повинні змусити клас BasicTutorial6 стати кадровим оброблювачем.

    1. class BasicTutorial6. public Ogre :: WindowEventListener, public Ogre :: FrameListener
    1. // Ogre :: FrameListener
    2. virtual bool frameRenderingQueued (const Ogre :: FrameEvent evt);

    І потім, в BasicTutorial6.cpp, додайте визначення цієї функції:

    1. bool BasicTutorial6 :: frameRenderingQueued (const Ogre :: FrameEvent evt)
    2. if (mWindow-> isClosed ())
    3. return false;
    4. // Need to capture / update each device
    5. mKeyboard-> capture ();
    6. mMouse-> capture ();
    7. if (mKeyboard-> isKeyDown (OIS :: KC_ESCAPE))
    8. return false;
    9. return true;
    10. >

    останні штрихи

    Перш, ніж ми будемо готові скомпілювати і запустити додаток, потрібно зареєструвати його як кадровий обробник. І ми також не маємо потреби в циклі рендеринга.

    Знайдіть BasicTutorial6 :: go і видаліть цикл while.
    Потім додайте туди це:

    1. mRoot-> addFrameListener (this);
    2. mRoot-> startRendering ();

    Перша лінія коду додає BasicTutorial6 Коржики це фрагменти тексту як кадровий обробник, це означає, що клас буде отримувати події фрейма. Якщо ми не зареєструємо клас разом з Ogre :: Root як кадровий обробник, то функція frameRenderingQueued НЕ буде викликана.

    На другому рядку коду починається цикл рендрінга. Ми дійсно не маємо потреби ні в якій спеціальній обробці циклу, так як ми можемо виконувати наші завдання в функції frameRenderingQueued "покадрово".

    Скомпілюйте і запустіть!

    Ви повинні бачити фірмову голову огра і додаток повинен закриватися при натисканні на клавішу "Esc".

    версія Cocoa

    Новий спосіб установки поточного керівництва для xcode в Mac OS X набагато коротше і легше зрозуміти.
    Переконайтеся, що проект зібраний як і додаток cocoa і поміняйте розширення з .cpp на .mm, далі скопіюйте .cfg файли ресурсів і плагінів в вашу xcode папку.

    Тепер змініть наступне:

    1. #ifdef _DEBUG
    2. mResourcesCfg = "resources_d.cfg";
    3. mPluginsCfg = "plugins_d.cfg";
    4. #else
    5. mResourcesCfg = "resources.cfg";
    6. mPluginsCfg = "plugins.cfg";
    7. #endif
    1. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
    2. std :: string mResourcePath = [[[NSBundle mainBundle] resourcePath] cStringUsingEncoding: NSUTF8StringEncoding];
    3. #endif
    4. #ifdef _DEBUG
    5. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
    6. mResourcesCfg = mResourcePath + "/resources_d.cfg";
    7. mPluginsCfg = mResourcePath + "/plugins_d.cfg";
    8. #else
    9. mResourcesCfg = "resources_d.cfg";
    10. mPluginsCfg = "plugins_d.cfg";
    11. #endif
    12. #else
    13. #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
    14. mResourcesCfg = mResourcePath + "/resources.cfg";
    15. mPluginsCfg = mResourcePath + "/plugins.cfg";
    16. #else
    17. mResourcesCfg = "resources.cfg";
    18. mPluginsCfg = "plugins.cfg";
    19. #endif

    версія Carbon

    Так як Mac OS X використовує app bundles, концепція радикально відрізняється від тієї що ми використовуємо для windows і linux. Код описаний вище (вище ніж попередній розділ) не запуститься на Mac OS X.

    Додайте наступну функцію:

    У createRoot (), поміняйте: