]> git.lizzy.rs Git - minetest.git/blob - src/drawscene.cpp
FormSpec: Add StaticTextSpec and superimpose over item image buttons
[minetest.git] / src / drawscene.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "drawscene.h"
21 #include "settings.h"
22 #include "clouds.h"
23 #include "clientmap.h"
24 #include "util/timetaker.h"
25 #include "fontengine.h"
26 #include "guiscalingfilter.h"
27
28 typedef enum {
29         LEFT = -1,
30         RIGHT = 1,
31         EYECOUNT = 2
32 } paralax_sign;
33
34 void draw_anaglyph_3d_mode(Camera& camera, bool show_hud, Hud& hud,
35                 video::IVideoDriver* driver, scene::ISceneManager* smgr,
36                 bool draw_wield_tool, Client& client,
37                 gui::IGUIEnvironment* guienv )
38 {
39
40         /* preserve old setup*/
41         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
42         irr::core::vector3df oldTarget   = camera.getCameraNode()->getTarget();
43
44         irr::core::matrix4 startMatrix =
45                         camera.getCameraNode()->getAbsoluteTransformation();
46         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
47                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
48                         + camera.getCameraNode()->getAbsolutePosition();
49
50
51         //Left eye...
52         irr::core::vector3df leftEye;
53         irr::core::matrix4 leftMove;
54         leftMove.setTranslation(
55                         irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
56                                         0.0f, 0.0f));
57         leftEye = (startMatrix * leftMove).getTranslation();
58
59         //clear the depth buffer, and color
60         driver->beginScene( true, true, irr::video::SColor(0, 200, 200, 255));
61         driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED;
62         driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
63         driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
64                         + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
65                         + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
66         camera.getCameraNode()->setPosition(leftEye);
67         camera.getCameraNode()->setTarget(focusPoint);
68         smgr->drawAll();
69         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
70         if (show_hud) {
71                 hud.drawSelectionMesh();
72                 if (draw_wield_tool)
73                         camera.drawWieldedTool(&leftMove);
74         }
75
76         guienv->drawAll();
77
78         //Right eye...
79         irr::core::vector3df rightEye;
80         irr::core::matrix4 rightMove;
81         rightMove.setTranslation(
82                         irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
83                                         0.0f, 0.0f));
84         rightEye = (startMatrix * rightMove).getTranslation();
85
86         //clear the depth buffer
87         driver->clearZBuffer();
88         driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN
89                         + irr::video::ECP_BLUE;
90         driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
91         driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
92                         + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
93                         + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
94         camera.getCameraNode()->setPosition(rightEye);
95         camera.getCameraNode()->setTarget(focusPoint);
96         smgr->drawAll();
97         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
98         if (show_hud) {
99                 hud.drawSelectionMesh();
100                 if (draw_wield_tool)
101                         camera.drawWieldedTool(&rightMove);
102         }
103
104         guienv->drawAll();
105
106         driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_ALL;
107         driver->getOverrideMaterial().EnableFlags = 0;
108         driver->getOverrideMaterial().EnablePasses = 0;
109         camera.getCameraNode()->setPosition(oldPosition);
110         camera.getCameraNode()->setTarget(oldTarget);
111 }
112
113 void init_texture(video::IVideoDriver* driver, const v2u32& screensize,
114                 video::ITexture** texture, const char* name)
115 {
116         if (*texture != NULL)
117         {
118                 driver->removeTexture(*texture);
119         }
120         *texture = driver->addRenderTargetTexture(
121                         core::dimension2d<u32>(screensize.X, screensize.Y), name,
122                         irr::video::ECF_A8R8G8B8);
123 }
124
125 video::ITexture* draw_image(const v2u32 &screensize,
126                 paralax_sign psign, const irr::core::matrix4 &startMatrix,
127                 const irr::core::vector3df &focusPoint, bool show_hud,
128                 video::IVideoDriver *driver, Camera &camera, scene::ISceneManager *smgr,
129                 Hud &hud, bool draw_wield_tool, Client &client,
130                 gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
131 {
132         static video::ITexture* images[2] = { NULL, NULL };
133         static v2u32 last_screensize = v2u32(0, 0);
134
135         video::ITexture* image = NULL;
136
137         if (screensize != last_screensize) {
138                 init_texture(driver, screensize, &images[1], "mt_drawimage_img1");
139                 init_texture(driver, screensize, &images[0], "mt_drawimage_img2");
140                 last_screensize = screensize;
141         }
142
143         if (psign == RIGHT)
144                 image = images[1];
145         else
146                 image = images[0];
147
148         driver->setRenderTarget(image, true, true,
149                         irr::video::SColor(255,
150                                         skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
151
152         irr::core::vector3df eye_pos;
153         irr::core::matrix4 movement;
154         movement.setTranslation(
155                         irr::core::vector3df((int) psign *
156                                         g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
157         eye_pos = (startMatrix * movement).getTranslation();
158
159         //clear the depth buffer
160         driver->clearZBuffer();
161         camera.getCameraNode()->setPosition(eye_pos);
162         camera.getCameraNode()->setTarget(focusPoint);
163         smgr->drawAll();
164
165         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
166
167         if (show_hud) {
168                 hud.drawSelectionMesh();
169                 if (draw_wield_tool)
170                         camera.drawWieldedTool(&movement);
171         }
172
173         guienv->drawAll();
174
175         /* switch back to real renderer */
176         driver->setRenderTarget(0, true, true,
177                         irr::video::SColor(0,
178                                         skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
179
180         return image;
181 }
182
183 video::ITexture*  draw_hud(video::IVideoDriver* driver, const v2u32& screensize,
184                 bool show_hud, Hud& hud, Client& client, bool draw_crosshair,
185                 video::SColor skycolor, gui::IGUIEnvironment* guienv, Camera& camera )
186 {
187         static video::ITexture* image = NULL;
188         init_texture(driver, screensize, &image, "mt_drawimage_hud");
189         driver->setRenderTarget(image, true, true,
190                         irr::video::SColor(255,0,0,0));
191
192         if (show_hud)
193         {
194                 if (draw_crosshair)
195                         hud.drawCrosshair();
196                 hud.drawHotbar(client.getPlayerItem());
197                 hud.drawLuaElements(camera.getOffset());
198
199                 guienv->drawAll();
200         }
201
202         driver->setRenderTarget(0, true, true,
203                         irr::video::SColor(0,
204                                         skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
205
206         return image;
207 }
208
209 void draw_interlaced_3d_mode(Camera& camera, bool show_hud,
210                 Hud& hud, video::IVideoDriver* driver,
211                 scene::ISceneManager* smgr, const v2u32& screensize,
212                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
213                 video::SColor skycolor )
214 {
215         /* save current info */
216         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
217         irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
218         irr::core::matrix4 startMatrix =
219                         camera.getCameraNode()->getAbsoluteTransformation();
220         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
221                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
222                         + camera.getCameraNode()->getAbsolutePosition();
223
224         /* create left view */
225         video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
226                         focusPoint, show_hud, driver, camera, smgr, hud,
227                         draw_wield_tool, client, guienv, skycolor);
228
229         //Right eye...
230         irr::core::vector3df rightEye;
231         irr::core::matrix4 rightMove;
232         rightMove.setTranslation(
233                         irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
234                                         0.0f, 0.0f));
235         rightEye = (startMatrix * rightMove).getTranslation();
236
237         //clear the depth buffer
238         driver->clearZBuffer();
239         camera.getCameraNode()->setPosition(rightEye);
240         camera.getCameraNode()->setTarget(focusPoint);
241         smgr->drawAll();
242
243         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
244
245         if (show_hud) {
246                 hud.drawSelectionMesh();
247                 if(draw_wield_tool)
248                         camera.drawWieldedTool(&rightMove);
249         }
250         guienv->drawAll();
251
252         for (unsigned int i = 0; i < screensize.Y; i+=2 ) {
253 #if (IRRLICHT_VERSION_MAJOR >= 1) && (IRRLICHT_VERSION_MINOR >= 8)
254                 driver->draw2DImage(left_image, irr::core::position2d<s32>(0, i),
255 #else
256                 driver->draw2DImage(left_image, irr::core::position2d<s32>(0, screensize.Y-i),
257 #endif
258                                 irr::core::rect<s32>(0, i,screensize.X, i+1), 0,
259                                 irr::video::SColor(255, 255, 255, 255),
260                                 false);
261         }
262
263         /* cleanup */
264         camera.getCameraNode()->setPosition(oldPosition);
265         camera.getCameraNode()->setTarget(oldTarget);
266 }
267
268 void draw_sidebyside_3d_mode(Camera& camera, bool show_hud,
269                 Hud& hud, video::IVideoDriver* driver,
270                 scene::ISceneManager* smgr, const v2u32& screensize,
271                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
272                 video::SColor skycolor )
273 {
274         /* save current info */
275         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
276         irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
277         irr::core::matrix4 startMatrix =
278                         camera.getCameraNode()->getAbsoluteTransformation();
279         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
280                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
281                         + camera.getCameraNode()->getAbsolutePosition();
282
283         /* create left view */
284         video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
285                         focusPoint, show_hud, driver, camera, smgr, hud,
286                         draw_wield_tool, client, guienv, skycolor);
287
288         /* create right view */
289         video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
290                         focusPoint, show_hud, driver, camera, smgr, hud,
291                         draw_wield_tool, client, guienv, skycolor);
292
293         /* create hud overlay */
294         video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
295                         false, skycolor, guienv, camera );
296         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
297         //makeColorKeyTexture mirrors texture so we do it twice to get it right again
298         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
299
300         draw2DImageFilterScaled(driver, left_image,
301                         irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
302                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
303
304         draw2DImageFilterScaled(driver, hudtexture,
305                         irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
306                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
307
308         draw2DImageFilterScaled(driver, right_image,
309                         irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
310                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
311
312         draw2DImageFilterScaled(driver, hudtexture,
313                         irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
314                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
315
316         left_image = NULL;
317         right_image = NULL;
318
319         /* cleanup */
320         camera.getCameraNode()->setPosition(oldPosition);
321         camera.getCameraNode()->setTarget(oldTarget);
322 }
323
324 void draw_top_bottom_3d_mode(Camera& camera, bool show_hud,
325                 Hud& hud, video::IVideoDriver* driver,
326                 scene::ISceneManager* smgr, const v2u32& screensize,
327                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
328                 video::SColor skycolor )
329 {
330         /* save current info */
331         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
332         irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
333         irr::core::matrix4 startMatrix =
334                         camera.getCameraNode()->getAbsoluteTransformation();
335         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
336                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
337                         + camera.getCameraNode()->getAbsolutePosition();
338
339         /* create left view */
340         video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
341                         focusPoint, show_hud, driver, camera, smgr, hud,
342                         draw_wield_tool, client, guienv, skycolor);
343
344         /* create right view */
345         video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
346                         focusPoint, show_hud, driver, camera, smgr, hud,
347                         draw_wield_tool, client, guienv, skycolor);
348
349         /* create hud overlay */
350         video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
351                         false, skycolor, guienv, camera );
352         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
353         //makeColorKeyTexture mirrors texture so we do it twice to get it right again
354         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
355
356         draw2DImageFilterScaled(driver, left_image,
357                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
358                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
359
360         draw2DImageFilterScaled(driver, hudtexture,
361                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
362                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
363
364         draw2DImageFilterScaled(driver, right_image,
365                         irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
366                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
367
368         draw2DImageFilterScaled(driver, hudtexture,
369                         irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
370                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
371
372         left_image = NULL;
373         right_image = NULL;
374
375         /* cleanup */
376         camera.getCameraNode()->setPosition(oldPosition);
377         camera.getCameraNode()->setTarget(oldTarget);
378 }
379
380 void draw_pageflip_3d_mode(Camera& camera, bool show_hud,
381                 Hud& hud, video::IVideoDriver* driver,
382                 scene::ISceneManager* smgr, const v2u32& screensize,
383                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
384                 video::SColor skycolor)
385 {
386         /* preserve old setup*/
387         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
388         irr::core::vector3df oldTarget   = camera.getCameraNode()->getTarget();
389
390         irr::core::matrix4 startMatrix =
391                         camera.getCameraNode()->getAbsoluteTransformation();
392         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
393                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
394                         + camera.getCameraNode()->getAbsolutePosition();
395
396         //Left eye...
397         driver->setRenderTarget(irr::video::ERT_STEREO_LEFT_BUFFER);
398
399         irr::core::vector3df leftEye;
400         irr::core::matrix4 leftMove;
401         leftMove.setTranslation(
402                         irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
403                                         0.0f, 0.0f));
404         leftEye = (startMatrix * leftMove).getTranslation();
405
406         //clear the depth buffer, and color
407         driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
408         camera.getCameraNode()->setPosition(leftEye);
409         camera.getCameraNode()->setTarget(focusPoint);
410         smgr->drawAll();
411         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
412
413         if (show_hud) {
414                 hud.drawSelectionMesh();
415                 if (draw_wield_tool)
416                         camera.drawWieldedTool(&leftMove);
417                 hud.drawHotbar(client.getPlayerItem());
418                 hud.drawLuaElements(camera.getOffset());
419         }
420
421         guienv->drawAll();
422
423         //Right eye...
424         driver->setRenderTarget(irr::video::ERT_STEREO_RIGHT_BUFFER);
425
426         irr::core::vector3df rightEye;
427         irr::core::matrix4 rightMove;
428         rightMove.setTranslation(
429                         irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
430                                         0.0f, 0.0f));
431         rightEye = (startMatrix * rightMove).getTranslation();
432
433         //clear the depth buffer, and color
434         driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
435         camera.getCameraNode()->setPosition(rightEye);
436         camera.getCameraNode()->setTarget(focusPoint);
437         smgr->drawAll();
438         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
439
440         if (show_hud) {
441                 hud.drawSelectionMesh();
442                 if (draw_wield_tool)
443                         camera.drawWieldedTool(&rightMove);
444                 hud.drawHotbar(client.getPlayerItem());
445                 hud.drawLuaElements(camera.getOffset());
446         }
447
448         guienv->drawAll();
449
450         camera.getCameraNode()->setPosition(oldPosition);
451         camera.getCameraNode()->setTarget(oldTarget);
452 }
453
454 void draw_plain(Camera &camera, bool show_hud, Hud &hud,
455                 video::IVideoDriver *driver, bool draw_wield_tool,
456                 Client &client, gui::IGUIEnvironment *guienv)
457 {
458         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
459         if (show_hud) {
460                 hud.drawSelectionMesh();
461                 if (draw_wield_tool) {
462                         camera.drawWieldedTool();
463                 }
464         }
465 }
466
467 void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr,
468                 Camera &camera, Client& client, LocalPlayer *player, Hud &hud,
469                 Mapper &mapper, gui::IGUIEnvironment *guienv,
470                 const v2u32 &screensize, const video::SColor &skycolor,
471                 bool show_hud, bool show_minimap)
472 {
473         TimeTaker timer("smgr");
474
475         bool draw_wield_tool = (show_hud &&
476                         (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
477                         camera.getCameraMode() < CAMERA_MODE_THIRD );
478
479         bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
480                         (camera.getCameraMode() != CAMERA_MODE_THIRD_FRONT));
481
482 #ifdef HAVE_TOUCHSCREENGUI
483         try {
484                 draw_crosshair = !g_settings->getBool("touchtarget");
485         }
486         catch(SettingNotFoundException) {}
487 #endif
488
489         std::string draw_mode = g_settings->get("3d_mode");
490
491         smgr->drawAll();
492
493         if (draw_mode == "anaglyph")
494         {
495                 draw_anaglyph_3d_mode(camera, show_hud, hud, driver,
496                                 smgr, draw_wield_tool, client, guienv);
497                 draw_crosshair = false;
498         }
499         else if (draw_mode == "interlaced")
500         {
501                 draw_interlaced_3d_mode(camera, show_hud, hud, driver,
502                                 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
503                 draw_crosshair = false;
504         }
505         else if (draw_mode == "sidebyside")
506         {
507                 draw_sidebyside_3d_mode(camera, show_hud, hud, driver,
508                                 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
509                 show_hud = false;
510         }
511         else if (draw_mode == "topbottom")
512         {
513                 draw_top_bottom_3d_mode(camera, show_hud, hud, driver,
514                                 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
515                 show_hud = false;
516         }
517         else if (draw_mode == "pageflip")
518         {
519                 draw_pageflip_3d_mode(camera, show_hud, hud, driver,
520                                 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
521                 draw_crosshair = false;
522                 show_hud = false;
523         }
524         else {
525                 draw_plain(camera, show_hud, hud, driver,
526                                 draw_wield_tool, client, guienv);
527         }
528
529         /*
530                 Post effects
531         */
532         {
533                 client.getEnv().getClientMap().renderPostFx(camera.getCameraMode());
534         }
535
536         //TODO how to make those 3d too
537         if (show_hud)
538         {
539                 if (draw_crosshair)
540                         hud.drawCrosshair();
541                 hud.drawHotbar(client.getPlayerItem());
542                 hud.drawLuaElements(camera.getOffset());
543                 if (show_minimap)
544                         mapper.drawMinimap();
545         }
546
547         guienv->drawAll();
548
549         timer.stop(true);
550 }
551
552 /*
553         Draws a screen with a single text on it.
554         Text will be removed when the screen is drawn the next time.
555         Additionally, a progressbar can be drawn when percent is set between 0 and 100.
556 */
557 void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
558                 gui::IGUIEnvironment* guienv, float dtime, int percent, bool clouds )
559 {
560         video::IVideoDriver* driver    = device->getVideoDriver();
561         v2u32 screensize               = porting::getWindowSize();
562
563         v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight());
564         v2s32 center(screensize.X / 2, screensize.Y / 2);
565         core::rect<s32> textrect(center - textsize / 2, center + textsize / 2);
566
567         gui::IGUIStaticText *guitext = guienv->addStaticText(
568                         text.c_str(), textrect, false, false);
569         guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
570
571         bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
572         if (cloud_menu_background)
573         {
574                 g_menuclouds->step(dtime*3);
575                 g_menuclouds->render();
576                 driver->beginScene(true, true, video::SColor(255, 140, 186, 250));
577                 g_menucloudsmgr->drawAll();
578         }
579         else
580                 driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
581
582         // draw progress bar
583         if ((percent >= 0) && (percent <= 100))
584         {
585                 v2s32 barsize(
586                                 // 342 is (approximately) 256/0.75 to keep bar on same size as
587                                 // before with default settings
588                                 342 * porting::getDisplayDensity() *
589                                 g_settings->getFloat("gui_scaling"),
590                                 g_fontengine->getTextHeight() * 2);
591
592                 core::rect<s32> barrect(center - barsize / 2, center + barsize / 2);
593                 driver->draw2DRectangle(video::SColor(255, 255, 255, 255),barrect, NULL); // border
594                 driver->draw2DRectangle(video::SColor(255, 64, 64, 64), core::rect<s32> (
595                                 barrect.UpperLeftCorner + 1,
596                                 barrect.LowerRightCorner-1), NULL); // black inside the bar
597                 driver->draw2DRectangle(video::SColor(255, 128, 128, 128), core::rect<s32> (
598                                 barrect.UpperLeftCorner + 1,
599                                 core::vector2d<s32>(
600                                                 barrect.LowerRightCorner.X -
601                                                 (barsize.X - 1) + percent * (barsize.X - 2) / 100,
602                                                 barrect.LowerRightCorner.Y - 1)), NULL); // the actual progress
603         }
604         guienv->drawAll();
605         driver->endScene();
606
607         guitext->remove();
608
609         //return guitext;
610 }