aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/examples/16.Quake3MapShader/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/irrlicht-1.8/examples/16.Quake3MapShader/main.cpp776
1 files changed, 388 insertions, 388 deletions
diff --git a/libraries/irrlicht-1.8/examples/16.Quake3MapShader/main.cpp b/libraries/irrlicht-1.8/examples/16.Quake3MapShader/main.cpp
index 1e5d55e..bd11c95 100644
--- a/libraries/irrlicht-1.8/examples/16.Quake3MapShader/main.cpp
+++ b/libraries/irrlicht-1.8/examples/16.Quake3MapShader/main.cpp
@@ -1,388 +1,388 @@
1/** Example 016 Quake3 Map Shader Support 1/** Example 016 Quake3 Map Shader Support
2 2
3This Tutorial shows how to load a Quake 3 map into the 3This Tutorial shows how to load a Quake 3 map into the
4engine, create a SceneNode for optimizing the speed of 4engine, create a SceneNode for optimizing the speed of
5rendering and how to create a user controlled camera. 5rendering and how to create a user controlled camera.
6 6
7Lets start like the HelloWorld example: We include 7Lets start like the HelloWorld example: We include
8the irrlicht header files and an additional file to be able 8the irrlicht header files and an additional file to be able
9to ask the user for a driver type using the console. 9to ask the user for a driver type using the console.
10*/ 10*/
11#include <irrlicht.h> 11#include <irrlicht.h>
12#include "driverChoice.h" 12#include "driverChoice.h"
13 13
14/* 14/*
15 define which Quake3 Level should be loaded 15 define which Quake3 Level should be loaded
16*/ 16*/
17#define IRRLICHT_QUAKE3_ARENA 17#define IRRLICHT_QUAKE3_ARENA
18//#define ORIGINAL_QUAKE3_ARENA 18//#define ORIGINAL_QUAKE3_ARENA
19//#define CUSTOM_QUAKE3_ARENA 19//#define CUSTOM_QUAKE3_ARENA
20//#define SHOW_SHADER_NAME 20//#define SHOW_SHADER_NAME
21 21
22#ifdef ORIGINAL_QUAKE3_ARENA 22#ifdef ORIGINAL_QUAKE3_ARENA
23 #define QUAKE3_STORAGE_FORMAT addFolderFileArchive 23 #define QUAKE3_STORAGE_FORMAT addFolderFileArchive
24 #define QUAKE3_STORAGE_1 "/baseq3/" 24 #define QUAKE3_STORAGE_1 "/baseq3/"
25 #ifdef CUSTOM_QUAKE3_ARENA 25 #ifdef CUSTOM_QUAKE3_ARENA
26 #define QUAKE3_STORAGE_2 "/cf/" 26 #define QUAKE3_STORAGE_2 "/cf/"
27 #define QUAKE3_MAP_NAME "maps/cf.bsp" 27 #define QUAKE3_MAP_NAME "maps/cf.bsp"
28 #else 28 #else
29 #define QUAKE3_MAP_NAME "maps/q3dm8.bsp" 29 #define QUAKE3_MAP_NAME "maps/q3dm8.bsp"
30 #endif 30 #endif
31#endif 31#endif
32 32
33#ifdef IRRLICHT_QUAKE3_ARENA 33#ifdef IRRLICHT_QUAKE3_ARENA
34 #define QUAKE3_STORAGE_FORMAT addFileArchive 34 #define QUAKE3_STORAGE_FORMAT addFileArchive
35 #define QUAKE3_STORAGE_1 "../../media/map-20kdm2.pk3" 35 #define QUAKE3_STORAGE_1 "../../media/map-20kdm2.pk3"
36 #define QUAKE3_MAP_NAME "maps/20kdm2.bsp" 36 #define QUAKE3_MAP_NAME "maps/20kdm2.bsp"
37#endif 37#endif
38 38
39using namespace irr; 39using namespace irr;
40using namespace scene; 40using namespace scene;
41 41
42/* 42/*
43Again, to be able to use the Irrlicht.DLL file, we need to link with the 43Again, to be able to use the Irrlicht.DLL file, we need to link with the
44Irrlicht.lib. We could set this option in the project settings, but 44Irrlicht.lib. We could set this option in the project settings, but
45to make it easy, we use a pragma comment lib: 45to make it easy, we use a pragma comment lib:
46*/ 46*/
47#ifdef _MSC_VER 47#ifdef _MSC_VER
48#pragma comment(lib, "Irrlicht.lib") 48#pragma comment(lib, "Irrlicht.lib")
49#endif 49#endif
50 50
51 51
52/* 52/*
53A class to produce a series of screenshots 53A class to produce a series of screenshots
54*/ 54*/
55class CScreenShotFactory : public IEventReceiver 55class CScreenShotFactory : public IEventReceiver
56{ 56{
57public: 57public:
58 58
59 CScreenShotFactory( IrrlichtDevice *device, const c8 * templateName, ISceneNode* node ) 59 CScreenShotFactory( IrrlichtDevice *device, const c8 * templateName, ISceneNode* node )
60 : Device(device), Number(0), FilenameTemplate(templateName), Node(node) 60 : Device(device), Number(0), FilenameTemplate(templateName), Node(node)
61 { 61 {
62 FilenameTemplate.replace ( '/', '_' ); 62 FilenameTemplate.replace ( '/', '_' );
63 FilenameTemplate.replace ( '\\', '_' ); 63 FilenameTemplate.replace ( '\\', '_' );
64 } 64 }
65 65
66 bool OnEvent(const SEvent& event) 66 bool OnEvent(const SEvent& event)
67 { 67 {
68 // check if user presses the key F9 68 // check if user presses the key F9
69 if ((event.EventType == EET_KEY_INPUT_EVENT) && 69 if ((event.EventType == EET_KEY_INPUT_EVENT) &&
70 event.KeyInput.PressedDown) 70 event.KeyInput.PressedDown)
71 { 71 {
72 if (event.KeyInput.Key == KEY_F9) 72 if (event.KeyInput.Key == KEY_F9)
73 { 73 {
74 video::IImage* image = Device->getVideoDriver()->createScreenShot(); 74 video::IImage* image = Device->getVideoDriver()->createScreenShot();
75 if (image) 75 if (image)
76 { 76 {
77 c8 buf[256]; 77 c8 buf[256];
78 snprintf(buf, 256, "%s_shot%04d.jpg", 78 snprintf(buf, 256, "%s_shot%04d.jpg",
79 FilenameTemplate.c_str(), 79 FilenameTemplate.c_str(),
80 ++Number); 80 ++Number);
81 Device->getVideoDriver()->writeImageToFile(image, buf, 85 ); 81 Device->getVideoDriver()->writeImageToFile(image, buf, 85 );
82 image->drop(); 82 image->drop();
83 } 83 }
84 } 84 }
85 else 85 else
86 if (event.KeyInput.Key == KEY_F8) 86 if (event.KeyInput.Key == KEY_F8)
87 { 87 {
88 if (Node->isDebugDataVisible()) 88 if (Node->isDebugDataVisible())
89 Node->setDebugDataVisible(scene::EDS_OFF); 89 Node->setDebugDataVisible(scene::EDS_OFF);
90 else 90 else
91 Node->setDebugDataVisible(scene::EDS_BBOX_ALL); 91 Node->setDebugDataVisible(scene::EDS_BBOX_ALL);
92 } 92 }
93 } 93 }
94 return false; 94 return false;
95 } 95 }
96 96
97private: 97private:
98 IrrlichtDevice *Device; 98 IrrlichtDevice *Device;
99 u32 Number; 99 u32 Number;
100 core::stringc FilenameTemplate; 100 core::stringc FilenameTemplate;
101 ISceneNode* Node; 101 ISceneNode* Node;
102}; 102};
103 103
104 104
105/* 105/*
106Ok, lets start. 106Ok, lets start.
107*/ 107*/
108 108
109int IRRCALLCONV main(int argc, char* argv[]) 109int IRRCALLCONV main(int argc, char* argv[])
110{ 110{
111 /* 111 /*
112 Like in the HelloWorld example, we create an IrrlichtDevice with 112 Like in the HelloWorld example, we create an IrrlichtDevice with
113 createDevice(). The difference now is that we ask the user to select 113 createDevice(). The difference now is that we ask the user to select
114 which hardware accelerated driver to use. The Software device would be 114 which hardware accelerated driver to use. The Software device would be
115 too slow to draw a huge Quake 3 map, but just for the fun of it, we make 115 too slow to draw a huge Quake 3 map, but just for the fun of it, we make
116 this decision possible too. 116 this decision possible too.
117 */ 117 */
118 118
119 // ask user for driver 119 // ask user for driver
120 video::E_DRIVER_TYPE driverType=driverChoiceConsole(); 120 video::E_DRIVER_TYPE driverType=driverChoiceConsole();
121 if (driverType==video::EDT_COUNT) 121 if (driverType==video::EDT_COUNT)
122 return 1; 122 return 1;
123 123
124 // create device and exit if creation failed 124 // create device and exit if creation failed
125 const core::dimension2du videoDim(800,600); 125 const core::dimension2du videoDim(800,600);
126 126
127 IrrlichtDevice *device = createDevice(driverType, videoDim, 32, false ); 127 IrrlichtDevice *device = createDevice(driverType, videoDim, 32, false );
128 128
129 if (device == 0) 129 if (device == 0)
130 return 1; // could not create selected driver. 130 return 1; // could not create selected driver.
131 131
132 const char* mapname=0; 132 const char* mapname=0;
133 if (argc>2) 133 if (argc>2)
134 mapname = argv[2]; 134 mapname = argv[2];
135 else 135 else
136 mapname = QUAKE3_MAP_NAME; 136 mapname = QUAKE3_MAP_NAME;
137 137
138 /* 138 /*
139 Get a pointer to the video driver and the SceneManager so that 139 Get a pointer to the video driver and the SceneManager so that
140 we do not always have to write device->getVideoDriver() and 140 we do not always have to write device->getVideoDriver() and
141 device->getSceneManager(). 141 device->getSceneManager().
142 */ 142 */
143 video::IVideoDriver* driver = device->getVideoDriver(); 143 video::IVideoDriver* driver = device->getVideoDriver();
144 scene::ISceneManager* smgr = device->getSceneManager(); 144 scene::ISceneManager* smgr = device->getSceneManager();
145 gui::IGUIEnvironment* gui = device->getGUIEnvironment(); 145 gui::IGUIEnvironment* gui = device->getGUIEnvironment();
146 146
147 //! add our private media directory to the file system 147 //! add our private media directory to the file system
148 device->getFileSystem()->addFileArchive("../../media/"); 148 device->getFileSystem()->addFileArchive("../../media/");
149 149
150 /* 150 /*
151 To display the Quake 3 map, we first need to load it. Quake 3 maps 151 To display the Quake 3 map, we first need to load it. Quake 3 maps
152 are packed into .pk3 files, which are nothing other than .zip files. 152 are packed into .pk3 files, which are nothing other than .zip files.
153 So we add the .pk3 file to our FileSystem. After it was added, 153 So we add the .pk3 file to our FileSystem. After it was added,
154 we are able to read from the files in that archive as they would 154 we are able to read from the files in that archive as they would
155 directly be stored on disk. 155 directly be stored on disk.
156 */ 156 */
157 if (argc>2) 157 if (argc>2)
158 device->getFileSystem()->QUAKE3_STORAGE_FORMAT(argv[1]); 158 device->getFileSystem()->QUAKE3_STORAGE_FORMAT(argv[1]);
159 else 159 else
160 device->getFileSystem()->QUAKE3_STORAGE_FORMAT(QUAKE3_STORAGE_1); 160 device->getFileSystem()->QUAKE3_STORAGE_FORMAT(QUAKE3_STORAGE_1);
161#ifdef QUAKE3_STORAGE_2 161#ifdef QUAKE3_STORAGE_2
162 device->getFileSystem()->QUAKE3_STORAGE_FORMAT(QUAKE3_STORAGE_2); 162 device->getFileSystem()->QUAKE3_STORAGE_FORMAT(QUAKE3_STORAGE_2);
163#endif 163#endif
164 164
165 // Quake3 Shader controls Z-Writing 165 // Quake3 Shader controls Z-Writing
166 smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true); 166 smgr->getParameters()->setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
167 167
168 /* 168 /*
169 Now we can load the mesh by calling getMesh(). We get a pointer returned 169 Now we can load the mesh by calling getMesh(). We get a pointer returned
170 to a IAnimatedMesh. As you know, Quake 3 maps are not really animated, 170 to a IAnimatedMesh. As you know, Quake 3 maps are not really animated,
171 they are only a huge chunk of static geometry with some materials 171 they are only a huge chunk of static geometry with some materials
172 attached. Hence the IAnimated mesh consists of only one frame, 172 attached. Hence the IAnimated mesh consists of only one frame,
173 so we get the "first frame" of the "animation", which is our quake level 173 so we get the "first frame" of the "animation", which is our quake level
174 and create an Octree scene node with it, using addOctreeSceneNode(). 174 and create an Octree scene node with it, using addOctreeSceneNode().
175 The Octree optimizes the scene a little bit, trying to draw only geometry 175 The Octree optimizes the scene a little bit, trying to draw only geometry
176 which is currently visible. An alternative to the Octree would be a 176 which is currently visible. An alternative to the Octree would be a
177 AnimatedMeshSceneNode, which would draw always the complete geometry of 177 AnimatedMeshSceneNode, which would draw always the complete geometry of
178 the mesh, without optimization. Try it out: Write addAnimatedMeshSceneNode 178 the mesh, without optimization. Try it out: Write addAnimatedMeshSceneNode
179 instead of addOctreeSceneNode and compare the primitives drawn by the 179 instead of addOctreeSceneNode and compare the primitives drawn by the
180 video driver. (There is a getPrimitiveCountDrawed() method in the 180 video driver. (There is a getPrimitiveCountDrawed() method in the
181 IVideoDriver class). Note that this optimization with the Octree is only 181 IVideoDriver class). Note that this optimization with the Octree is only
182 useful when drawing huge meshes consisting of lots of geometry. 182 useful when drawing huge meshes consisting of lots of geometry.
183 */ 183 */
184 scene::IQ3LevelMesh* const mesh = 184 scene::IQ3LevelMesh* const mesh =
185 (scene::IQ3LevelMesh*) smgr->getMesh(mapname); 185 (scene::IQ3LevelMesh*) smgr->getMesh(mapname);
186 186
187 /* 187 /*
188 add the geometry mesh to the Scene ( polygon & patches ) 188 add the geometry mesh to the Scene ( polygon & patches )
189 The Geometry mesh is optimised for faster drawing 189 The Geometry mesh is optimised for faster drawing
190 */ 190 */
191 scene::ISceneNode* node = 0; 191 scene::ISceneNode* node = 0;
192 if (mesh) 192 if (mesh)
193 { 193 {
194 scene::IMesh * const geometry = mesh->getMesh(quake3::E_Q3_MESH_GEOMETRY); 194 scene::IMesh * const geometry = mesh->getMesh(quake3::E_Q3_MESH_GEOMETRY);
195 node = smgr->addOctreeSceneNode(geometry, 0, -1, 4096); 195 node = smgr->addOctreeSceneNode(geometry, 0, -1, 4096);
196 } 196 }
197 197
198 // create an event receiver for making screenshots 198 // create an event receiver for making screenshots
199 CScreenShotFactory screenshotFactory(device, mapname, node); 199 CScreenShotFactory screenshotFactory(device, mapname, node);
200 device->setEventReceiver(&screenshotFactory); 200 device->setEventReceiver(&screenshotFactory);
201 201
202 /* 202 /*
203 now construct SceneNodes for each Shader 203 now construct SceneNodes for each Shader
204 The Objects are stored in the quake mesh scene::E_Q3_MESH_ITEMS 204 The Objects are stored in the quake mesh scene::E_Q3_MESH_ITEMS
205 and the Shader ID is stored in the MaterialParameters 205 and the Shader ID is stored in the MaterialParameters
206 mostly dark looking skulls and moving lava.. or green flashing tubes? 206 mostly dark looking skulls and moving lava.. or green flashing tubes?
207 */ 207 */
208 if ( mesh ) 208 if ( mesh )
209 { 209 {
210 // the additional mesh can be quite huge and is unoptimized 210 // the additional mesh can be quite huge and is unoptimized
211 const scene::IMesh * const additional_mesh = mesh->getMesh(quake3::E_Q3_MESH_ITEMS); 211 const scene::IMesh * const additional_mesh = mesh->getMesh(quake3::E_Q3_MESH_ITEMS);
212 212
213#ifdef SHOW_SHADER_NAME 213#ifdef SHOW_SHADER_NAME
214 gui::IGUIFont *font = device->getGUIEnvironment()->getFont("../../media/fontlucida.png"); 214 gui::IGUIFont *font = device->getGUIEnvironment()->getFont("../../media/fontlucida.png");
215 u32 count = 0; 215 u32 count = 0;
216#endif 216#endif
217 217
218 for ( u32 i = 0; i!= additional_mesh->getMeshBufferCount(); ++i ) 218 for ( u32 i = 0; i!= additional_mesh->getMeshBufferCount(); ++i )
219 { 219 {
220 const IMeshBuffer* meshBuffer = additional_mesh->getMeshBuffer(i); 220 const IMeshBuffer* meshBuffer = additional_mesh->getMeshBuffer(i);
221 const video::SMaterial& material = meshBuffer->getMaterial(); 221 const video::SMaterial& material = meshBuffer->getMaterial();
222 222
223 // The ShaderIndex is stored in the material parameter 223 // The ShaderIndex is stored in the material parameter
224 const s32 shaderIndex = (s32) material.MaterialTypeParam2; 224 const s32 shaderIndex = (s32) material.MaterialTypeParam2;
225 225
226 // the meshbuffer can be rendered without additional support, or it has no shader 226 // the meshbuffer can be rendered without additional support, or it has no shader
227 const quake3::IShader *shader = mesh->getShader(shaderIndex); 227 const quake3::IShader *shader = mesh->getShader(shaderIndex);
228 if (0 == shader) 228 if (0 == shader)
229 { 229 {
230 continue; 230 continue;
231 } 231 }
232 232
233 // we can dump the shader to the console in its 233 // we can dump the shader to the console in its
234 // original but already parsed layout in a pretty 234 // original but already parsed layout in a pretty
235 // printers way.. commented out, because the console 235 // printers way.. commented out, because the console
236 // would be full... 236 // would be full...
237 // quake3::dumpShader ( Shader ); 237 // quake3::dumpShader ( Shader );
238 238
239 node = smgr->addQuake3SceneNode(meshBuffer, shader); 239 node = smgr->addQuake3SceneNode(meshBuffer, shader);
240 240
241#ifdef SHOW_SHADER_NAME 241#ifdef SHOW_SHADER_NAME
242 count += 1; 242 count += 1;
243 core::stringw name( node->getName() ); 243 core::stringw name( node->getName() );
244 node = smgr->addBillboardTextSceneNode( 244 node = smgr->addBillboardTextSceneNode(
245 font, name.c_str(), node, 245 font, name.c_str(), node,
246 core::dimension2d<f32>(80.0f, 8.0f), 246 core::dimension2d<f32>(80.0f, 8.0f),
247 core::vector3df(0, 10, 0)); 247 core::vector3df(0, 10, 0));
248#endif 248#endif
249 } 249 }
250 } 250 }
251 251
252 /* 252 /*
253 Now we only need a Camera to look at the Quake 3 map. And we want to 253 Now we only need a Camera to look at the Quake 3 map. And we want to
254 create a user controlled camera. There are some different cameras 254 create a user controlled camera. There are some different cameras
255 available in the Irrlicht engine. For example the Maya Camera which can 255 available in the Irrlicht engine. For example the Maya Camera which can
256 be controlled comparable to the camera in Maya: Rotate with left mouse 256 be controlled comparable to the camera in Maya: Rotate with left mouse
257 button pressed, Zoom with both buttons pressed, translate with right 257 button pressed, Zoom with both buttons pressed, translate with right
258 mouse button pressed. This could be created with 258 mouse button pressed. This could be created with
259 addCameraSceneNodeMaya(). But for this example, we want to create a 259 addCameraSceneNodeMaya(). But for this example, we want to create a
260 camera which behaves like the ones in first person shooter games (FPS). 260 camera which behaves like the ones in first person shooter games (FPS).
261 */ 261 */
262 262
263 scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(); 263 scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS();
264 264
265 /* 265 /*
266 so we need a good starting Position in the level. 266 so we need a good starting Position in the level.
267 we can ask the Quake3 Loader for all entities with class_name 267 we can ask the Quake3 Loader for all entities with class_name
268 "info_player_deathmatch" 268 "info_player_deathmatch"
269 we choose a random launch 269 we choose a random launch
270 */ 270 */
271 if ( mesh ) 271 if ( mesh )
272 { 272 {
273 quake3::tQ3EntityList &entityList = mesh->getEntityList(); 273 quake3::tQ3EntityList &entityList = mesh->getEntityList();
274 274
275 quake3::IEntity search; 275 quake3::IEntity search;
276 search.name = "info_player_deathmatch"; 276 search.name = "info_player_deathmatch";
277 277
278 s32 index = entityList.binary_search(search); 278 s32 index = entityList.binary_search(search);
279 if (index >= 0) 279 if (index >= 0)
280 { 280 {
281 s32 notEndList; 281 s32 notEndList;
282 do 282 do
283 { 283 {
284 const quake3::SVarGroup *group = entityList[index].getGroup(1); 284 const quake3::SVarGroup *group = entityList[index].getGroup(1);
285 285
286 u32 parsepos = 0; 286 u32 parsepos = 0;
287 const core::vector3df pos = 287 const core::vector3df pos =
288 quake3::getAsVector3df(group->get("origin"), parsepos); 288 quake3::getAsVector3df(group->get("origin"), parsepos);
289 289
290 parsepos = 0; 290 parsepos = 0;
291 const f32 angle = quake3::getAsFloat(group->get("angle"), parsepos); 291 const f32 angle = quake3::getAsFloat(group->get("angle"), parsepos);
292 292
293 core::vector3df target(0.f, 0.f, 1.f); 293 core::vector3df target(0.f, 0.f, 1.f);
294 target.rotateXZBy(angle); 294 target.rotateXZBy(angle);
295 295
296 camera->setPosition(pos); 296 camera->setPosition(pos);
297 camera->setTarget(pos + target); 297 camera->setTarget(pos + target);
298 298
299 ++index; 299 ++index;
300/* 300/*
301 notEndList = ( index < (s32) entityList.size () && 301 notEndList = ( index < (s32) entityList.size () &&
302 entityList[index].name == search.name && 302 entityList[index].name == search.name &&
303 (device->getTimer()->getRealTime() >> 3 ) & 1 303 (device->getTimer()->getRealTime() >> 3 ) & 1
304 ); 304 );
305*/ 305*/
306 notEndList = index == 2; 306 notEndList = index == 2;
307 } while ( notEndList ); 307 } while ( notEndList );
308 } 308 }
309 } 309 }
310 310
311 /* 311 /*
312 The mouse cursor needs not to be visible, so we make it invisible. 312 The mouse cursor needs not to be visible, so we make it invisible.
313 */ 313 */
314 314
315 device->getCursorControl()->setVisible(false); 315 device->getCursorControl()->setVisible(false);
316 316
317 // load the engine logo 317 // load the engine logo
318 gui->addImage(driver->getTexture("irrlichtlogo2.png"), 318 gui->addImage(driver->getTexture("irrlichtlogo2.png"),
319 core::position2d<s32>(10, 10)); 319 core::position2d<s32>(10, 10));
320 320
321 // show the driver logo 321 // show the driver logo
322 const core::position2di pos(videoDim.Width - 128, videoDim.Height - 64); 322 const core::position2di pos(videoDim.Width - 128, videoDim.Height - 64);
323 323
324 switch ( driverType ) 324 switch ( driverType )
325 { 325 {
326 case video::EDT_BURNINGSVIDEO: 326 case video::EDT_BURNINGSVIDEO:
327 gui->addImage(driver->getTexture("burninglogo.png"), pos); 327 gui->addImage(driver->getTexture("burninglogo.png"), pos);
328 break; 328 break;
329 case video::EDT_OPENGL: 329 case video::EDT_OPENGL:
330 gui->addImage(driver->getTexture("opengllogo.png"), pos); 330 gui->addImage(driver->getTexture("opengllogo.png"), pos);
331 break; 331 break;
332 case video::EDT_DIRECT3D8: 332 case video::EDT_DIRECT3D8:
333 case video::EDT_DIRECT3D9: 333 case video::EDT_DIRECT3D9:
334 gui->addImage(driver->getTexture("directxlogo.png"), pos); 334 gui->addImage(driver->getTexture("directxlogo.png"), pos);
335 break; 335 break;
336 } 336 }
337 337
338 /* 338 /*
339 We have done everything, so lets draw it. We also write the current 339 We have done everything, so lets draw it. We also write the current
340 frames per second and the drawn primitives to the caption of the 340 frames per second and the drawn primitives to the caption of the
341 window. The 'if (device->isWindowActive())' line is optional, but 341 window. The 'if (device->isWindowActive())' line is optional, but
342 prevents the engine render to set the position of the mouse cursor 342 prevents the engine render to set the position of the mouse cursor
343 after task switching when other program are active. 343 after task switching when other program are active.
344 */ 344 */
345 int lastFPS = -1; 345 int lastFPS = -1;
346 346
347 while(device->run()) 347 while(device->run())
348 if (device->isWindowActive()) 348 if (device->isWindowActive())
349 { 349 {
350 driver->beginScene(true, true, video::SColor(255,20,20,40)); 350 driver->beginScene(true, true, video::SColor(255,20,20,40));
351 smgr->drawAll(); 351 smgr->drawAll();
352 gui->drawAll(); 352 gui->drawAll();
353 driver->endScene(); 353 driver->endScene();
354 354
355 int fps = driver->getFPS(); 355 int fps = driver->getFPS();
356 //if (lastFPS != fps) 356 //if (lastFPS != fps)
357 { 357 {
358 io::IAttributes * const attr = smgr->getParameters(); 358 io::IAttributes * const attr = smgr->getParameters();
359 core::stringw str = L"Q3 ["; 359 core::stringw str = L"Q3 [";
360 str += driver->getName(); 360 str += driver->getName();
361 str += "] FPS:"; 361 str += "] FPS:";
362 str += fps; 362 str += fps;
363 str += " Cull:"; 363 str += " Cull:";
364 str += attr->getAttributeAsInt("calls"); 364 str += attr->getAttributeAsInt("calls");
365 str += "/"; 365 str += "/";
366 str += attr->getAttributeAsInt("culled"); 366 str += attr->getAttributeAsInt("culled");
367 str += " Draw: "; 367 str += " Draw: ";
368 str += attr->getAttributeAsInt("drawn_solid"); 368 str += attr->getAttributeAsInt("drawn_solid");
369 str += "/"; 369 str += "/";
370 str += attr->getAttributeAsInt("drawn_transparent"); 370 str += attr->getAttributeAsInt("drawn_transparent");
371 str += "/"; 371 str += "/";
372 str += attr->getAttributeAsInt("drawn_transparent_effect"); 372 str += attr->getAttributeAsInt("drawn_transparent_effect");
373 373
374 device->setWindowCaption(str.c_str()); 374 device->setWindowCaption(str.c_str());
375 lastFPS = fps; 375 lastFPS = fps;
376 } 376 }
377 } 377 }
378 378
379 /* 379 /*
380 In the end, delete the Irrlicht device. 380 In the end, delete the Irrlicht device.
381 */ 381 */
382 device->drop(); 382 device->drop();
383 383
384 return 0; 384 return 0;
385} 385}
386 386
387/* 387/*
388**/ 388**/