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; }
Компилируем, запускаем, любуемся!
|
|
| |