Sophie

Sophie

distrib > Mandriva > 2010.1 > x86_64 > media > contrib-release > by-pkgid > 58828b263d8f56d90ac336dea07a4586 > files > 744

irrlicht-doc-1.6.1-1mdv2010.1.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Irrlicht Engine: Tutorial 13: Render To Texture</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<table class="irrlicht" >
  <tr valign="middle"> 
    <td><font size="2"><a class="qindex" href="index.html"><font color="#FFFFFF">Home</font></a> 
      | <a class="qindex" href="namespaces.html"><font color="#FFFFFF">Namespaces</font></a> 
      | <a class="qindex" href="hierarchy.html"><font color="#FFFFFF">Hierarchy</font></a> 
      | <a class="qindex" href="classes.html"><font color="#FFFFFF">Alphabetical 
      List</font></a> | <a class="qindex" href="annotated.html"><font color="#FFFFFF"> 
      Class list</font></a> | <a class="qindex" href="files.html"><font color="#FFFFFF">Files</font></a> 
      | <a class="qindex" href="namespacemembers.html"><font color="#FFFFFF"> 
      Namespace&nbsp;Members</font></a> | <a class="qindex" href="functions.html"><font color="#FFFFFF">Class 
      members</font></a> | <a class="qindex" href="globals.html"><font color="#FFFFFF">File 
      members</font></a> | <a class="qindex" href="pages.html"><font color="#FFFFFF">Tutorials</font></a></font> </td>
  </tr>
</table>
<!-- Generated by Doxygen 1.5.6 -->
<div class="contents">
<h1><a class="anchor" name="example013">Tutorial 13: Render To Texture </a></h1><div align="center">
<img src="013shot.jpg" alt="013shot.jpg">
</div>
 <p>
This tutorial shows how to render to a texture using Irrlicht. Render to texture is a feature with which it is possible to create nice special effects. In addition, this tutorial shows how to enable specular highlights.<p>
In the beginning, everything as usual. Include the needed headers, ask the user for the rendering driver, create the Irrlicht Device: <div class="fragment"><pre class="fragment"><span class="preprocessor">#include &lt;<a class="code" href="irrlicht_8h.html" title="Main header file of the irrlicht, the only file needed to include.">irrlicht.h</a>&gt;</span>
<span class="preprocessor">#include &lt;iostream&gt;</span>

<span class="keyword">using namespace </span>irr;

<span class="preprocessor">#ifdef _MSC_VER</span>
<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, "Irrlicht.lib")</span>
<span class="preprocessor"></span><span class="preprocessor">#endif</span>
<span class="preprocessor"></span>
<span class="keywordtype">int</span> main()
{
        <span class="comment">// let user select driver type</span>

        <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d04691ca314f9018f508dcf2c57dcaacec" title="Direct3D 9 device, only available on Win32 platforms.">video::EDT_DIRECT3D9</a>;

        printf(<span class="stringliteral">"Please select the driver you want for this example:\n"</span>\
                <span class="stringliteral">" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"</span>\
                <span class="stringliteral">" (d) Software Renderer\n (e) Burning's Software Renderer\n"</span>\
                <span class="stringliteral">" (f) NullDevice\n (otherKey) exit\n\n"</span>);

        <span class="keywordtype">char</span> i;
        std::cin &gt;&gt; i;

        <span class="keywordflow">switch</span>(i)
        {
                <span class="keywordflow">case</span> <span class="charliteral">'a'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d04691ca314f9018f508dcf2c57dcaacec" title="Direct3D 9 device, only available on Win32 platforms.">video::EDT_DIRECT3D9</a>;<span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'b'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d08cc3807f6f28404f3424ad7e31b3142f" title="Direct3D8 device, only available on Win32 platforms.">video::EDT_DIRECT3D8</a>;<span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'c'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d02715182a79f1cb8e2826fd68a8150a53" title="OpenGL device, available on most platforms.">video::EDT_OPENGL</a>;   <span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'d'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d01598cd235a1a6bd052e2011b559e8995" title="The Irrlicht Engine Software renderer.">video::EDT_SOFTWARE</a>; <span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'e'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d0e85481da26159b967191ccc6de1e4a05" title="The Burning&amp;#39;s Software Renderer, an alternative software renderer.">video::EDT_BURNINGSVIDEO</a>;<span class="keywordflow">break</span>;
                <span class="keywordflow">case</span> <span class="charliteral">'f'</span>: driverType = <a class="code" href="namespaceirr_1_1video.html#e35a6de6d436c76107ad157fe42356d0cfdbd476cbfd4d05e72f9adffcc42210" title="Null driver, useful for applications to run the engine without visualisation.">video::EDT_NULL</a>;     <span class="keywordflow">break</span>;
                <span class="keywordflow">default</span>: <span class="keywordflow">return</span> 1;
        }       

        <span class="comment">// create device and exit if creation failed</span>

        IrrlichtDevice *device =
                <a class="code" href="namespaceirr.html#baf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the...">createDevice</a>(driverType, core::dimension2d&lt;u32&gt;(640, 480),
                16, <span class="keyword">false</span>, <span class="keyword">false</span>);

        <span class="keywordflow">if</span> (device == 0)
                <span class="keywordflow">return</span> 1; <span class="comment">// could not create selected driver.</span>

        video::IVideoDriver* driver = device-&gt;getVideoDriver();
        scene::ISceneManager* smgr = device-&gt;getSceneManager();
        gui::IGUIEnvironment* env = device-&gt;getGUIEnvironment();
</pre></div><p>
Now, we load an animated mesh to be displayed. As in most examples, we'll take the fairy md2 model. The difference here: We set the shininess of the model to a value other than 0 which is the default value. This enables specular highlights on the model if dynamic lighting is on. The value influences the size of the highlights. <div class="fragment"><pre class="fragment">        <span class="comment">// load and display animated fairy mesh</span>

        scene::IAnimatedMeshSceneNode* fairy = smgr-&gt;addAnimatedMeshSceneNode(
                smgr-&gt;getMesh(<span class="stringliteral">"../../media/faerie.md2"</span>));

        <span class="keywordflow">if</span> (fairy)
        {
                fairy-&gt;setMaterialTexture(0,
                                driver-&gt;getTexture(<span class="stringliteral">"../../media/faerie2.bmp"</span>)); <span class="comment">// set diffuse texture</span>
                fairy-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#8a3bc00ae8137535b9fbc5f40add70d3cea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, <span class="keyword">true</span>); <span class="comment">// enable dynamic lighting</span>
                fairy-&gt;getMaterial(0).Shininess = 20.0f; <span class="comment">// set size of specular highlights</span>
                fairy-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-10,0,-100));
                fairy-&gt;setMD2Animation ( <a class="code" href="namespaceirr_1_1scene.html#08d4a84966e1d2886d0d57e4acbb4f1935893ae58423c41dace23ad13e262e2c">scene::EMAT_STAND</a> );
        }
