diff options
Diffstat (limited to 'libraries/irrlicht-1.8/examples/03.CustomSceneNode/tutorial.html')
-rw-r--r-- | libraries/irrlicht-1.8/examples/03.CustomSceneNode/tutorial.html | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/examples/03.CustomSceneNode/tutorial.html b/libraries/irrlicht-1.8/examples/03.CustomSceneNode/tutorial.html new file mode 100644 index 0000000..becc3d7 --- /dev/null +++ b/libraries/irrlicht-1.8/examples/03.CustomSceneNode/tutorial.html | |||
@@ -0,0 +1,222 @@ | |||
1 | <html> | ||
2 | <head> | ||
3 | <title>Irrlicht Engine Tutorial</title> | ||
4 | <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> | ||
5 | </head> | ||
6 | |||
7 | <body bgcolor="#FFFFFF" leftmargin="0" topmargin="0" marginwidth="0" marginheight="0"> | ||
8 | <br> | ||
9 | <table width="95%" border="0" cellspacing="0" cellpadding="2" align="center"> | ||
10 | <tr> | ||
11 | <td bgcolor="#666699" width="10"><b><a href="http://irrlicht.sourceforge.net" target="_blank"><img src="../../media/irrlichtlogo.jpg" width="88" height="31" border="0"></a></b></td> | ||
12 | <td bgcolor="#666699" width="100%"> | ||
13 | <div align="center"> | ||
14 | <div align="center"></div> | ||
15 | <div align="left"><b><font color="#FFFFFF">Tutorial 3.CustomSceneNode</font></b></div> | ||
16 | </div> | ||
17 | </td> | ||
18 | </tr> | ||
19 | <tr bgcolor="#eeeeff"> | ||
20 | <td height="90" colspan="2"> | ||
21 | <div align="left"> | ||
22 | <p>This Tutorial is a tutorial for more advanced developers. If you are | ||
23 | currently just playing around with the Irrlicht engine, please look | ||
24 | at other examples first. This tutorial shows how to create a custom | ||
25 | scene node and how to use it in the engine. A custom scene node is needed, | ||
26 | if you want to implement a render technique, the Irrlicht Engine is | ||
27 | currently not supporting. For example you can write a indoor portal | ||
28 | based renderer or a advanced terrain scene node with it. With creating | ||
29 | custom scene nodes, you can easily extend the Irrlicht Engine and adapt | ||
30 | it to your needs.</p> | ||
31 | <p>I will keep the tutorial simple: Keep everything very short, everything | ||
32 | in one .cpp file, and I'll use the engine here as in all other tutorials. | ||
33 | At the end of the tutorial, the result will look like the image below. | ||
34 | This looks not very exciting, but it is a complete customized scene | ||
35 | node and a good point to start from creating you own scene nodes.</p> | ||
36 | <p align="center"><img src="../../media/003shot.jpg" width="259" height="204"><br> | ||
37 | </p> | ||
38 | </div> | ||
39 | </td> | ||
40 | </tr> | ||
41 | </table> | ||
42 | <br> | ||
43 | <table width="95%" border="0" cellspacing="0" cellpadding="2" align="center"> | ||
44 | <tr> | ||
45 | <td bgcolor="#666699"> <div align="center"><b><font color="#FFFFFF"></font></b></div> | ||
46 | <b><font color="#FFFFFF">Lets start!</font></b></td> | ||
47 | </tr> | ||
48 | <tr> | ||
49 | <td height="90" bgcolor="#eeeeff" valign="top"> <div align="left"> | ||
50 | <p>To start, I include the header files, use the irr namespace, and tell | ||
51 | the linker to link with the .lib file. </p> | ||
52 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
53 | <tr> | ||
54 | <td> <pre>#include <irrlicht.h></pre> <pre>using namespace irr;</pre> <pre>#pragma comment(lib, "Irrlicht.lib")</pre></td> | ||
55 | </tr> | ||
56 | </table> | ||
57 | <p>Here comes the most sophisticated part of this tutorial: The class | ||
58 | of our very own custom scene node. To keep it simple,<br> | ||
59 | our scene node will not be an indoor portal renderer nor a terrain scene | ||
60 | node, but a simple tetraeder, a 3d object consiting of 4 connected vertices, | ||
61 | which only draws itself and does nothing more.</p> | ||
62 | <p>To let our scene node be able to be inserted into the Irrlicht Engine | ||
63 | scene, the class we create needs only be derived from the ISceneNode | ||
64 | class and has to override some methods.</p> | ||
65 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
66 | <tr> | ||
67 | <td> <pre>class CSampleSceneNode : public scene::ISceneNode<br>{</pre> </td> | ||
68 | </tr> | ||
69 | </table> | ||
70 | <p>First, we declare some member variables, to hold data for our tetraeder: | ||
71 | The bounding box, 4 vertices, and<br> | ||
72 | the material of the tetraeder.</p> | ||
73 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
74 | <tr> | ||
75 | <td> <pre>core::aabbox3d<f32> Box;<br>video::S3DVertex Vertices[4];<br>video::SMaterial Material;</pre> </td> | ||
76 | </tr> | ||
77 | </table> | ||
78 | <p>The parameters of the constructor specify the parent of the scene node, | ||
79 | a pointer to the scene manager, and an id of the scene node. In the | ||
80 | constructor itself, we call the parent classes constructor, set some | ||
81 | properties of the material we use to draw the scene node and create | ||
82 | the 4 vertices of the tetraeder we will draw later. </p> | ||
83 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
84 | <tr> | ||
85 | <td> <pre>public:</pre> <pre>CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id) | ||
86 | : scene::ISceneNode(parent, mgr, id) | ||
87 | { | ||
88 | Material.Wireframe = false; | ||
89 | Material.Lighting = false;</pre> | ||
90 | <pre> Vertices[0] = video::S3DVertex(0,0,10, 1,1,0,video::SColor(255,0,255,255),0,1); | ||
91 | Vertices[1] = video::S3DVertex(10,0,-10, 1,0,0,video::SColor(255,255,0,255),1,1); | ||
92 | Vertices[2] = video::S3DVertex(0,20,0, 0,1,1,video::SColor(255,255,255,0),1,0); | ||
93 | Vertices[3] = video::S3DVertex(-10,0,-10, 0,0,1,video::SColor(255,0,255,0),0,0); | ||
94 | </pre></td> | ||
95 | </tr> | ||
96 | </table> | ||
97 | <br> | ||
98 | The Irrlicht Engine needs to know the bounding box of your scene node. | ||
99 | It will use it for doing automatic culling and other things. Hence we | ||
100 | need to create a bounding box from the 4 vertices we use. If you do not | ||
101 | want the engine to use the box for automatic culling, and/or don't want | ||
102 | to create the box, you could also write<br> | ||
103 | <font face="Courier New, Courier, mono">AutomaticCullingEnabled = false;</font>.<br> | ||
104 | <br> | ||
105 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
106 | <tr> | ||
107 | <td> <pre> Box.reset(Vertices[0].Pos);<br> for (s32 i=1; i<4; ++i)<br> Box.addInternalPoint(Vertices[i].Pos); | ||
108 | }</pre> </td> | ||
109 | </tr> | ||
110 | </table> | ||
111 | <br> | ||
112 | <p>Before it is drawn, the OnPreRender() method of every scene node in | ||
113 | the scene is called by the scene manager. If the scene node wishes to | ||
114 | draw itself, it may register itself in the scene manager to be drawn. | ||
115 | This is necessary to tell the scene manager when it should call the | ||
116 | ::render method. For example normal scene nodes render their content | ||
117 | one after another, while stencil buffer shadows would like to be drawn | ||
118 | after all other scene nodes. And camera or light scene nodes need to | ||
119 | be rendered before all other scene nodes (if at all). <br> | ||
120 | So here we simply register the scene node to get rendered normally. | ||
121 | If we would like to let it be rendered like cameras or light, we would | ||
122 | have to call SceneManager->registerNodeForRendering(this, SNRT_LIGHT_AND_CAMERA); | ||
123 | <br> | ||
124 | After this, we call the OnPreRender-method of the base class ISceneNode, | ||
125 | which simply lets also all the child scene nodes of this node register | ||
126 | themselves. </p> | ||
127 | </div> | ||
128 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
129 | <tr> | ||
130 | <td> <pre>virtual void OnPreRender()<br>{<br> if (IsVisible)<br> SceneManager->registerNodeForRendering(this); | ||
131 | |||
132 | ISceneNode::OnPreRender(); | ||
133 | }</pre> </td> | ||
134 | </tr> | ||
135 | </table> | ||
136 | <p>In the render() method most of the interresting stuff happenes: The Scene | ||
137 | node renders itself. We override this method and draw the tetraeder.</p> | ||
138 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
139 | <tr> | ||
140 | <td> <pre>virtual void render()<br>{<br> u16 indices[] = { 0,2,3, 2,1,3, 1,0,3, 2,0,1 }; | ||
141 | video::IVideoDriver* driver = SceneManager->getVideoDriver();</pre> | ||
142 | <pre> driver->setMaterial(Material); | ||
143 | driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); | ||
144 | driver->drawIndexedTriangleList(&Vertices[0], 4, &indices[0], 4); | ||
145 | }</pre> </td> | ||
146 | </tr> | ||
147 | </table> | ||
148 | <p> At least, we create three small additional methods. GetBoundingBox() | ||
149 | returns the bounding box of this scene node, <br> | ||
150 | GetMaterialCount() returns the amount of materials in this scene node | ||
151 | (our tetraeder only has one material), and getMaterial() returns the material | ||
152 | at an index. Because we have only one material here, we can return the | ||
153 | only one material, assuming that no one ever calls getMaterial() with | ||
154 | an index greater than 0. </p> | ||
155 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
156 | <tr> | ||
157 | <td><pre> virtual const core::aabbox3d<f32>& getBoundingBox() const<br> {<br> return Box;<br> }</pre> <pre> virtual u32 getMaterialCount() | ||
158 | { | ||
159 | return 1; | ||
160 | }</pre> <pre> virtual video::SMaterial& getMaterial(u32 i) | ||
161 | { | ||
162 | return Material; | ||
163 | } | ||
164 | };</pre></td> | ||
165 | </tr> | ||
166 | </table> | ||
167 | <p>That's it. The Scene node is done. Now we simply have to start the engine, | ||
168 | create the scene node and a camera, and look at the result.</p> | ||
169 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
170 | <tr> | ||
171 | <td> <pre>int main()<br>{ | ||
172 | IrrlichtDevice *device = | ||
173 | createDevice(video::EDT_OPENGL, core::dimension2d<s32>(640, 480), 16, false);</pre> <pre> device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo");</pre> <pre> video::IVideoDriver* driver = device->getVideoDriver(); | ||
174 | scene::ISceneManager* smgr = device->getSceneManager();</pre> | ||
175 | <pre> smgr->addCameraSceneNode(0, core::vector3df(0,-40,0), core::vector3df(0,0,0)); | ||
176 | </pre></td> | ||
177 | </tr> | ||
178 | </table> | ||
179 | <p>Create our scene node. Note that it is dropped (->drop()) instantly | ||
180 | after we create it. This is possible because the scene manager now takes | ||
181 | care of it. This is not nessecary, it would also be possible to drop it | ||
182 | at the end of the program.</p> | ||
183 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
184 | <tr> | ||
185 | <td> <pre>CSampleSceneNode *myNode = <br> new CSampleSceneNode(smgr->getRootSceneNode(), smgr, 666); | ||
186 | |||
187 | myNode->drop();</pre> </td> | ||
188 | </tr> | ||
189 | </table> | ||
190 | <p>To animate something in this boring scene consisting only of one tetraeder, | ||
191 | and to show, that you now can use your scene node like any other scene | ||
192 | node in the engine, we add an animator to the scene node, which rotates | ||
193 | the node a little bit. </p> | ||
194 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
195 | <tr> | ||
196 | <td> <pre>scene::ISceneNodeAnimator* anim = <br> smgr->createRotationAnimator(core::vector3df(0.8f, 0, 0.8f)); | ||
197 | |||
198 | myNode->addAnimator(anim); | ||
199 | anim->drop();</pre> </td> | ||
200 | </tr> | ||
201 | </table> | ||
202 | <p>Now draw everything and finish.</p> | ||
203 | <table width="95%" border="0" cellspacing="2" cellpadding="0" bgcolor="#CCCCCC" align="center"> | ||
204 | <tr> | ||
205 | <td> <pre> while(device->run())<br> {<br> driver->beginScene(true, true, video::SColor(0,100,100,100)); | ||
206 | |||
207 | smgr->drawAll(); | ||
208 | |||
209 | driver->endScene(); | ||
210 | } | ||
211 | |||
212 | device->drop(); | ||
213 | return 0; | ||
214 | }</pre> </td> | ||
215 | </tr> | ||
216 | </table> | ||
217 | <p>That's it. Compile and play around with the program. </p></td> | ||
218 | </tr> | ||
219 | </table> | ||
220 | <p> </p> | ||
221 | </body> | ||
222 | </html> | ||