]> git.lizzy.rs Git - irrlicht.git/blob - examples/Demo/CMainMenu.cpp
Merging r6145 through r6171 from trunk to ogl-es branch
[irrlicht.git] / examples / Demo / CMainMenu.cpp
1 // This is a Demo of the Irrlicht Engine (c) 2005-2009 by N.Gebhardt.\r
2 // This file is not documented.\r
3 \r
4 #include "CMainMenu.h"\r
5 #include "CDemo.h"\r
6 #include "exampleHelper.h"\r
7 \r
8 \r
9 \r
10 CMainMenu::CMainMenu()\r
11 : startButton(0), MenuDevice(0), selected(0), start(false),     fullscreen(false),\r
12 #if defined(USE_IRRKLANG) || defined(USE_SDL_MIXER)\r
13         music(true),\r
14 #else\r
15         music(false),\r
16 #endif\r
17         shadows(true), additive(false), transparent(true), vsync(true), aa(true),\r
18 #ifndef _IRR_WINDOWS_\r
19         driverType(video::EDT_OPENGL)\r
20 #else\r
21         driverType(video::EDT_DIRECT3D9)\r
22 #endif\r
23         //driverType(video::EDT_BURNINGSVIDEO)\r
24 {\r
25 }\r
26 \r
27 \r
28 bool CMainMenu::run()\r
29 {\r
30         video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;\r
31         if (!IrrlichtDevice::isDriverSupported(video::EDT_OPENGL))\r
32                 driverType = video::EDT_BURNINGSVIDEO;\r
33 \r
34         MenuDevice = createDevice(driverType,\r
35                 core::dimension2d<u32>(512, 384), 16, false, false, false, this);\r
36 \r
37         const io::path mediaPath = getExampleMediaPath();\r
38 \r
39         if (MenuDevice->getFileSystem()->existFile("irrlicht.dat"))\r
40                 MenuDevice->getFileSystem()->addFileArchive("irrlicht.dat");\r
41         else\r
42                 MenuDevice->getFileSystem()->addFileArchive(mediaPath + "irrlicht.dat");\r
43 \r
44         video::IVideoDriver* driver = MenuDevice->getVideoDriver();\r
45         scene::ISceneManager* smgr = MenuDevice->getSceneManager();\r
46         gui::IGUIEnvironment* guienv = MenuDevice->getGUIEnvironment();\r
47 \r
48         core::stringw str = "Irrlicht Engine Demo v";\r
49         str += MenuDevice->getVersion();\r
50         MenuDevice->setWindowCaption(str.c_str());\r
51 \r
52         // set new Skin\r
53         gui::IGUISkin* newskin = guienv->createSkin(gui::EGST_BURNING_SKIN);\r
54         guienv->setSkin(newskin);\r
55         newskin->drop();\r
56 \r
57         // load font\r
58         gui::IGUIFont* font = guienv->getFont(mediaPath + "fonthaettenschweiler.bmp");\r
59         if (font)\r
60                 guienv->getSkin()->setFont(font);\r
61 \r
62         // add images\r
63 \r
64         const s32 leftX = 260;\r
65 \r
66         // add tab control\r
67         gui::IGUITabControl* tabctrl = guienv->addTabControl(core::rect<int>(leftX,10,512-10,384-10),\r
68                 0, true, true);\r
69         gui::IGUITab* optTab = tabctrl->addTab(L"Demo");\r
70         gui::IGUITab* aboutTab = tabctrl->addTab(L"About");\r
71 \r
72         // add list box\r
73 \r
74         gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1);\r
75         for (u32 i=1; i<video::EDT_COUNT; ++i)\r
76         {\r
77                 if (IrrlichtDevice::isDriverSupported(video::E_DRIVER_TYPE(i)))\r
78                 {\r
79                         box->addItem(core::stringw(video::DRIVER_TYPE_NAMES[i]).c_str());\r
80                         if ( driverType == video::E_DRIVER_TYPE(i) )\r
81                                 selected = box->getItemCount()-1;\r
82                 }\r
83         }\r
84         box->setSelected(selected);\r
85 \r
86         // add button\r
87 \r
88         startButton = guienv->addButton(core::rect<int>(30,295,200,324), optTab, 2, L"Start Demo");\r
89 \r
90         // add checkbox\r
91 \r
92         const s32 d = 50;\r
93 \r
94         guienv->addCheckBox(fullscreen, core::rect<int>(20,85+d,130,110+d),\r
95                 optTab, 3, L"Fullscreen");\r
96         guienv->addCheckBox(music, core::rect<int>(135,85+d,245,110+d),\r
97                 optTab, 4, L"Music & Sfx");\r
98         guienv->addCheckBox(shadows, core::rect<int>(20,110+d,135,135+d),\r
99                 optTab, 5, L"Realtime shadows");\r
100         guienv->addCheckBox(additive, core::rect<int>(20,135+d,230,160+d),\r
101                 optTab, 6, L"Old HW compatible blending");\r
102         guienv->addCheckBox(vsync, core::rect<int>(20,160+d,230,185+d),\r
103                 optTab, 7, L"Vertical synchronisation");\r
104         guienv->addCheckBox(aa, core::rect<int>(20,185+d,230,210+d),\r
105                 optTab, 8, L"Antialiasing");\r
106 \r
107         // add about text\r
108 \r
109         const wchar_t* text2 = L"This is the tech demo of the Irrlicht engine. To start, "\\r
110                 L"select a video driver which works best with your hardware and press 'Start Demo'.\n"\\r
111                 L"What you currently see is displayed using the Burning Software Renderer (Thomas Alten).\n"\\r
112                 L"The Irrlicht Engine was written by me, Nikolaus Gebhardt. The models, "\\r
113                 L"maps and textures were placed at my disposal by B.Collins, M.Cook and J.Marton. The music was created by "\\r
114                 L"M.Rohde and is played back by irrKlang.\n"\\r
115                 L"For more information, please visit the homepage of the Irrlicht engine:\nhttp://irrlicht.sourceforge.net";\r
116 \r
117         guienv->addStaticText(text2, core::rect<int>(10, 10, 230, 320),\r
118                 true, true, aboutTab);\r
119 \r
120         // add md2 model\r
121 \r
122         scene::IAnimatedMesh* mesh = smgr->getMesh(mediaPath + "faerie.md2");\r
123         scene::IAnimatedMeshSceneNode* modelNode = smgr->addAnimatedMeshSceneNode(mesh);\r
124         if (modelNode)\r
125         {\r
126                 modelNode->setPosition( core::vector3df(0.f, 0.f, -5.f) );\r
127                 modelNode->setMaterialTexture(0, driver->getTexture(mediaPath + "faerie2.bmp"));\r
128                 modelNode->setMaterialFlag(video::EMF_LIGHTING, true);\r
129                 modelNode->getMaterial(0).Shininess = 50.f;\r
130                 modelNode->getMaterial(0).NormalizeNormals = true;\r
131                 modelNode->setMD2Animation(scene::EMAT_STAND);\r
132         }\r
133 \r
134         // set ambient light (no sun light in the catacombs)\r
135         smgr->setAmbientLight( video::SColorf(0.2f, 0.2f, 0.2f) );\r
136 \r
137         scene::ILightSceneNode *light;\r
138         scene::ISceneNodeAnimator* anim;\r
139         scene::ISceneNode* bill;\r
140 \r
141         enum eLightParticle\r
142         {\r
143                 LIGHT_NONE,\r
144                 LIGHT_GLOBAL,\r
145                 LIGHT_RED,\r
146                 LIGHT_BLUE\r
147         };\r
148         core::vector3df lightDir[2] = {\r
149                 core::vector3df(0.f, 0.1f, 0.4f),\r
150                 core::vector3df(0.f, 0.1f, -0.4f),\r
151         };\r
152 \r
153         struct SLightParticle\r
154         {\r
155                 eLightParticle type;\r
156                 u32 dir;\r
157         };\r
158         const SLightParticle lightParticle[] =\r
159         {\r
160                 //LIGHT_GLOBAL,0,\r
161                 {LIGHT_RED,0},\r
162                 {LIGHT_BLUE,0},\r
163                 {LIGHT_RED,1},\r
164                 {LIGHT_BLUE,1},\r
165                 {LIGHT_NONE,0}\r
166         };\r
167 \r
168         const SLightParticle *l = lightParticle;\r
169         while ( l->type != LIGHT_NONE )\r
170         {\r
171                 switch ( l->type )\r
172                 {\r
173                         case LIGHT_GLOBAL:\r
174                                 // add illumination from the background\r
175                                 light = smgr->addLightSceneNode(0, core::vector3df(10.f,40.f,-5.f),\r
176                                         video::SColorf(0.2f, 0.2f, 0.2f), 90.f);\r
177                                 break;\r
178                         case LIGHT_RED:\r
179                                 // add light nearly red\r
180                                 light = smgr->addLightSceneNode(0, core::vector3df(0,1,0),\r
181                                         video::SColorf(0.8f, 0.f, 0.f, 0.0f), 30.0f);\r
182                                 // attach red billboard to the light\r
183                                 bill = smgr->addBillboardSceneNode(light, core::dimension2d<f32>(10, 10));\r
184                                 if ( bill )\r
185                                 {\r
186                                         bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
187                                         bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
188                                         bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
189                                         bill->setMaterialTexture(0, driver->getTexture(mediaPath + "particlered.bmp"));\r
190                                 }\r
191                                 // add fly circle animator to the light\r
192                                 anim = smgr->createFlyCircleAnimator(core::vector3df(0.f,0.f,-5.f),20.f,\r
193                                         0.002f, lightDir [l->dir] );\r
194                                 light->addAnimator(anim);\r
195                                 anim->drop();\r
196                                 break;\r
197                         case LIGHT_BLUE:\r
198                                 // add light nearly blue\r
199                                 light = smgr->addLightSceneNode(0, core::vector3df(0,1,0),\r
200                                         video::SColorf(0.f, 0.0f, 0.8f, 0.0f), 30.0f);\r
201                                 // attach blue billboard to the light\r
202                                 bill = smgr->addBillboardSceneNode(light, core::dimension2d<f32>(10, 10));\r
203                                 if (bill)\r
204                                 {\r
205                                         bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
206                                         bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
207                                         bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
208                                         bill->setMaterialTexture(0, driver->getTexture(mediaPath + "portal1.bmp"));\r
209                                 }\r
210                                 // add fly circle animator to the light\r
211                                 anim = smgr->createFlyCircleAnimator(core::vector3df(0.f,0.f,-5.f),20.f,\r
212                                         -0.002f, lightDir [l->dir], 0.5f);\r
213                                 light->addAnimator(anim);\r
214                                 anim->drop();\r
215                                 break;\r
216                         case LIGHT_NONE:\r
217                                 break;\r
218                 }\r
219                 l += 1;\r
220         }\r
221 \r
222         // create a fixed camera\r
223         smgr->addCameraSceneNode(0, core::vector3df(45,0,0), core::vector3df(0,0,10));\r
224 \r
225 \r
226         // irrlicht logo and background\r
227         // add irrlicht logo\r
228         bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);\r
229         driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);\r
230 \r
231         guienv->addImage(driver->getTexture(mediaPath + "irrlichtlogo3.png"),\r
232                 core::position2d<s32>(5,5));\r
233 \r
234         video::ITexture* irrlichtBack = driver->getTexture(mediaPath + "demoback.jpg");\r
235 \r
236         driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);\r
237 \r
238         // query original skin color\r
239         getOriginalSkinColor();\r
240 \r
241         // set transparency\r
242         setTransparency();\r
243 \r
244         // draw all\r
245 \r
246         while(MenuDevice->run())\r
247         {\r
248                 if (MenuDevice->isWindowActive())\r
249                 {\r
250                         driver->beginScene(video::ECBF_DEPTH, video::SColor(0,0,0,0));\r
251 \r
252                         if (irrlichtBack)\r
253                                 driver->draw2DImage(irrlichtBack,\r
254                                                 core::position2d<int>(0,0));\r
255 \r
256                         smgr->drawAll();\r
257                         guienv->drawAll();\r
258                         driver->endScene();\r
259                 }\r
260         }\r
261 \r
262         MenuDevice->drop();\r
263 \r
264         for (u32 i=1; i<video::EDT_COUNT; ++i)\r
265         {\r
266                 if (IrrlichtDevice::isDriverSupported(video::E_DRIVER_TYPE(i)))\r
267                 {\r
268                         if (!selected)\r
269                         {\r
270                                 driverType=video::E_DRIVER_TYPE(i);\r
271                                 break;\r
272                         }\r
273                         --selected;\r
274                 }\r
275         }\r
276 \r
277         return start;\r
278 }\r
279 \r
280 \r
281 bool CMainMenu::OnEvent(const SEvent& event)\r
282 {\r
283         if (event.EventType == EET_KEY_INPUT_EVENT &&\r
284                 event.KeyInput.Key == KEY_F9 &&\r
285                 event.KeyInput.PressedDown == false)\r
286         {\r
287                 video::IImage* image = MenuDevice->getVideoDriver()->createScreenShot();\r
288                 if (image)\r
289                 {\r
290                         MenuDevice->getVideoDriver()->writeImageToFile(image, "screenshot_main.jpg");\r
291                         image->drop();\r
292                 }\r
293         }\r
294         else\r
295         if (event.EventType == irr::EET_MOUSE_INPUT_EVENT &&\r
296                 event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP )\r
297         {\r
298                 core::rect<s32> r(event.MouseInput.X, event.MouseInput.Y, 0, 0);\r
299                 gui::IGUIContextMenu* menu = MenuDevice->getGUIEnvironment()->addContextMenu(r, 0, 45);\r
300                 menu->addItem(L"transparent menus", 666, transparent == false);\r
301                 menu->addItem(L"solid menus", 666, transparent == true);\r
302                 menu->addSeparator();\r
303                 menu->addItem(L"Cancel");\r
304         }\r
305         else\r
306         if (event.EventType == EET_GUI_EVENT)\r
307         {\r
308                 s32 id = event.GUIEvent.Caller->getID();\r
309                 switch(id)\r
310                 {\r
311                 case 45: // context menu\r
312                         if (event.GUIEvent.EventType == gui::EGET_MENU_ITEM_SELECTED)\r
313                         {\r
314                                 s32 s = ((gui::IGUIContextMenu*)event.GUIEvent.Caller)->getSelectedItem();\r
315                                 if (s == 0 || s == 1)\r
316                                 {\r
317                                         transparent = !transparent;\r
318                                         setTransparency();\r
319                                 }\r
320                         }\r
321                         break;\r
322                 case 1:\r
323                         if (event.GUIEvent.EventType == gui::EGET_LISTBOX_CHANGED ||\r
324                                 event.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN)\r
325                         {\r
326                                 selected = ((gui::IGUIListBox*)event.GUIEvent.Caller)->getSelected();\r
327                                 //startButton->setEnabled(selected != 4);\r
328                                 startButton->setEnabled(true);\r
329                         }\r
330                         break;\r
331                 case 2:\r
332                         if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED )\r
333                         {\r
334                                 MenuDevice->closeDevice();\r
335                                 start = true;\r
336                         }\r
337                 case 3:\r
338                         if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )\r
339                                 fullscreen = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();\r
340                         break;\r
341                 case 4:\r
342                         if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )\r
343                                 music = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();\r
344                         break;\r
345                 case 5:\r
346                         if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )\r
347                                 shadows = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();\r
348                         break;\r
349                 case 6:\r
350                         if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )\r
351                                 additive = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();\r
352                         break;\r
353                 case 7:\r
354                         if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )\r
355                                 vsync = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();\r
356                         break;\r
357                 case 8:\r
358                         if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )\r
359                                 aa = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();\r
360                         break;\r
361                 }\r
362         }\r
363 \r
364         return false;\r
365 }\r
366 \r
367 \r
368 void CMainMenu::getOriginalSkinColor()\r
369 {\r
370         irr::gui::IGUISkin * skin = MenuDevice->getGUIEnvironment()->getSkin();\r
371         for (s32 i=0; i<gui::EGDC_COUNT ; ++i)\r
372         {\r
373                 SkinColor[i] = skin->getColor( (gui::EGUI_DEFAULT_COLOR)i );\r
374         }\r
375 \r
376 }\r
377 \r
378 \r
379 void CMainMenu::setTransparency()\r
380 {\r
381         irr::gui::IGUISkin * skin = MenuDevice->getGUIEnvironment()->getSkin();\r
382 \r
383         for (u32 i=0; i<gui::EGDC_COUNT ; ++i)\r
384         {\r
385                 video::SColor col = SkinColor[i];\r
386 \r
387                 if (false == transparent)\r
388                         col.setAlpha(255);\r
389 \r
390                 skin->setColor((gui::EGUI_DEFAULT_COLOR)i, col);\r
391         }\r
392 }\r
393 \r