irrlicht/doc/docu/example013.html
2020-05-16 23:31:28 +02:00

280 lines
23 KiB
HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>Irrlicht 3D Engine: Tutorial 13: Render To Texture</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
</script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
$(document).ready(function() { searchBox.OnSelectItem(0); });
</script>
</head>
<body>
<div id="top"><!-- do not remove this div! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
<td style="padding-left: 0.5em;">
<div id="projectname">Irrlicht 3D Engine
</div>
</td>
<td> <div id="MSearchBox" class="MSearchBoxInactive">
<span class="left">
<img id="MSearchSelect" src="search/mag_sel.png"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
alt=""/>
<input type="text" id="MSearchField" value="Search" accesskey="S"
onfocus="searchBox.OnSearchFieldFocus(true)"
onblur="searchBox.OnSearchFieldFocus(false)"
onkeyup="searchBox.OnSearchFieldChange(event)"/>
</span><span class="right">
<a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Generated by Doxygen 1.7.5.1 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "search",false,'Search');
</script>
<script type="text/javascript" src="dynsections.js"></script>
</div>
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
initNavTree('example013.html','');
</script>
<div id="doc-content">
<div class="header">
<div class="headertitle">
<div class="title">Tutorial 13: Render To Texture </div> </div>
</div>
<div class="contents">
<div class="textblock"><div class="image">
<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>
<p>In the beginning, everything as usual. Include the needed headers, ask the user for the rendering driver, create the Irrlicht Device: </p>
<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 &quot;<a class="code" href="driver_choice_8h.html">driverChoice.h</a>&quot;</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, &quot;Irrlicht.lib&quot;)</span>
<span class="preprocessor"></span><span class="preprocessor">#endif</span>
<span class="preprocessor"></span>
<span class="keywordtype">int</span> main()
{
<span class="comment">// ask user for driver</span>
<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0" title="An enum for all types of drivers the Irrlicht Engine supports.">video::E_DRIVER_TYPE</a> driverType=driverChoiceConsole();
<span class="keywordflow">if</span> (driverType==<a class="code" href="namespaceirr_1_1video.html#ae35a6de6d436c76107ad157fe42356d0ae685cada50f8c100403134d932d0414c" title="No driver, just for counting the elements.">video::EDT_COUNT</a>)
<span class="keywordflow">return</span> 1;
<span class="comment">// create device and exit if creation failed</span>
<a class="code" href="classirr_1_1_irrlicht_device.html" title="The Irrlicht device. You can create it with createDevice() or createDeviceEx().">IrrlichtDevice</a> *device =
<a class="code" href="namespaceirr.html#abaf4d8719cc26b0d30813abf85e47c76" title="Creates an Irrlicht device. The Irrlicht device is the root object for using the engine.">createDevice</a>(driverType, <a class="code" href="classirr_1_1core_1_1dimension2d.html">core::dimension2d&lt;u32&gt;</a>(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>
<a class="code" href="classirr_1_1video_1_1_i_video_driver.html" title="Interface to driver which is able to perform 2d and 3d graphics functions.">video::IVideoDriver</a>* driver = device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#ada90707ba5c645d47e000e4e0f87c4c4" title="Provides access to the video driver for drawing 3d and 2d geometry.">getVideoDriver</a>();
<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html" title="The Scene Manager manages scene nodes, mesh recources, cameras and all the other stuff.">scene::ISceneManager</a>* smgr = device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#a891b503ff4d5041296d88f23f97d7b3d" title="Provides access to the scene manager.">getSceneManager</a>();
<a class="code" href="classirr_1_1gui_1_1_i_g_u_i_environment.html" title="GUI Environment. Used as factory and manager of all other GUI elements.">gui::IGUIEnvironment</a>* env = device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#af7491b8c5ef4f71360f30fbad90ae35c" title="Provides access to the 2d user interface environment.">getGUIEnvironment</a>();
</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. </p>
<div class="fragment"><pre class="fragment"> <span class="comment">// load and display animated fairy mesh</span>
scene::IAnimatedMeshSceneNode* fairy = smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a8e2e0cd3a27e85b4116855dd2f3365b8" title="Adds a scene node for rendering an animated mesh model.">addAnimatedMeshSceneNode</a>(
smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a63894c3f3d46cfc385116f1705935e03" title="Get pointer to an animateable mesh. Loads the file if not loaded already.">getMesh</a>(<span class="stringliteral">&quot;../../media/faerie.md2&quot;</span>));
<span class="keywordflow">if</span> (fairy)
{
fairy-&gt;setMaterialTexture(0,
driver-&gt;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#af4055165190e4adf221c6dc6f2434ea0" title="Get access to a named texture.">getTexture</a>(<span class="stringliteral">&quot;../../media/faerie2.bmp&quot;</span>)); <span class="comment">// set diffuse texture</span>
fairy-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" 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#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-10,0,-100));
fairy-&gt;setMD2Animation ( <a class="code" href="namespaceirr_1_1scene.html#a08d4a84966e1d2886d0d57e4acbb4f19a35893ae58423c41dace23ad13e262e2c">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. </p>
<div class="fragment"><pre class="fragment"> <span class="comment">// add white light</span>
smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a2e6442f8c95a544c355bd137ccdb7095" title="Adds a dynamic light scene node to the scene graph.">addLightSceneNode</a>(0, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" 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;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a8a424accb615c4f60fde59f55033a816" title="Sets ambient color of the scene.">setAmbientLight</a>(video::SColor(0,60,60,60));
</pre></div><p>The next is just some standard stuff: Add a test cube and let it rotate to make the scene more interesting. The user defined camera and cursor setup is made later on, right before the render loop. </p>
<div class="fragment"><pre class="fragment"> <span class="comment">// create test cube</span>
scene::ISceneNode* test = smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a23d1328c68b1585f613108f386fabc1c" title="Adds a cube scene node.">addCubeSceneNode</a>(60);
<span class="comment">// let the cube rotate and set some light settings</span>
scene::ISceneNodeAnimator* anim = smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a29efe9505de4e5dc2218283ef0c2a64d" title="Creates a rotation animator, which rotates the attached scene node around itself.">createRotationAnimator</a>(
<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" 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#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-100,0,-100));
test-&gt;setMaterialFlag(<a class="code" href="namespaceirr_1_1video.html#a8a3bc00ae8137535b9fbc5f40add70d3acea597a2692b8415486a464a7f954d34" 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;<a class="code" href="classirr_1_1_irrlicht_device.html#a3d7c98d520bf18ce1973c6f1439a7c0f" title="Sets the caption of the window.">setWindowCaption</a>(L<span class="stringliteral">&quot;Irrlicht Engine - Render to Texture and Specular Highlights example&quot;</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. </p>
<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;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#adde468368b77441ada246e1603da4f47" title="Queries the features of the driver.">queryFeature</a>(<a class="code" href="namespaceirr_1_1video.html#a57b1721e42a79c5dcf8e830e3621e08fa331e98faf8143ec5d7625255531ad47d" title="Is driver able to render to a surface?">video::EVDF_RENDER_TO_TARGET</a>))
{
rt = driver-&gt;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#aa704cece826ee37d02e4bb054b0b8797" title="Adds a new render target texture to the texture cache.">addRenderTargetTexture</a>(core::dimension2d&lt;u32&gt;(256,256), <span class="stringliteral">&quot;RTT1&quot;</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;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#afc3733849319078d5d22d94f58c7d1f2" title="Adds a camera scene node to the scene graph and sets it as active camera.">addCameraSceneNode</a>(0, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(10,10,-80),
<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" 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;<a class="code" href="classirr_1_1gui_1_1_i_g_u_i_environment.html#a54ce9072ea7b89cdaea65306e93ba90c" title="Returns pointer to the current gui skin.">getSkin</a>();
gui::IGUIFont* font = env-&gt;<a class="code" href="classirr_1_1gui_1_1_i_g_u_i_environment.html#a22074f9a1a5a86d5d216126bbb90b3b1" title="Returns pointer to the font with the specified filename.">getFont</a>(<span class="stringliteral">&quot;../../media/fonthaettenschweiler.bmp&quot;</span>);
<span class="keywordflow">if</span> (font)
skin-&gt;setFont(font);
gui::IGUIStaticText* text = env-&gt;<a class="code" href="classirr_1_1gui_1_1_i_g_u_i_environment.html#adb56652b23932a391b08f710a9546ef3" title="Adds a static text.">addStaticText</a>(
L<span class="stringliteral">&quot;Your hardware or this renderer is not able to use the &quot;</span>\
L<span class="stringliteral">&quot;render to texture feature. RTT Disabled.&quot;</span>,
core::rect&lt;s32&gt;(150,20,470,60));
text-&gt;setOverrideColor(video::SColor(100,255,255,255));
}
<span class="comment">// add fps camera</span>
scene::ICameraSceneNode* fpsCamera = smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#ac312cbc85161678d00192880f2cdddbb" title="Adds a camera scene node with an animator which provides mouse and keyboard control appropriate for f...">addCameraSceneNodeFPS</a>();
fpsCamera-&gt;setPosition(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(-50,50,-150));
<span class="comment">// disable mouse cursor</span>
device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#a500a3b7bf69487ff7e2075dd0b0db529" title="Provides access to the cursor control.">getCursorControl</a>()-&gt;setVisible(<span class="keyword">false</span>);
</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 visibility of the test cube, because it has the render target texture applied to it. That's it, wasn't too complicated I hope. :) </p>
<div class="fragment"><pre class="fragment"> <span class="keywordtype">int</span> lastFPS = -1;
<span class="keywordflow">while</span>(device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#a0489f8151dc43f6f41503ffb5a160b35" title="Runs the device.">run</a>())
<span class="keywordflow">if</span> (device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#abd3c88336b739da2694883d5ffd25a70" title="Returns if the window is active.">isWindowActive</a>())
{
driver-&gt;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a015b8f2f18c260a00a858181be1e9945" title="Applications must call this method before performing any rendering.">beginScene</a>(<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;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a8c38a8d8d6d49be53bda55eb0749e7eb" title="Sets a new render target.">setRenderTarget</a>(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;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a5d19b7a6803a0a021082fc2b86043b3d" title="Sets the currently active camera.">setActiveCamera</a>(fixedCam);
<span class="comment">// draw whole scene into render buffer</span>
smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a04240262904667c821bd9de5e5fd9b02" title="Draws all the scene nodes.">drawAll</a>();
<span class="comment">// set back old render target</span>
<span class="comment">// The buffer might have been distorted, so clear it</span>
driver-&gt;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a8c38a8d8d6d49be53bda55eb0749e7eb" title="Sets a new render target.">setRenderTarget</a>(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;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a5d19b7a6803a0a021082fc2b86043b3d" title="Sets the currently active camera.">setActiveCamera</a>(fpsCamera);
}
<span class="comment">// draw scene normally</span>
smgr-&gt;<a class="code" href="classirr_1_1scene_1_1_i_scene_manager.html#a04240262904667c821bd9de5e5fd9b02" title="Draws all the scene nodes.">drawAll</a>();
env-&gt;<a class="code" href="classirr_1_1gui_1_1_i_g_u_i_environment.html#aa6ba29bbf3121a5954cfa5a9ca72982f" title="Draws all gui elements by traversing the GUI environment starting at the root node.">drawAll</a>();
driver-&gt;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a75f61a93c5fc9fdf161c044d27bc994e" title="Presents the rendered image to the screen.">endScene</a>();
<span class="comment">// display frames per second in window title</span>
<span class="keywordtype">int</span> fps = driver-&gt;<a class="code" href="classirr_1_1video_1_1_i_video_driver.html#a5b71428402c0b6a3b18b8f2fa408af13" title="Returns current frames per second value.">getFPS</a>();
<span class="keywordflow">if</span> (lastFPS != fps)
{
<a class="code" href="namespaceirr_1_1core.html#aef83fafbb1b36fcce44c07c9be23a7f2" title="Typedef for wide character strings.">core::stringw</a> str = L<span class="stringliteral">&quot;Irrlicht Engine - Render to Texture and Specular Highlights example&quot;</span>;
str += <span class="stringliteral">&quot; FPS:&quot;</span>;
str += fps;
device-&gt;<a class="code" href="classirr_1_1_irrlicht_device.html#a3d7c98d520bf18ce1973c6f1439a7c0f" title="Sets the caption of the window.">setWindowCaption</a>(str.c_str());
lastFPS = fps;
}
}
device-&gt;<a class="code" href="classirr_1_1_i_reference_counted.html#afb169a857e0d2cdb96b8821cb9bff17a" title="Drops the object. Decrements the reference counter by one.">drop</a>(); <span class="comment">// drop device</span>
<span class="keywordflow">return</span> 0;
}
</pre></div> </div></div>
</div>
<div id="nav-path" class="navpath">
<ul>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
<a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(0)"><span class="SelectionMark">&#160;</span>All</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(1)"><span class="SelectionMark">&#160;</span>Classes</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(2)"><span class="SelectionMark">&#160;</span>Namespaces</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(3)"><span class="SelectionMark">&#160;</span>Files</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(4)"><span class="SelectionMark">&#160;</span>Functions</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(5)"><span class="SelectionMark">&#160;</span>Variables</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(6)"><span class="SelectionMark">&#160;</span>Typedefs</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(7)"><span class="SelectionMark">&#160;</span>Enumerations</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(8)"><span class="SelectionMark">&#160;</span>Enumerator</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(9)"><span class="SelectionMark">&#160;</span>Friends</a><a class="SelectItem" href="javascript:void(0)" onclick="searchBox.OnSelectItem(10)"><span class="SelectionMark">&#160;</span>Defines</a></div>
<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0"
name="MSearchResults" id="MSearchResults">
</iframe>
</div>
<li class="footer">
<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht
Engine</a> Documentation &copy; 2003-2012 by Nikolaus Gebhardt. Generated on Tue Jan 19 2016 16:08:47 for Irrlicht 3D Engine by
<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
</ul>
</div>
</body>
</html>