现在的位置: 首页 > 综合 > 正文

Irrlicht学习备忘录——13 RenderToTexture

2014年04月05日 ⁄ 综合 ⁄ 共 3640字 ⁄ 字号 评论关闭

13 RenderToTexture

    官方代码($sdk)\examples\13.RenderToTexture

  

        渲染纹理,可以做出很多看起来非常不错的特效,如镜面、径向模糊等效果。官方例子用制作镜面来说明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()设置活动摄像机,通过它就能完成切换摄像机的功能。

抱歉!评论已关闭.