</pre></div><p>
To make specular highlights appear on the model, we need a dynamic light in the scene. We add one directly in vicinity of the model. In addition, to make the model not that dark, we set the ambient light to gray. <div class="fragment"><pre class="fragment">        <span class="comment">// add white light</span>
        smgr-&gt;addLightSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-15,5,-105),
                        video::SColorf(1.0f, 1.0f, 1.0f));

        <span class="comment">// set ambient light</span>
        smgr-&gt;setAmbientLight(video::SColor(0,60,60,60));
</pre></div><p>
The next is just some standard stuff: Add a user controlled camera to the scene, disable mouse cursor, and add a test cube and let it rotate to make the scene more interesting. <div class="fragment"><pre class="fragment">        <span class="comment">// add fps camera</span>
        scene::ICameraSceneNode* fpsCamera = smgr-&gt;addCameraSceneNodeFPS();
        fpsCamera-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-50,50,-150));

        <span class="comment">// disable mouse cursor</span>
        device-&gt;getCursorControl()-&gt;setVisible(<span class="keyword">false</span>);

        <span class="comment">// create test cube</span>
        scene::ISceneNode* test = smgr-&gt;addCubeSceneNode(60);

        <span class="comment">// let the cube rotate and set some light settings</span>
        scene::ISceneNodeAnimator* anim = smgr-&gt;createRotationAnimator(
                <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0.3f, 0.3f,0));

        test-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-100,0,-100));
        test-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#8a3bc00ae8137535b9fbc5f40add70d3cea597a2692b8415486a464a7f954d34" title="Will this material be lighted? Default: true.">video::EMF_LIGHTING</a>, <span class="keyword">false</span>); <span class="comment">// disable dynamic lighting</span>
        test-&gt;addAnimator(anim);
        anim-&gt;drop();

        <span class="comment">// set window caption</span>
        device-&gt;setWindowCaption(L<span class="stringliteral">"Irrlicht Engine - Render to Texture and Specular Highlights example"</span>);
