13 RenderToTexture
官方代碼($sdk)\examples\13.RenderToTexture
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc5WNyImd4dlW0ZkMaZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zM1QTNzEDNxITNyIDM0EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
渲染紋理,可以做出很多看起來非常不錯的特效,如鏡面、徑向模糊等效果。官方例子用制作鏡面來說明irr中如何渲染紋理。
scene::IAnimatedMeshSceneNode* fairy = smgr->addAnimatedMeshSceneNode(smgr->getMesh("../../media/faerie.md2"));
建立一個動畫場景節點,使用的Mesh仍然是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 );
将動畫設為站立的動畫
}
一般情況下模型的自發光值使用預設值0,本例中設為大一0的值。這樣在開啟光照時模型就能産生高亮點,而這個自發光值也将會模型上亮點的大小。
smgr->addLightSceneNode(0, core::vector3df(-15,5,-105),video::SColorf(1.0f, 1.0f, 1.0f));
為了使模型上出現高光點,例子中在模型旁邊添加了一個動态光。
smgr->setAmbientLight(video::SColor(0,60,60,60));
//将環境光設為灰色,這樣模型就不會顯示成黑的。
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();
渲染紋理所使用的目标紋理和irr的普通紋理不同,需要使用IVideoDriver::createRenderTargetTexture函數建立一個渲染目标紋理,建立時需要指定紋理的大小。例子中沒有以使用者錄影機做為鏡面錄影機,它建立了一個新錄影機來擷取渲染出的紋理。這個例子用了兩個錄影機,以往的例子中從來沒有這樣用過,通過它為可以學會如何切換錄影機。
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");
//建立一個渲染目标紋理,大小為256*256
test->setMaterialTexture(0, rt); // set material of cube to render target
//将渲染目标紋理做為測試立方體的材質,這樣立方體上的紋理将是動态渲染出來的
fixedCam = smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
core::vector3df(-10,10,-100));
//增加一個固定錄影機
}
else
{
//驅動不支援渲染到紋理,建立報錯資訊。建立報錯資訊用到的方法全是UserInterface例子中介紹過的,沒什麼難度,一看就懂。
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));
}
//建立一個FPS錄影機,通過這個錄影機能夠以不同位置觀察渲染紋理的效果。
scene::ICameraSceneNode* fpsCamera = smgr->addCameraSceneNodeFPS();
fpsCamera->setPosition(core::vector3df(-50,50,-150));
這個例子中的幀循環跟以往的例子不同。以前每幀隻繪制場景一次,這次每幀繪制場景兩次。第一次繪制使用的是fixedCam固定錄影機,通過它截取繪制到紋理上的場景圖像,這次繪制使用者看不到,測試立方體在這次繪制中不需要被顯示,它将被隐藏掉。第二次繪制的是使用者看到的場景,它會将第一次繪制的紋理顯示在測試立方體上。
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);
//更換活動錄影機為FPS錄影機
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;
}
}
渲染到紋理使用的不是普通紋理,而是IVideoDriver::addRenderTargetTexture()建立的可修改紋理。使用IVideoDriver::setRenderTarget()設定渲染目标。使用ISceneManager::setActiveCamera()設定活動錄影機,通過它就能完成切換錄影機的功能。