Programming Gems::CPP and OGRE

Материал из NNLUG Wiki

Перейти к: навигация, поиск

Отображение стандартной 3D-модели средствами графической библиотеки OGRE

OGRE - это объектно-ориентированный графический движок рендеринга. Написан на языке C++. Существуют версии этого движка под Windows, Linux, MacOS. Движок работает поверх OpenGL/DirectX. Для просчета физики (динамики) объектов могут использоваться различные физические движки (такие, как ODE, Newton Game Dynamics). Преимущества OGRE: большое коммьюнити, продвинутые технологии, отличное качество кода. Недостатки: относительная сложность изучения новичками.

Под Linux OGRE SDK компилируется очень просто: ./configure && make. В самом OGRE и на OGRE Wiki есть множество примеров программ. Но все они излишне усложнены и мне не встретилось ни одного исходника размером со страничку, который хотя бы загружал и отображал произвольную модель. Целью данной статьи является иллюстрация возможности написания короткого рабочего примера.

Screenshot-athena.png

Нижеприведенная программа отображает стандартную 3D-модель OGRE формата .mesh. Для перевода 3D-моделей в такой формат существует множество утилит (из Blender, 3D Studio Max, Maya и других программ).

#include <Ogre.h>

int main () {
  Ogre::Root *pRoot;
  Ogre::RenderWindow *window;
  Ogre::SceneManager *sceneMgr;
  Ogre::Camera *camera;
  Ogre::Light *pLight;
  Ogre::MeshPtr mesh;
  Ogre::Entity *ent;

  pRoot = new Ogre::Root;

  // renderer and plugins
  Ogre::RenderSystemList *renderSystems = pRoot->getAvailableRenderers();
  Ogre::RenderSystem *selectedRenderSystem = NULL;
  bool f = false;
  for (int i = 0; (i < (int) renderSystems->size()); i++) {
    selectedRenderSystem = renderSystems->at(i);
    Ogre::String rname = selectedRenderSystem->getName();
    if (rname.compare("OpenGL Rendering Subsystem") == 0) {
      f = true;
      break;
    }
  }
  if (!f) {
    delete(pRoot);
    return 0;
  }
  pRoot->setRenderSystem(selectedRenderSystem);
  selectedRenderSystem->setConfigOption("Full Screen", "No");
  selectedRenderSystem->setConfigOption("Video Mode", "800 x 600 @ 16-bit colour");

  // window
  window = pRoot->initialise(true,"sw");

  // camera and scene manager
  sceneMgr = pRoot->createSceneManager(Ogre::ST_GENERIC);
  camera = sceneMgr->createCamera("camera");
  camera->setPosition(Ogre::Vector3(50,50,50));
  camera->lookAt(Ogre::Vector3(5,5,5));
  camera->setNearClipDistance(5);

  Ogre::Viewport* vp = window->addViewport(camera);
  vp->setBackgroundColour(Ogre::ColourValue(0.25,0.5,0.5));
  camera->setAspectRatio((Ogre::Real)1.333333);

  // light
  pLight = sceneMgr->createLight("Light");
  pLight->setType(Ogre::Light::LT_POINT);
  pLight->setPosition(Ogre::Vector3(0.0, 0.0, 0.0));
  sceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));

  // mesh
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
    "media/models", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
    "media/materials/scripts", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
    "media/materials/programs", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
    "media/materials/textures", "FileSystem", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
  Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

  Ogre::SceneNode* headNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
  ent = sceneMgr->createEntity("athene", "athene.mesh");
  headNode->attachObject(ent);

  // start
  pRoot->startRendering();
  delete(pRoot);
  return 0;
}

Давайте разберем исходник по пунктам.

  • Для работы с OGRE мы должны подключить соответствующие header-файлы (в нашем случае достаточно одного include).
  • Определяем систему рендеринга и устанавливаем параметры экрана.
  pRoot->setRenderSystem(selectedRenderSystem);
  selectedRenderSystem->setConfigOption("Full Screen", "No");
  selectedRenderSystem->setConfigOption("Video Mode", "800 x 600 @ 16-bit colour");
  • Устанавливаем камеру и источник света (OGRE допускает неограниченное число источников света в отличие от чистого OpenGL).
  sceneMgr = pRoot->createSceneManager(Ogre::ST_GENERIC);
  camera = sceneMgr->createCamera("camera");
  ....
  // light
  pLight = sceneMgr->createLight("Light");
  pLight->setType(Ogre::Light::LT_POINT);
  pLight->setPosition(Ogre::Vector3(0.0, 0.0, 0.0));
  sceneMgr->setAmbientLight(Ogre::ColourValue(0.5, 0.5, 0.5));
  • Задаем пути к ресурсам.
  Ogre::ResourceGroupManager::getSingleton().addResourceLocation(...);
  • Загружаем модель.
  Ogre::SceneNode* headNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
  ent = sceneMgr->createEntity("athene", "athene.mesh");
  headNode->attachObject(ent);
  • Запускаем цикл рендернга.
  pRoot->startRendering();

Примечание. При работе с OGRE мне пришлось столкнуться со следующей проблемой. Если откомпилировать OGRE с двойной точностью, то моя программа не отображает модель. См. обсуждение на gamedev.ru.