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