</pre></div><p>
To test out the render to texture feature, we need a render target texture. These are not like standard textures, but need to be created first. To create one, we call IVideoDriver::addRenderTargetTexture() and specify the size of the texture. Please don't use sizes bigger than the frame buffer for this, because the render target shares the zbuffer with the frame buffer. Because we want to render the scene not from the user camera into the texture, we add another fixed camera to the scene. But before we do all this, we check if the current running driver is able to render to textures. If it is not, we simply display a warning text. <div class="fragment"><pre class="fragment">        <span class="comment">// create render target</span>
        video::ITexture* rt = 0;
        scene::ICameraSceneNode* fixedCam = 0;
        

        <span class="keywordflow">if</span> (driver-&gt;queryFeature(<a class="code" href="namespaceirr_1_1video.html#57b1721e42a79c5dcf8e830e3621e08f331e98faf8143ec5d7625255531ad47d" title="Is driver able to render to a surface?">video::EVDF_RENDER_TO_TARGET</a>))
        {
                rt = driver-&gt;addRenderTargetTexture(core::dimension2d&lt;u32&gt;(256,256), <span class="stringliteral">"RTT1"</span>);
                test-&gt;setMaterialTexture(0, rt); <span class="comment">// set material of cube to render target</span>

                <span class="comment">// add fixed camera</span>
                fixedCam = smgr-&gt;addCameraSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(10,10,-80),
                        <a class="code" href="namespaceirr_1_1core.html#06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-10,10,-100));
        }
        <span class="keywordflow">else</span>
        {
                <span class="comment">// create problem text</span>
                gui::IGUISkin* skin = env-&gt;getSkin();
                gui::IGUIFont* font = env-&gt;getFont(<span class="stringliteral">"../../media/fonthaettenschweiler.bmp"</span>);
                <span class="keywordflow">if</span> (font)
                        skin-&gt;setFont(font);

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

                text-&gt;setOverrideColor(video::SColor(100,255,255,255));
        }
</pre></div><p>
Nearly finished. Now we need to draw everything. Every frame, we draw the scene twice. Once from the fixed camera into the render target texture and once as usual. When rendering into the render target, we need to disable the visibilty of the test cube, because it has the render target texture applied to it. That's it, wasn't too complicated I hope. :) <div class="fragment"><pre class="fragment">        <span class="keywordtype">int</span> lastFPS = -1;

        <span class="keywordflow">while</span>(device-&gt;run())
        <span class="keywordflow">if</span> (device-&gt;isWindowActive())
        {
                driver-&gt;beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, 0);

                <span class="keywordflow">if</span> (rt)
                {
                        <span class="comment">// draw scene into render target</span>
                        
                        <span class="comment">// set render target texture</span>
                        driver-&gt;setRenderTarget(rt, <span class="keyword">true</span>, <span class="keyword">true</span>, video::SColor(0,0,0,255));

                        <span class="comment">// make cube invisible and set fixed camera as active camera</span>
                        test-&gt;setVisible(<span class="keyword">false</span>);
                        smgr-&gt;setActiveCamera(fixedCam);

                        <span class="comment">// draw whole scene into render buffer</span>
                        smgr-&gt;drawAll();

                        <span class="comment">// set back old render target</span>
                        <span class="comment">// The buffer might have been distorted, so clear it</span>
                        driver-&gt;setRenderTarget(0, <span class="keyword">true</span>, <span class="keyword">true</span>, 0);

                        <span class="comment">// make the cube visible and set the user controlled camera as active one</span>
                        test-&gt;setVisible(<span class="keyword">true</span>);
                        smgr-&gt;setActiveCamera(fpsCamera);
                }
                
                <span class="comment">// draw scene normally</span>
                smgr-&gt;drawAll();
                env-&gt;drawAll();

                driver-&gt;endScene();

                <span class="comment">// display frames per second in window title</span>
                <span class="keywordtype">int</span> fps = driver-&gt;getFPS();
                <span class="keywordflow">if</span> (lastFPS != fps)
                {
                        <a class="code" href="namespaceirr_1_1core.html#ef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> str = L<span class="stringliteral">"Irrlicht Engine - Render to Texture and Specular Highlights example"</span>;
                        str += <span class="stringliteral">" FPS:"</span>;
                        str += fps;

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

        device-&gt;drop(); <span class="comment">// drop device</span>
        <span class="keywordflow">return</span> 0;
}
</pre></div> </div>
<hr size="1">
<address style="align: right;">
<small> </small>
</address>
<table width="100%" border="0" cellspacing="0" cellpadding="2">
  <tr> 
    <td width="0"> <div align="left"><small><a href="http://irrlicht.sourceforge.net" target="_blank"><img src="irrlicht.png" alt="The Irrlicht Engine" align="middle" border=0 width=88 height=31></a></small></div></td>
    <td> <div align="left"><small><em><font size="2">The <a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht 
        Engine</a> Documentation &copy; 2003-2009 by Nikolaus Gebhardt. Generated 
        on Sun Jan 10 09:24:07 2010 by <a href="http://www.doxygen.org" target="_blank">Doxygen</a> 
        (1.5.6)</font></em></small></div></td>
  </tr>
</table>
<address style="align: right;">
</address>
</body>
</html>