[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Игровые движки » IrrLicht Engine » Туториал №2: Уровни Quake 3 (сложность: легкий)
Туториал №2: Уровни Quake 3 (сложность: легкий)
MerGC_TeamДата: Пятница, 28.02.2014, 21:23 | Сообщение # 1
Веселый админ
Группа: Администраторы
Сообщений: 32
Статус: Оффлайн
В этом туториале мы расскажем за загрузить в движок карту из игры Quake 3, прикрепить к сцене и как добавить на сцену камеру управляемую
игроком.
Начнем как и в примере “Привет Мир”: подключим заголовочный файл
движка к проекту ну и еще библиотеку для того чтобы движок мог
“общаться” с пользователем через консоль.

Код
#include <irrlicht.h>
#include <iostream>

Кам мы уже писали ранее все что касается IrrLicht находится в пространстве имен ‘irr’. Чтобы избавиться от необходимости указывать эту
приставку ‘irr::’ для каждого класса движка, мы укажем компилятору
использовать его автоматически. Чтобы также же избавиться от
необходимости указания подпространств имен движка, можно аналогичным
способом “рассказать” о них компилятору, как мы сделали в туториале №1


Код
using namespace irr;

Чтобы использовать Irrlicht.DLL, надо подключить Irrlicht.lib. Это можно сделать двумя способами, указать в настройка проекта или
использовать диррективу pragma comment.
Ok, начнем. Мы опять будем использовать функцию main() как главную, а не WinMain().

Код
int main()
{

Как и в туториале №1, мы создаем корневой объект движка с помощью функции createDevice(). Небольшим отличием будет то, что мы спросим у пользователя какой
драйвер использовать. Программный (Software) рендерер слишком медленным
для огромных карт Quake 3, но для эксперимента можете попробовать
запустится и с ним. Из подключенного driverChoice.h используем функцю driverChoiceConsole для выбора пользователем видеодрайвера.

Код
// спрашиваем у пользователя про дарайвер (DirectX, OpenGL и т.п.)
video::E_DRIVER_TYPE driverType = driverChoiceConsole();
// содаем выбранный драйвер, при ошибке выходим
IrrlichtDevice *device = (driverType, core::dimension2d< u32>;(640, 480));
if (device == 0)
return 1; // драйвер не выбран или возникла ошибка, выходим

Получаем указатели на видеодрайвер и менеджер сцены, чтобы не запрашивать их постоянно у движка с помощью вызовов irr::IrrlichtDevice::getVideoDriver() и irr::IrrlichtDevice::getSceneManager().

Код
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();

Для отображения уровня из Quake 3, в первую очередь его надо загрузить. Уровни из Quake 3 упакованы в файлы .pk3, которые по факту являются архивами .zip . Добавим файл .pk3 в нашу irr::io::IFileSystem и после этого сможем обращатся к файлам архива так как и к любым файлам на винчестере.

Код
// подключаем архив .pk3 (.zip)
device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3");

Теперь мы може загрузить меш интересующего нас уровня вызовом irr::scene::ISceneManager::getMesh(). Мы получим указатель на irr::scene::IAnimatedMesh. Как вам должно быть известно, Quake 3 уровни не анимированы и представляют собой кучу статической геометрии с привязанными к ней материалами. Следовательно наш IAnimatedMesh будет содержать только один фрейм и мы возмем “первый кадр” нашей “анимации”, который по сути является уровнем quake и создадим Octree узел(ноду) на сцене, используя irr::scene::ISceneManager::addOctreeSceneNode(). Octree ноды оптимизированны для отрисовки только видимой части геометрии. Как альтернатива Octree является irr::scene::IMeshSceneNode, нода, которая всегда рисуется целиком без оптимизаций. Воспользуйтесь irr::scene::ISceneManager::addMeshSceneNode() вместо addOctreeSceneNode() и обратите внимание сколько примитивов рисуется за раз и как это отражается на производительности. (Для подсчета примитивов существует метод irr::video::IVideoDriver::getPrimitiveCountDrawn() класса irr::video::IVideoDriver ). Обратите внимание что оптимизация Octree подходит только для работы с мешами с очень большим числом статической геометрии.

Код
scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
scene::ISceneNode* node = 0;
   
if (mesh)
node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
//node = smgr->addMeshSceneNode(mesh->getMesh(0));


Так как уровень смоделирован не относительно центра координат, мы его чуть-чуть подвинем с помощью метода irr::scene::ISceneNode::setPosition().

Код
if (node)
node->setPosition(core::vector3df(-1300,-144,-1249));


Теперь осталось добавить камеру, с помощью которой мы будем обозревать уровень и положение которой сможем контролировать. В движке IrrLicht существует несколько камер, например MayaCamera которая управляется аналогичне камере популярного 3D редактора Maya: вращает с прижатой левой кнопкой мыши, маштабируется с прижатыми левой и правой кнопками мыши, перемещается с прижатой правой кнопкой мыши и создается методом irr::scene::ISceneManager::addCameraSceneNodeMaya(). Но в этом примере нам нужна камера, которая управляется как 3D шутерах от первого лица (FPS) и такая создается с помощью метода irr::scene::ISceneManager::addCameraSceneNodeFPS().

Код
smgr->addCameraSceneNodeFPS();


Прячем указатель мыши за ненадобностью с помощью irr::IrrlichtDevice::ICursorControl.

Код
device->getCursorControl()->setVisible(false);


Теперь все готово и можно запускать вывод на экран. Попутно мы будет выводить информацию о количестве кадров в секунду и число рисуемых примитивов в одном кадре. Проверка irr::IrrlichtDevice::isWindowActive() опциональная, но делает указатель мыши доступным для других приложений, если переключиться на другую программу, т.е. окно с нашим приложением потеряет фокус. Вызов irr::IrrlichtDevice::yield() предотвратит холостые циклы, т.е. движок не будет продолжать отрисовку, если окно нашего приложения не активно, это избавит центральный процессор от ненужной нагрузки в этот момент.

Код
int lastFPS = -1;
   
while(device->run())
{
if (device->isWindowActive())
{
driver->beginScene(true, true, video::SColor(255,200,200,200));
smgr->drawAll();
driver->endScene();
   
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";
str += driver->getName();
str += "] FPS:";
str += fps;
device->setWindowCaption(str.c_str());
lastFPS = fps;
}
} else {
device->yield();
}


По выходу из главного цикла, уничтожим корневой объект.

Код
device->drop();
return 0;}


Это все. Компилируем и “играем.
 
Форум » Игровые движки » IrrLicht Engine » Туториал №2: Уровни Quake 3 (сложность: легкий)
  • Страница 1 из 1
  • 1
Поиск: