[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Игровые движки » IrrLicht Engine » Туториал №13: Рендеринг в текстуру
Туториал №13: Рендеринг в текстуру
MerGC_TeamДата: Четверг, 03.04.2014, 17:29 | Сообщение # 1
Веселый админ
Группа: Администраторы
Сообщений: 32
Статус: Оффлайн
В этом уроке вы научитесь рендерить в текстуру. Это очень интересная фичка(спецэффект), кто знает тот поймет, а кто не знает, то это проецирование какого либо изображения (например. удаленного участка сцены или спрайтовой анимации) на текстурированный объект. В дополнении вы узнаете как включать для объектов сцены спектральное освещение.

Начинаем как обычно, подключаем заголовочный файл IrrLicth.h, включаем по умолчанию пространство имен irr, запрашиваем видеодрайвер и создаем корневой объект(движок) IrrLicht:

Код
#include < irrlicht.h >
#include "driverChoice.h"

using namespace irr;  

int main()
{
         // запрашиваем видеодрайвер
         video::E_DRIVER_TYPE driverType=driverChoiceConsole();
         if (driverType==video::EDT_COUNT) return 1; // выходим если не выбран.

         // создаем движок

         IrrlichtDevice *device = createDevice(driverType, core::dimension2d< u32 >(640, 480), 16, false, false);

         if (device == 0) return 1; // выходим если не создан.

         video::IVideoDriver* driver = device->getVideoDriver();
         scene::ISceneManager* smgr = device->getSceneManager();
         gui::IGUIEnvironment* env = device->getGUIEnvironment();


Загружаем анимационную модель, анимацию которой будем проецировать. Как и в большинстве уроков, это будет модель в формате md2. Отличие же будет в том, что мы установим флаг сияния материала модели. Это активирует спектральные отблески отраженные от динамического источника света.
Код
// грузим модельку феи

         scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode(
                 smgr->getMesh("../../media/faerie.md2"));

         if (fairy)
         {
                 fairy->setMaterialTexture(0,
                    driver->getTexture("../../media/faerie2.bmp")); // грузим текстурку
                 fairy->setMaterialFlag(video::EMF_LIGHTING, true); // включаем динамическое освещение для модели
                 fairy->getMaterial(0).Shininess = 20.0f; // размер спектральных брызг
                 fairy->setPosition(core::vector3df(-10,0,-100));
                 fairy->setMD2Animation ( scene::EMAT_STAND );
         }


Но чтобы модель реагировала на свет - этот свет надо добавить на сцену. Мы добавим один динамический источник рядом с моделью и добавим еще один атмосферны(амбиентный) серого цвета, чтобы модель не была черной когда первый ее не освещает.
Код
// добавляем белый свет
         smgr->addLightSceneNode(0, core::vector3df(-15,5,-105),
                         video::SColorf(1.0f, 1.0f, 1.0f));

         // добавляем серый свет
         smgr->setAmbientLight(video::SColor(0,60,60,60));


Далее добавляем FPS камеру, отключаем видимость курсора мыши и кубик на грань которого будем проецировать анимацию и при всем при этом кубик будет вращаться!!!
Код
// добавляем fps камеру
         scene::ICameraSceneNode* fpsCamera = smgr->addCameraSceneNodeFPS();
         fpsCamera->setPosition(core::vector3df(-50,50,-150));

         // отключаем курсор мыши
         device->getCursorControl()->setVisible(false);

         // создаем куб
         scene::ISceneNode* test = smgr->addCubeSceneNode(60);

         // анимируем
         scene::ISceneNodeAnimator* anim = smgr->createRotationAnimator(
                 core::vector3df(0.3f, 0.3f,0));

         test->setPosition(core::vector3df(-100,0,-100));
         test->setMaterialFlag(video::EMF_LIGHTING, false); // отключаем динамический свет для материала
         test->addAnimator(anim);
         anim->drop();

         // устанавливаем заголовок окна
         device->setWindowCaption(L"Irrlicht Engine - Render to Texture and Specular Highlights example");


И так чтобы рендерить на текстуру, надо эту текстуру подготовить. Это делается вызовом IVideoDriver::addRenderTargetTexture() с указанием размера текстуры. Постарайтесь не использовать размер больший чем фрейм буфер, т.к. эта фича использует фрейм буфер совместно с z-буфером. А еще нам нужна еще одна камера изображение с которой мы будем проецировать.
Код
// создаем "полотно" для проецирования
         video::ITexture* rt = 0;
         scene::ICameraSceneNode* fixedCam = 0;
          

         if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
         {
                 // создаем "полотно" - текстуру в которую рендерить будем
                 rt = driver->addRenderTargetTexture(core::dimension2d< u32 >(256,256), "RTT1");
                 test->setMaterialTexture(0, rt); // устанавливаем материалом куба "полотно"

                 // добавляем дополнительную камеру
                 fixedCam = smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
                         core::vector3df(-10,10,-100));
         }
         else
         {
                 // беда, драйвер карты не поддерживает фичу
                 // сообщаем об этом пользователю
                 gui::IGUISkin* skin = env->getSkin();
                 gui::IGUIFont* font = env->getFont("../../media/fonthaettenschweiler.bmp");
                 if (font)
                         skin->setFont(font);

                 gui::IGUIStaticText* text = env->addStaticText(
                         L"Your hardware or this renderer is not able to use the "
                         L"render to texture feature. RTT Disabled.",
                         core::rect< s32 >(150,20,470,60));

                 text->setOverrideColor(video::SColor(100,255,255,255));
         }


Начинаем рисовать. В каждом фрейме мы рисуем сцену дважды. Первый раз от лица дополнительной камеры, которая снимает изображение для рендеринга в текстуру и второй раз от лица камеры пользователя. Заметочка: перед рендером в текстуру кубика, надо его невидимым сделать, т.к. его тестура еще не готова.
Код
int lastFPS = -1;

         while(device->run())
         if (device->isWindowActive())
         {
                 driver->beginScene(true, true, 0);

                 if (rt)
                 {
                         // рисуем сцену от лица доп.камеры                        

                         // определяем "полотно"
                         driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));

                         // делаем куб невидимым и делаем доп.камеру активной
                         test->setVisible(false);
                         smgr->setActiveCamera(fixedCam);

                         // рисуем всю сцену на "полотно"
                         smgr->drawAll();

                         // убираем "полотно", с зачисткой буферов
                         driver->setRenderTarget(0, true, true, 0);

                         // делаем куб видимым и активной камеру пользователя
                         test->setVisible(true);
                         smgr->setActiveCamera(fpsCamera);
                 }
                  
                 // рисуем сцену как обычно, но уже на кубике "хитрая" текстура
                 smgr->drawAll();
                 env->drawAll();

                 driver->endScene();

                 // в заголовок окна дописываем число кадров в секунду
                 int fps = driver->getFPS();
                 if (lastFPS != fps)
                 {
                         core::stringw str = L"Irrlicht Engine - Render to Texture and Specular Highlights example";
                         str += " FPS:";
                         str += fps;

                         device->setWindowCaption(str.c_str());
                         lastFPS = fps;
                 }
         }

         device->drop(); // дропаем движок
         return 0;
}


Компилируем, запускаем, любуемся!
 
Форум » Игровые движки » IrrLicht Engine » Туториал №13: Рендеринг в текстуру
  • Страница 1 из 1
  • 1
Поиск: