aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/others/irrlicht-1.8.1/doc/html/example003.html
diff options
context:
space:
mode:
Diffstat (limited to 'src/others/irrlicht-1.8.1/doc/html/example003.html')
-rw-r--r--src/others/irrlicht-1.8.1/doc/html/example003.html264
1 files changed, 264 insertions, 0 deletions
diff --git a/src/others/irrlicht-1.8.1/doc/html/example003.html b/src/others/irrlicht-1.8.1/doc/html/example003.html
new file mode 100644
index 0000000..411fbff
--- /dev/null
+++ b/src/others/irrlicht-1.8.1/doc/html/example003.html
@@ -0,0 +1,264 @@
1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2<html xmlns="http://www.w3.org/1999/xhtml">
3<head>
4<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
5<title>Irrlicht 3D Engine: Tutorial 3: Custom SceneNode</title>
6
7<link href="tabs.css" rel="stylesheet" type="text/css"/>
8<link href="doxygen.css" rel="stylesheet" type="text/css" />
9<link href="navtree.css" rel="stylesheet" type="text/css"/>
10<script type="text/javascript" src="jquery.js"></script>
11<script type="text/javascript" src="resize.js"></script>
12<script type="text/javascript" src="navtree.js"></script>
13<script type="text/javascript">
14 $(document).ready(initResizable);
15</script>
16<link href="search/search.css" rel="stylesheet" type="text/css"/>
17<script type="text/javascript" src="search/search.js"></script>
18<script type="text/javascript">
19 $(document).ready(function() { searchBox.OnSelectItem(0); });
20</script>
21
22</head>
23<body>
24<div id="top"><!-- do not remove this div! -->
25
26
27<div id="titlearea">
28<table cellspacing="0" cellpadding="0">
29 <tbody>
30 <tr style="height: 56px;">
31
32 <td id="projectlogo"><img alt="Logo" src="irrlichtlogo.png"/></td>
33
34
35 <td style="padding-left: 0.5em;">
36 <div id="projectname">Irrlicht 3D Engine
37
38 </div>
39
40 </td>
41
42
43
44
45 <td> <div id="MSearchBox" class="MSearchBoxInactive">
46 <span class="left">
47 <img id="MSearchSelect" src="search/mag_sel.png"
48 onmouseover="return searchBox.OnSearchSelectShow()"
49 onmouseout="return searchBox.OnSearchSelectHide()"
50 alt=""/>
51 <input type="text" id="MSearchField" value="Search" accesskey="S"
52 onfocus="searchBox.OnSearchFieldFocus(true)"
53 onblur="searchBox.OnSearchFieldFocus(false)"
54 onkeyup="searchBox.OnSearchFieldChange(event)"/>
55 </span><span class="right">
56 <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
57 </span>
58 </div>
59</td>
60
61
62 </tr>
63 </tbody>
64</table>
65</div>
66
67<!-- Generated by Doxygen 1.7.5.1 -->
68<script type="text/javascript">
69var searchBox = new SearchBox("searchBox", "search",false,'Search');
70</script>
71<script type="text/javascript" src="dynsections.js"></script>
72</div>
73<div id="side-nav" class="ui-resizable side-nav-resizable">
74 <div id="nav-tree">
75 <div id="nav-tree-contents">
76 </div>
77 </div>
78 <div id="splitbar" style="-moz-user-select:none;"
79 class="ui-resizable-handle">
80 </div>
81</div>
82<script type="text/javascript">
83 initNavTree('example003.html','');
84</script>
85<div id="doc-content">
86<div class="header">
87 <div class="headertitle">
88<div class="title">Tutorial 3: Custom SceneNode </div> </div>
89</div>
90<div class="contents">
91<div class="textblock"><div class="image">
92<img src="003shot.jpg" alt="003shot.jpg"/>
93</div>
94 <p>This Tutorial is more advanced than the previous ones. If you are currently just playing around with the Irrlicht engine, you may want to look at other examples first. This tutorials shows how to create a custom scene node and how to use it in the engine. A custom scene node is needed if you want to implement a render technique the Irrlicht Engine currently does not support. For example, you can write an indoor portal based renderer or an advanced terrain scene node with it. By creating custom scene nodes, you can easily extend the Irrlicht Engine and adapt it to your own needs.</p>
95<p>I will keep the tutorial simple: Keep everything very short, everything in one .cpp file, and I'll use the engine here as in all other tutorials.</p>
96<p>To start, I include the header files, use the irr namespace, and tell the linker to link with the .lib file. </p>
97<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>
98<span class="preprocessor">#include &quot;<a class="code" href="driver_choice_8h.html">driverChoice.h</a>&quot;</span>
99
100<span class="keyword">using namespace </span>irr;
101
102<span class="preprocessor">#ifdef _MSC_VER</span>
103<span class="preprocessor"></span><span class="preprocessor">#pragma comment(lib, &quot;Irrlicht.lib&quot;)</span>
104<span class="preprocessor">#endif</span>
105</pre></div><p>Here comes the more sophisticated part of this tutorial: The class of our very own custom scene node. To keep it simple, our scene node will not be an indoor portal renderer nor a terrain scene node, but a simple tetraeder, a 3d object consisting of 4 connected vertices, which only draws itself and does nothing more. Note that this scenario does not require a custom scene node in Irrlicht. Instead one would create a mesh from the geometry and pass it to a <a class="el" href="classirr_1_1scene_1_1_i_mesh_scene_node.html" title="A scene node displaying a static mesh.">irr::scene::IMeshSceneNode</a>. This example just illustrates creation of a custom scene node in a very simple setting.</p>
106<p>To let our scene node be able to be inserted into the Irrlicht Engine scene, the class we create needs to be derived from the <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html" title="Scene node interface.">irr::scene::ISceneNode</a> class and has to override some methods. </p>
107<div class="fragment"><pre class="fragment"><span class="keyword">class </span>CSampleSceneNode : <span class="keyword">public</span> scene::ISceneNode
108{
109</pre></div><p>First, we declare some member variables: The bounding box, 4 vertices, and the material of the tetraeder. </p>
110<div class="fragment"><pre class="fragment"> core::aabbox3d&lt;f32&gt; Box;
111 video::S3DVertex Vertices[4];
112 video::SMaterial Material;
113</pre></div><p>The parameters of the constructor specify the parent of the scene node, a pointer to the scene manager, and an id of the scene node. In the constructor we call the parent class' constructor, set some properties of the material, and create the 4 vertices of the tetraeder we will draw later. </p>
114<div class="fragment"><pre class="fragment"><span class="keyword">public</span>:
115
116 CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, <a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> <span class="keywordtype">id</span>)
117 : scene::ISceneNode(parent, mgr, id)
118 {
119 Material.Wireframe = <span class="keyword">false</span>;
120 Material.Lighting = <span class="keyword">false</span>;
121
122 Vertices[0] = video::S3DVertex(0,0,10, 1,1,0,
123 video::SColor(255,0,255,255), 0, 1);
124 Vertices[1] = video::S3DVertex(10,0,-10, 1,0,0,
125 video::SColor(255,255,0,255), 1, 1);
126 Vertices[2] = video::S3DVertex(0,20,0, 0,1,1,
127 video::SColor(255,255,255,0), 1, 0);
128 Vertices[3] = video::S3DVertex(-10,0,-10, 0,0,1,
129 video::SColor(255,0,255,0), 0, 0);
130</pre></div><p>The Irrlicht Engine needs to know the bounding box of a scene node. It will use it for automatic culling and other things. Hence, we need to create a bounding box from the 4 vertices we use. If you do not want the engine to use the box for automatic culling, and/or don't want to create the box, you could also call <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html#a5fcd62dbf524b8d2d6daa61c7d6cf119" title="Enables or disables automatic culling based on the bounding box.">irr::scene::ISceneNode::setAutomaticCulling()</a> with <a class="el" href="namespaceirr_1_1scene.html#acabb2772476aa3706e65a7dc77fd9cceacf8b41fd7d45781cfb2eb7039ba6b09a">irr::scene::EAC_OFF</a>. </p>
131<div class="fragment"><pre class="fragment"> Box.reset(Vertices[0].Pos);
132 <span class="keywordflow">for</span> (<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a> i=1; i&lt;4; ++i)
133 Box.addInternalPoint(Vertices[i].Pos);
134 }
135</pre></div><p>Before it is drawn, the <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html#ac9795bfcb88dcaf8cba6ea3296e5d8d0" title="This method is called just before the rendering process of the whole scene.">irr::scene::ISceneNode::OnRegisterSceneNode()</a> method of every scene node in the scene is called by the scene manager. If the scene node wishes to draw itself, it may register itself in the scene manager to be drawn. This is necessary to tell the scene manager when it should call <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html#aff530cc4856792101d0aedee51ce35fa" title="Renders the node.">irr::scene::ISceneNode::render()</a>. For example, normal scene nodes render their content one after another, while stencil buffer shadows would like to be drawn after all other scene nodes. And camera or light scene nodes need to be rendered before all other scene nodes (if at all). So here we simply register the scene node to render normally. If we would like to let it be rendered like cameras or light, we would have to call SceneManager-&gt;registerNodeForRendering(this, SNRT_LIGHT_AND_CAMERA); After this, we call the actual <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html#ac9795bfcb88dcaf8cba6ea3296e5d8d0" title="This method is called just before the rendering process of the whole scene.">irr::scene::ISceneNode::OnRegisterSceneNode()</a> method of the base class, which simply lets also all the child scene nodes of this node register themselves. </p>
136<div class="fragment"><pre class="fragment"> <span class="keyword">virtual</span> <span class="keywordtype">void</span> OnRegisterSceneNode()
137 {
138 <span class="keywordflow">if</span> (IsVisible)
139 SceneManager-&gt;registerNodeForRendering(<span class="keyword">this</span>);
140
141 ISceneNode::OnRegisterSceneNode();
142 }
143</pre></div><p>In the render() method most of the interesting stuff happens: The Scene node renders itself. We override this method and draw the tetraeder. </p>
144<div class="fragment"><pre class="fragment"> <span class="keyword">virtual</span> <span class="keywordtype">void</span> render()
145 {
146 <a class="code" href="namespaceirr.html#ae9f8ec82692ad3b83c21f555bfa70bcc" title="16 bit unsigned variable.">u16</a> indices[] = { 0,2,3, 2,1,3, 1,0,3, 2,0,1 };
147 video::IVideoDriver* driver = SceneManager-&gt;getVideoDriver();
148
149 driver-&gt;setMaterial(Material);
150 driver-&gt;setTransform(<a class="code" href="namespaceirr_1_1video.html#a15b57657a320243be03ae6f66fcff43da843cf42adb3fa9caf61c9e228cf14e85" title="World transformation.">video::ETS_WORLD</a>, AbsoluteTransformation);
151 driver-&gt;drawVertexPrimitiveList(&amp;Vertices[0], 4, &amp;indices[0], 4, <a class="code" href="namespaceirr_1_1video.html#a0e3b59e025e0d0db0ed2ee0ce904deaca98c8b791280bbf9252c4f4a37e91a416" title="Standard vertex type used by the Irrlicht engine, video::S3DVertex.">video::EVT_STANDARD</a>, <a class="code" href="namespaceirr_1_1scene.html#a5d7de82f2169761194b2f44d95cdc1dca237fc76e4b259febd27b4b84066ca581" title="Explicitly set all vertices for each triangle.">scene::EPT_TRIANGLES</a>, <a class="code" href="namespaceirr_1_1video.html#af152a1edea2579f0517e0049525acb55a1c79610ea1191e124887efa16626f299">video::EIT_16BIT</a>);
152 }
153</pre></div><p>And finally we create three small additional methods. <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html#a223f718fc2f4944b5ad28c592f6cc8c6" title="Get the axis aligned, not transformed bounding box of this node.">irr::scene::ISceneNode::getBoundingBox()</a> returns the bounding box of this scene node, <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html#afa904bf3742941087aaee56b0b4cdfe2" title="Get amount of materials used by this scene node.">irr::scene::ISceneNode::getMaterialCount()</a> returns the amount of materials in this scene node (our tetraeder only has one material), and <a class="el" href="classirr_1_1scene_1_1_i_scene_node.html#a1f44d8cf753b2e4c17c90d4fc2ed05b2" title="Returns the material based on the zero based index i.">irr::scene::ISceneNode::getMaterial()</a> returns the material at an index. Because we have only one material here, we can return the only one material, assuming that no one ever calls getMaterial() with an index greater than 0. </p>
154<div class="fragment"><pre class="fragment"> <span class="keyword">virtual</span> <span class="keyword">const</span> core::aabbox3d&lt;f32&gt;&amp; getBoundingBox()<span class="keyword"> const</span>
155<span class="keyword"> </span>{
156 <span class="keywordflow">return</span> Box;
157 }
158
159 <span class="keyword">virtual</span> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> getMaterialCount()<span class="keyword"> const</span>
160<span class="keyword"> </span>{
161 <span class="keywordflow">return</span> 1;
162 }
163
164 <span class="keyword">virtual</span> video::SMaterial&amp; getMaterial(<a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> i)
165 {
166 <span class="keywordflow">return</span> Material;
167 }
168};
169</pre></div><p>That's it. The Scene node is done. Now we simply have to start the engine, create the scene node and a camera, and look at the result. </p>
170<div class="fragment"><pre class="fragment"><span class="keywordtype">int</span> main()
171{
172 <span class="comment">// ask user for driver</span>
173 <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();
174 <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>)
175 <span class="keywordflow">return</span> 1;
176
177 <span class="comment">// create device</span>
178
179 IrrlichtDevice *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,
180 core::dimension2d&lt;u32&gt;(640, 480), 16, <span class="keyword">false</span>);
181
182 <span class="keywordflow">if</span> (device == 0)
183 <span class="keywordflow">return</span> 1; <span class="comment">// could not create selected driver.</span>
184
185 <span class="comment">// create engine and camera</span>
186
187 device-&gt;setWindowCaption(L<span class="stringliteral">&quot;Custom Scene Node - Irrlicht Engine Demo&quot;</span>);
188
189 video::IVideoDriver* driver = device-&gt;getVideoDriver();
190 scene::ISceneManager* smgr = device-&gt;getSceneManager();
191
192 smgr-&gt;addCameraSceneNode(0, <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,-40,0), <a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0,0,0));
193</pre></div><p>Create our scene node. I don't check the result of calling new, as it should throw an exception rather than returning 0 on failure. Because the new node will create itself with a reference count of 1, and then will have another reference added by its parent scene node when it is added to the scene, I need to drop my reference to it. Best practice is to drop it only *after* I have finished using it, regardless of what the reference count of the object is after creation. </p>
194<div class="fragment"><pre class="fragment"> CSampleSceneNode *myNode =
195 <span class="keyword">new</span> CSampleSceneNode(smgr-&gt;getRootSceneNode(), smgr, 666);
196</pre></div><p>To animate something in this boring scene consisting only of one tetraeder, and to show that you now can use your scene node like any other scene node in the engine, we add an animator to the scene node, which rotates the node a little bit. <a class="el" href="classirr_1_1scene_1_1_i_scene_manager.html#a29efe9505de4e5dc2218283ef0c2a64d" title="Creates a rotation animator, which rotates the attached scene node around itself.">irr::scene::ISceneManager::createRotationAnimator()</a> could return 0, so should be checked. </p>
197<div class="fragment"><pre class="fragment"> scene::ISceneNodeAnimator* anim =
198 smgr-&gt;createRotationAnimator(<a class="code" href="namespaceirr_1_1core.html#a06f169d08b5c429f5575acb7edbad811" title="Typedef for a f32 3d vector.">core::vector3df</a>(0.8f, 0, 0.8f));
199
200 <span class="keywordflow">if</span>(anim)
201 {
202 myNode-&gt;addAnimator(anim);
203</pre></div><p>I'm done referring to anim, so must <a class="el" href="classirr_1_1_i_reference_counted.html#afb169a857e0d2cdb96b8821cb9bff17a" title="Drops the object. Decrements the reference counter by one.">irr::IReferenceCounted::drop()</a> this reference now because it was produced by a createFoo() function. As I shouldn't refer to it again, ensure that I can't by setting to 0. </p>
204<div class="fragment"><pre class="fragment"> anim-&gt;drop();
205 anim = 0;
206 }
207</pre></div><p>I'm done with my CSampleSceneNode object, and so must drop my reference. This won't delete the object, yet, because it is still attached to the scene graph, which prevents the deletion until the graph is deleted or the custom scene node is removed from it. </p>
208<div class="fragment"><pre class="fragment"> myNode-&gt;drop();
209 myNode = 0; <span class="comment">// As I shouldn&#39;t refer to it again, ensure that I can&#39;t</span>
210</pre></div><p>Now draw everything and finish. </p>
211<div class="fragment"><pre class="fragment"> <a class="code" href="namespaceirr.html#a0416a53257075833e7002efd0a18e804" title="32 bit unsigned variable.">u32</a> frames=0;
212 <span class="keywordflow">while</span>(device-&gt;run())
213 {
214 driver-&gt;beginScene(<span class="keyword">true</span>, <span class="keyword">true</span>, video::SColor(0,100,100,100));
215
216 smgr-&gt;drawAll();
217
218 driver-&gt;endScene();
219 <span class="keywordflow">if</span> (++frames==100)
220 {
221 <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 [&quot;</span>;
222 str += driver-&gt;getName();
223 str += L<span class="stringliteral">&quot;] FPS: &quot;</span>;
224 str += (<a class="code" href="namespaceirr.html#ac66849b7a6ed16e30ebede579f9b47c6" title="32 bit signed variable.">s32</a>)driver-&gt;getFPS();
225
226 device-&gt;setWindowCaption(str.c_str());
227 frames=0;
228 }
229 }
230
231 device-&gt;drop();
232
233 <span class="keywordflow">return</span> 0;
234}
235</pre></div><p>That's it. Compile and play around with the program. </p>
236</div></div>
237</div>
238 <div id="nav-path" class="navpath">
239 <ul>
240<!-- window showing the filter options -->
241<div id="MSearchSelectWindow"
242 onmouseover="return searchBox.OnSearchSelectShow()"
243 onmouseout="return searchBox.OnSearchSelectHide()"
244 onkeydown="return searchBox.OnSearchSelectKey(event)">
245<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>
246
247<!-- iframe showing the search results (closed by default) -->
248<div id="MSearchResultsWindow">
249<iframe src="javascript:void(0)" frameborder="0"
250 name="MSearchResults" id="MSearchResults">
251</iframe>
252</div>
253
254
255 <li class="footer">
256<a href="http://irrlicht.sourceforge.net" target="_blank">Irrlicht
257Engine</a> Documentation &copy; 2003-2012 by Nikolaus Gebhardt. Generated on Sun Nov 17 2013 20:18:41 for Irrlicht 3D Engine by
258<a href="http://www.doxygen.org/index.html" target="_blank">Doxygen</a> 1.7.5.1 </li>
259 </ul>
260 </div>
261
262
263</body>
264</html>