MerGC_Team | Дата: Четверг, 03.04.2014, 18:14 | Сообщение # 1 |
Веселый админ
Группа: Администраторы
Сообщений: 32
Статус: Оффлайн
| В этом туториале мы узнаем как разделить экран (например, для игр-гонок) в IrrLicht Engine. Мы создадим область проосмотра разбитую на 4 части, с 3 фиксированными камерами и 1 контролируемой пользователем.
Ok, пора начинать с хедеров (я думаю, что особо нечего сказать насчёт этого) Код #include < irrlicht.h > #include "driverChoice.h"
#ifdef _MSC_VER #pragma comment(lib, "Irrlicht.lib") #endif
//Пространства имён движка using namespace irr; using namespace core; using namespace video; using namespace scene;
Теперь мы определим глобальные константы описывающие разрешение основного окна для использования при инициализации устройства и установки областей просмотра. В добавок мы установим глобальные переменные говорящие активен ли режим разбиения экрна.. Код //Разрешение экрана const int ResX=800; const int ResY=600; const bool fullScreen=false;
//по умолчанию используем режим SplitScreen bool SplitScreen=true;
Теперь нам необходимы 4 указателя на наши камеры, которые будут созданы позже: Код //камеры ICameraSceneNode *camera[4]={0,0,0,0};
В нашем event-receiver(получальщике событий) мы переключаем SplitScreen-переменные, каждый раз, когда пользователь нажимает клавишу "S". Все остальные события посылаются FPS камере. Код class MyEventReceiver : public IEventReceiver { public: virtual bool OnEvent(const SEvent& event) { //Клавиша S включает/выключает режим SplitScreen if (event.EventType == irr::EET_KEY_INPUT_EVENT && event.KeyInput.Key == KEY_KEY_S && event.KeyInput.PressedDown) { SplitScreen = !SplitScreen; return true; } //Послать все остальные события оставшимся 4 камерам if (camera[3]) return camera[3]->OnEvent(event); return false; } };
Ok, теперь основная функция: Во-первых, мы инициируем устройство, получаем менеджер сцены и Видеодрайвер, загружаем анимированный меш из .md2 и карту из .pk3. Так как это старый материал, я не буду объяснять каждый шаг. Нужно лишь позаботиться о позиции карты. Код int main(int argc, char** argv) { // спросить пользователя о драйвере (OpenGL, DirectX и т.п.) video::E_DRIVER_TYPE driverType=driverChoiceConsole(); if (driverType==video::EDT_COUNT) driverType = video::EDT_OPENGL;
// Создать экземпляр EventReceiver(обработчика событий) MyEventReceiver receiver;
// Инициализация движка IrrlichtDevice *device = createDevice(driverType, dimension2du(ResX,ResY), 32, fullScreen, false, false, &receiver); if (!device) return 1;
ISceneManager *smgr = device->getSceneManager(); IVideoDriver *driver = device->getVideoDriver();
// Загрузить модель IAnimatedMesh *model = smgr->getMesh("../../media/sydney.md2"); if (!model) return 1; IAnimatedMeshSceneNode *model_node = smgr->addAnimatedMeshSceneNode(model); // Загрузить текстуру if (model_node) { ITexture *texture = driver->getTexture("../../media/sydney.bmp"); model_node->setMaterialTexture(0,texture); model_node->setMD2Animation(scene::EMAT_RUN); // отключаем освещение model_node->setMaterialFlag(EMF_LIGHTING,false); }
// Загрузить карту device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3"); IAnimatedMesh *map = smgr->getMesh("20kdm2.bsp"); if (map) { ISceneNode *map_node = smgr->addOctreeSceneNode(map->getMesh(0)); // установить позицию map_node->setPosition(vector3df(-850,-220,-850)); }
Сейчас мы создадим 4 наши камеры. Одна смотрит на модель с фронта(спереди), одна сверху и одна сбоку. В добавок создадим FPS-камеру которая управляется пользователем. Код // Создать 3 фиксированные и 1 управляемую пользователем камеру // Вид спереди camera[0] = smgr->addCameraSceneNode(0, vector3df(50,0,0), vector3df(0,0,0)); // Вид сверху camera[1] = smgr->addCameraSceneNode(0, vector3df(0,50,0), vector3df(0,0,0)); // Вид слева camera[2] = smgr->addCameraSceneNode(0, vector3df(0,0,50), vector3df(0,0,0)); // Вид контролируемый пользователем camera[3] = smgr->addCameraSceneNodeFPS(); // ставим позицию камеры 3, чтобы не появилась в позиции модели if (camera[3]) camera[3]->setPosition(core::vector3df(-50,0,-50));
Создать переменную для подсчёта fps(фреймов в секунду) и скрыть мышь: Код // прячем указатель мыши device->getCursorControl()->setVisible(false); // тут будет подсчитывать fps int lastFPS = -1;
До сих пор было не так много нового материала! Только лишь созданием 4 камер, экран не будет разбит/разделён. Чтобы это сделать потребуется несколько шагов:: Установить область просмотра на весь экран Создать новую сцену (очистить экран) Следующие 3 шага повторяются для каждой области просмотра на разделённом экране Установить область просмотра в необходимую вам область Активировать камеру "связанную" с областью просмотра Визуализировать(отрендерить) все объекты Если у вас есть GUI: Установить область просмотра на весь экран Отобразить(отрисовать) GUI End scene(команда конца отрисовки сцены в игровом цикле)
Звучит немного сложно, но вы увидите, что это не так: Код while(device->run()) { // //Установить область просмотра на весь экран и запустить сцену driver->setViewPort(rect(0,0,ResX,ResY)); driver->beginScene(true,true,SColor(255,100,100,100)); // Если режим SplitScreen включен if (SplitScreen) { // Активировать камеру 1 smgr->setActiveCamera(camera[0]); // Установить область просмотра в первом квадрате (левый верхний) driver->setViewPort(rect(0,0,ResX/2,ResY/2)); // Отрисовать сцену smgr->drawAll(); // Активировать камеру 2 smgr->setActiveCamera(camera[1]); // Установить область просмотра во втором квадрате (правый верхний) driver->setViewPort(rect(ResX/2,0,ResX,ResY/2)); // Отрисовать сцену smgr->drawAll(); // Активировать камеру 3 smgr->setActiveCamera(camera[2]); // Установить область просмотра в 3 квадрате (левый нижний) driver->setViewPort(rect(0,ResY/2,ResX/2,ResY)); // Отрисовать сцену smgr->drawAll(); //Set viewport the last quarter (right bottom) driver->setViewPort(rect(ResX/2,ResY/2,ResX,ResY)); } // Активировать камеру 4 smgr->setActiveCamera(camera[3]); // Отрисовать сцену smgr->drawAll(); driver->endScene();
Как вы вероятно можете видеть, изображение рендерится для каждой области просмотра по отдельности. Это значит, что будут серьёзные потери производительности при выполнении рограммы. Ok, если вы спросите "Как я должен установить область просмотра, чтобы получить тот или иной экран?", без паники. Это действительно просто: В ф-ции вы создаёте прямоугольник определяя 4 координаты: X-координата левого верхнего угла Y-координата левого верхнего угла X-координата правого нижнего угла Y-координата правого нижнего угла
То есть, если вы желаете разбить экран на 2 области просмотра вы могли бы задать следующие координаты: 1-ая область просмотра: 0,0,ResX/2,ResY 2-ая область просмотра: ResX/2,0,ResX,ResY
Если вы поняли не в полной мере, просто поиграйте с этим примером чтобы понять что происходит в ответ на ваши действия.
Теперь мы просто посмотрим текущий fps и выключим движок, когда пользователь захочет: Код // получить и отобразить fps if (driver->getFPS() != lastFPS) { lastFPS = driver->getFPS(); core::stringw tmp = L"Irrlicht SplitScreen-Example (FPS: "; tmp += lastFPS; tmp += ")"; device->setWindowCaption(tmp.c_str()); } } // Удалить устройство device->drop(); return 0; }
Вот и всё! Просто откомпилируйте и поиграйте с программой. Примечание: Нажимая клавишу "S" вы можете включать и выключать режим splitscreen.
|
|
| |