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 есть множество примеров программ. Но все они излишне усложнены и мне не встретилось ни одного исходника размером со страничку, который хотя бы загружал и отображал произвольную модель. Целью данной статьи является иллюстрация возможности написания короткого рабочего примера.
Нижеприведенная программа отображает стандартную 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.
