aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/examples/03.CustomSceneNode/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/examples/03.CustomSceneNode/main.cpp534
1 files changed, 267 insertions, 267 deletions
diff --git a/libraries/irrlicht-1.8/examples/03.CustomSceneNode/main.cpp b/libraries/irrlicht-1.8/examples/03.CustomSceneNode/main.cpp
index 534f0d3..5586168 100644
--- a/libraries/irrlicht-1.8/examples/03.CustomSceneNode/main.cpp
+++ b/libraries/irrlicht-1.8/examples/03.CustomSceneNode/main.cpp
@@ -1,267 +1,267 @@
1/** Example 003 Custom SceneNode 1/** Example 003 Custom SceneNode
2 2
3This Tutorial is more advanced than the previous ones. 3This Tutorial is more advanced than the previous ones.
4If you are currently just playing around with the Irrlicht 4If you are currently just playing around with the Irrlicht
5engine, you may want to look at other examples first. 5engine, you may want to look at other examples first.
6This tutorials shows how to create a custom scene node and 6This tutorials shows how to create a custom scene node and
7how to use it in the engine. A custom scene node is needed 7how to use it in the engine. A custom scene node is needed
8if you want to implement a render technique the Irrlicht 8if you want to implement a render technique the Irrlicht
9Engine currently does not support. For example, you can write 9Engine currently does not support. For example, you can write
10an indoor portal based renderer or an advanced terrain scene 10an indoor portal based renderer or an advanced terrain scene
11node with it. By creating custom scene nodes, you can 11node with it. By creating custom scene nodes, you can
12easily extend the Irrlicht Engine and adapt it to your own 12easily extend the Irrlicht Engine and adapt it to your own
13needs. 13needs.
14 14
15I will keep the tutorial simple: Keep everything very 15I will keep the tutorial simple: Keep everything very
16short, everything in one .cpp file, and I'll use the engine 16short, everything in one .cpp file, and I'll use the engine
17here as in all other tutorials. 17here as in all other tutorials.
18 18
19To start, I include the header files, use the irr namespace, 19To start, I include the header files, use the irr namespace,
20and tell the linker to link with the .lib file. 20and tell the linker to link with the .lib file.
21*/ 21*/
22#include <irrlicht.h> 22#include <irrlicht.h>
23#include "driverChoice.h" 23#include "driverChoice.h"
24 24
25using namespace irr; 25using namespace irr;
26 26
27#ifdef _MSC_VER 27#ifdef _MSC_VER
28#pragma comment(lib, "Irrlicht.lib") 28#pragma comment(lib, "Irrlicht.lib")
29#endif 29#endif
30 30
31/* 31/*
32Here comes the more sophisticated part of this tutorial: 32Here comes the more sophisticated part of this tutorial:
33The class of our very own custom scene node. To keep it simple, 33The class of our very own custom scene node. To keep it simple,
34our scene node will not be an indoor portal renderer nor a terrain 34our scene node will not be an indoor portal renderer nor a terrain
35scene node, but a simple tetraeder, a 3d object consisting of 4 35scene node, but a simple tetraeder, a 3d object consisting of 4
36connected vertices, which only draws itself and does nothing more. 36connected vertices, which only draws itself and does nothing more.
37Note that this scenario does not require a custom scene node in Irrlicht. 37Note that this scenario does not require a custom scene node in Irrlicht.
38Instead one would create a mesh from the geometry and pass it to a 38Instead one would create a mesh from the geometry and pass it to a
39irr::scene::IMeshSceneNode. This example just illustrates creation of a custom 39irr::scene::IMeshSceneNode. This example just illustrates creation of a custom
40scene node in a very simple setting. 40scene node in a very simple setting.
41 41
42To let our scene node be able to be inserted into the Irrlicht 42To let our scene node be able to be inserted into the Irrlicht
43Engine scene, the class we create needs to be derived from the 43Engine scene, the class we create needs to be derived from the
44irr::scene::ISceneNode class and has to override some methods. 44irr::scene::ISceneNode class and has to override some methods.
45*/ 45*/
46 46
47class CSampleSceneNode : public scene::ISceneNode 47class CSampleSceneNode : public scene::ISceneNode
48{ 48{
49 49
50 /* 50 /*
51 First, we declare some member variables: 51 First, we declare some member variables:
52 The bounding box, 4 vertices, and the material of the tetraeder. 52 The bounding box, 4 vertices, and the material of the tetraeder.
53 */ 53 */
54 core::aabbox3d<f32> Box; 54 core::aabbox3d<f32> Box;
55 video::S3DVertex Vertices[4]; 55 video::S3DVertex Vertices[4];
56 video::SMaterial Material; 56 video::SMaterial Material;
57 57
58 /* 58 /*
59 The parameters of the constructor specify the parent of the scene node, 59 The parameters of the constructor specify the parent of the scene node,
60 a pointer to the scene manager, and an id of the scene node. 60 a pointer to the scene manager, and an id of the scene node.
61 In the constructor we call the parent class' constructor, 61 In the constructor we call the parent class' constructor,
62 set some properties of the material, and 62 set some properties of the material, and
63 create the 4 vertices of the tetraeder we will draw later. 63 create the 4 vertices of the tetraeder we will draw later.
64 */ 64 */
65 65
66public: 66public:
67 67
68 CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id) 68 CSampleSceneNode(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id)
69 : scene::ISceneNode(parent, mgr, id) 69 : scene::ISceneNode(parent, mgr, id)
70 { 70 {
71 Material.Wireframe = false; 71 Material.Wireframe = false;
72 Material.Lighting = false; 72 Material.Lighting = false;
73 73
74 Vertices[0] = video::S3DVertex(0,0,10, 1,1,0, 74 Vertices[0] = video::S3DVertex(0,0,10, 1,1,0,
75 video::SColor(255,0,255,255), 0, 1); 75 video::SColor(255,0,255,255), 0, 1);
76 Vertices[1] = video::S3DVertex(10,0,-10, 1,0,0, 76 Vertices[1] = video::S3DVertex(10,0,-10, 1,0,0,
77 video::SColor(255,255,0,255), 1, 1); 77 video::SColor(255,255,0,255), 1, 1);
78 Vertices[2] = video::S3DVertex(0,20,0, 0,1,1, 78 Vertices[2] = video::S3DVertex(0,20,0, 0,1,1,
79 video::SColor(255,255,255,0), 1, 0); 79 video::SColor(255,255,255,0), 1, 0);
80 Vertices[3] = video::S3DVertex(-10,0,-10, 0,0,1, 80 Vertices[3] = video::S3DVertex(-10,0,-10, 0,0,1,
81 video::SColor(255,0,255,0), 0, 0); 81 video::SColor(255,0,255,0), 0, 0);
82 82
83 /* 83 /*
84 The Irrlicht Engine needs to know the bounding box of a scene node. 84 The Irrlicht Engine needs to know the bounding box of a scene node.
85 It will use it for automatic culling and other things. Hence, we 85 It will use it for automatic culling and other things. Hence, we
86 need to create a bounding box from the 4 vertices we use. 86 need to create a bounding box from the 4 vertices we use.
87 If you do not want the engine to use the box for automatic culling, 87 If you do not want the engine to use the box for automatic culling,
88 and/or don't want to create the box, you could also call 88 and/or don't want to create the box, you could also call
89 irr::scene::ISceneNode::setAutomaticCulling() with irr::scene::EAC_OFF. 89 irr::scene::ISceneNode::setAutomaticCulling() with irr::scene::EAC_OFF.
90 */ 90 */
91 Box.reset(Vertices[0].Pos); 91 Box.reset(Vertices[0].Pos);
92 for (s32 i=1; i<4; ++i) 92 for (s32 i=1; i<4; ++i)
93 Box.addInternalPoint(Vertices[i].Pos); 93 Box.addInternalPoint(Vertices[i].Pos);
94 } 94 }
95 95
96 /* 96 /*
97 Before it is drawn, the irr::scene::ISceneNode::OnRegisterSceneNode() 97 Before it is drawn, the irr::scene::ISceneNode::OnRegisterSceneNode()
98 method of every scene node in the scene is called by the scene manager. 98 method of every scene node in the scene is called by the scene manager.
99 If the scene node wishes to draw itself, it may register itself in the 99 If the scene node wishes to draw itself, it may register itself in the
100 scene manager to be drawn. This is necessary to tell the scene manager 100 scene manager to be drawn. This is necessary to tell the scene manager
101 when it should call irr::scene::ISceneNode::render(). For 101 when it should call irr::scene::ISceneNode::render(). For
102 example, normal scene nodes render their content one after another, 102 example, normal scene nodes render their content one after another,
103 while stencil buffer shadows would like to be drawn after all other 103 while stencil buffer shadows would like to be drawn after all other
104 scene nodes. And camera or light scene nodes need to be rendered before 104 scene nodes. And camera or light scene nodes need to be rendered before
105 all other scene nodes (if at all). So here we simply register the 105 all other scene nodes (if at all). So here we simply register the
106 scene node to render normally. If we would like to let it be rendered 106 scene node to render normally. If we would like to let it be rendered
107 like cameras or light, we would have to call 107 like cameras or light, we would have to call
108 SceneManager->registerNodeForRendering(this, SNRT_LIGHT_AND_CAMERA); 108 SceneManager->registerNodeForRendering(this, SNRT_LIGHT_AND_CAMERA);
109 After this, we call the actual 109 After this, we call the actual
110 irr::scene::ISceneNode::OnRegisterSceneNode() method of the base class, 110 irr::scene::ISceneNode::OnRegisterSceneNode() method of the base class,
111 which simply lets also all the child scene nodes of this node register 111 which simply lets also all the child scene nodes of this node register
112 themselves. 112 themselves.
113 */ 113 */
114 virtual void OnRegisterSceneNode() 114 virtual void OnRegisterSceneNode()
115 { 115 {
116 if (IsVisible) 116 if (IsVisible)
117 SceneManager->registerNodeForRendering(this); 117 SceneManager->registerNodeForRendering(this);
118 118
119 ISceneNode::OnRegisterSceneNode(); 119 ISceneNode::OnRegisterSceneNode();
120 } 120 }
121 121
122 /* 122 /*
123 In the render() method most of the interesting stuff happens: The 123 In the render() method most of the interesting stuff happens: The
124 Scene node renders itself. We override this method and draw the 124 Scene node renders itself. We override this method and draw the
125 tetraeder. 125 tetraeder.
126 */ 126 */
127 virtual void render() 127 virtual void render()
128 { 128 {
129 u16 indices[] = { 0,2,3, 2,1,3, 1,0,3, 2,0,1 }; 129 u16 indices[] = { 0,2,3, 2,1,3, 1,0,3, 2,0,1 };
130 video::IVideoDriver* driver = SceneManager->getVideoDriver(); 130 video::IVideoDriver* driver = SceneManager->getVideoDriver();
131 131
132 driver->setMaterial(Material); 132 driver->setMaterial(Material);
133 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); 133 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
134 driver->drawVertexPrimitiveList(&Vertices[0], 4, &indices[0], 4, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); 134 driver->drawVertexPrimitiveList(&Vertices[0], 4, &indices[0], 4, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
135 } 135 }
136 136
137 /* 137 /*
138 And finally we create three small additional methods. 138 And finally we create three small additional methods.
139 irr::scene::ISceneNode::getBoundingBox() returns the bounding box of 139 irr::scene::ISceneNode::getBoundingBox() returns the bounding box of
140 this scene node, irr::scene::ISceneNode::getMaterialCount() returns the 140 this scene node, irr::scene::ISceneNode::getMaterialCount() returns the
141 amount of materials in this scene node (our tetraeder only has one 141 amount of materials in this scene node (our tetraeder only has one
142 material), and irr::scene::ISceneNode::getMaterial() returns the 142 material), and irr::scene::ISceneNode::getMaterial() returns the
143 material at an index. Because we have only one material here, we can 143 material at an index. Because we have only one material here, we can
144 return the only one material, assuming that no one ever calls 144 return the only one material, assuming that no one ever calls
145 getMaterial() with an index greater than 0. 145 getMaterial() with an index greater than 0.
146 */ 146 */
147 virtual const core::aabbox3d<f32>& getBoundingBox() const 147 virtual const core::aabbox3d<f32>& getBoundingBox() const
148 { 148 {
149 return Box; 149 return Box;
150 } 150 }
151 151
152 virtual u32 getMaterialCount() const 152 virtual u32 getMaterialCount() const
153 { 153 {
154 return 1; 154 return 1;
155 } 155 }
156 156
157 virtual video::SMaterial& getMaterial(u32 i) 157 virtual video::SMaterial& getMaterial(u32 i)
158 { 158 {
159 return Material; 159 return Material;
160 } 160 }
161}; 161};
162 162
163/* 163/*
164That's it. The Scene node is done. Now we simply have to start 164That's it. The Scene node is done. Now we simply have to start
165the engine, create the scene node and a camera, and look at the result. 165the engine, create the scene node and a camera, and look at the result.
166*/ 166*/
167int main() 167int main()
168{ 168{
169 // ask user for driver 169 // ask user for driver
170 video::E_DRIVER_TYPE driverType=driverChoiceConsole(); 170 video::E_DRIVER_TYPE driverType=driverChoiceConsole();
171 if (driverType==video::EDT_COUNT) 171 if (driverType==video::EDT_COUNT)
172 return 1; 172 return 1;
173 173
174 // create device 174 // create device
175 175
176 IrrlichtDevice *device = createDevice(driverType, 176 IrrlichtDevice *device = createDevice(driverType,
177 core::dimension2d<u32>(640, 480), 16, false); 177 core::dimension2d<u32>(640, 480), 16, false);
178 178
179 if (device == 0) 179 if (device == 0)
180 return 1; // could not create selected driver. 180 return 1; // could not create selected driver.
181 181
182 // create engine and camera 182 // create engine and camera
183 183
184 device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo"); 184 device->setWindowCaption(L"Custom Scene Node - Irrlicht Engine Demo");
185 185
186 video::IVideoDriver* driver = device->getVideoDriver(); 186 video::IVideoDriver* driver = device->getVideoDriver();
187 scene::ISceneManager* smgr = device->getSceneManager(); 187 scene::ISceneManager* smgr = device->getSceneManager();
188 188
189 smgr->addCameraSceneNode(0, core::vector3df(0,-40,0), core::vector3df(0,0,0)); 189 smgr->addCameraSceneNode(0, core::vector3df(0,-40,0), core::vector3df(0,0,0));
190 190
191 /* 191 /*
192 Create our scene node. I don't check the result of calling new, as it 192 Create our scene node. I don't check the result of calling new, as it
193 should throw an exception rather than returning 0 on failure. Because 193 should throw an exception rather than returning 0 on failure. Because
194 the new node will create itself with a reference count of 1, and then 194 the new node will create itself with a reference count of 1, and then
195 will have another reference added by its parent scene node when it is 195 will have another reference added by its parent scene node when it is
196 added to the scene, I need to drop my reference to it. Best practice is 196 added to the scene, I need to drop my reference to it. Best practice is
197 to drop it only *after* I have finished using it, regardless of what 197 to drop it only *after* I have finished using it, regardless of what
198 the reference count of the object is after creation. 198 the reference count of the object is after creation.
199 */ 199 */
200 CSampleSceneNode *myNode = 200 CSampleSceneNode *myNode =
201 new CSampleSceneNode(smgr->getRootSceneNode(), smgr, 666); 201 new CSampleSceneNode(smgr->getRootSceneNode(), smgr, 666);
202 202
203 /* 203 /*
204 To animate something in this boring scene consisting only of one 204 To animate something in this boring scene consisting only of one
205 tetraeder, and to show that you now can use your scene node like any 205 tetraeder, and to show that you now can use your scene node like any
206 other scene node in the engine, we add an animator to the scene node, 206 other scene node in the engine, we add an animator to the scene node,
207 which rotates the node a little bit. 207 which rotates the node a little bit.
208 irr::scene::ISceneManager::createRotationAnimator() could return 0, so 208 irr::scene::ISceneManager::createRotationAnimator() could return 0, so
209 should be checked. 209 should be checked.
210 */ 210 */
211 scene::ISceneNodeAnimator* anim = 211 scene::ISceneNodeAnimator* anim =
212 smgr->createRotationAnimator(core::vector3df(0.8f, 0, 0.8f)); 212 smgr->createRotationAnimator(core::vector3df(0.8f, 0, 0.8f));
213 213
214 if(anim) 214 if(anim)
215 { 215 {
216 myNode->addAnimator(anim); 216 myNode->addAnimator(anim);
217 217
218 /* 218 /*
219 I'm done referring to anim, so must 219 I'm done referring to anim, so must
220 irr::IReferenceCounted::drop() this reference now because it 220 irr::IReferenceCounted::drop() this reference now because it
221 was produced by a createFoo() function. As I shouldn't refer to 221 was produced by a createFoo() function. As I shouldn't refer to
222 it again, ensure that I can't by setting to 0. 222 it again, ensure that I can't by setting to 0.
223 */ 223 */
224 anim->drop(); 224 anim->drop();
225 anim = 0; 225 anim = 0;
226 } 226 }
227 227
228 /* 228 /*
229 I'm done with my CSampleSceneNode object, and so must drop my reference. 229 I'm done with my CSampleSceneNode object, and so must drop my reference.
230 This won't delete the object, yet, because it is still attached to the 230 This won't delete the object, yet, because it is still attached to the
231 scene graph, which prevents the deletion until the graph is deleted or the 231 scene graph, which prevents the deletion until the graph is deleted or the
232 custom scene node is removed from it. 232 custom scene node is removed from it.
233 */ 233 */
234 myNode->drop(); 234 myNode->drop();
235 myNode = 0; // As I shouldn't refer to it again, ensure that I can't 235 myNode = 0; // As I shouldn't refer to it again, ensure that I can't
236 236
237 /* 237 /*
238 Now draw everything and finish. 238 Now draw everything and finish.
239 */ 239 */
240 u32 frames=0; 240 u32 frames=0;
241 while(device->run()) 241 while(device->run())
242 { 242 {
243 driver->beginScene(true, true, video::SColor(0,100,100,100)); 243 driver->beginScene(true, true, video::SColor(0,100,100,100));
244 244
245 smgr->drawAll(); 245 smgr->drawAll();
246 246
247 driver->endScene(); 247 driver->endScene();
248 if (++frames==100) 248 if (++frames==100)
249 { 249 {
250 core::stringw str = L"Irrlicht Engine ["; 250 core::stringw str = L"Irrlicht Engine [";
251 str += driver->getName(); 251 str += driver->getName();
252 str += L"] FPS: "; 252 str += L"] FPS: ";
253 str += (s32)driver->getFPS(); 253 str += (s32)driver->getFPS();
254 254
255 device->setWindowCaption(str.c_str()); 255 device->setWindowCaption(str.c_str());
256 frames=0; 256 frames=0;
257 } 257 }
258 } 258 }
259 259
260 device->drop(); 260 device->drop();
261 261
262 return 0; 262 return 0;
263} 263}
264 264
265/* 265/*
266That's it. Compile and play around with the program. 266That's it. Compile and play around with the program.
267**/ 267**/