Clean scaling pre-filter for formspec/HUD.
[oweals/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 "main.h" // for g_settings
22 #include "settings.h"
23 #include "clouds.h"
24 #include "clientmap.h"
25 #include "util/timetaker.h"
26 #include "fontengine.h"
27 #include "guiscalingfilter.h"
28
29 typedef enum {
30         LEFT = -1,
31         RIGHT = 1,
32         EYECOUNT = 2
33 } paralax_sign;
34
35
36 void draw_selectionbox(video::IVideoDriver* driver, Hud& hud,
37                 std::vector<aabb3f>& hilightboxes, bool show_hud)
38 {
39         static const s16 selectionbox_width = rangelim(g_settings->getS16("selectionbox_width"), 1, 5);
40
41         if (!show_hud)
42                 return;
43
44         video::SMaterial oldmaterial = driver->getMaterial2D();
45         video::SMaterial m;
46         m.Thickness = selectionbox_width;
47         m.Lighting = false;
48         driver->setMaterial(m);
49         hud.drawSelectionBoxes(hilightboxes);
50         driver->setMaterial(oldmaterial);
51 }
52
53 void draw_anaglyph_3d_mode(Camera& camera, bool show_hud, Hud& hud,
54                 std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
55                 scene::ISceneManager* smgr, bool draw_wield_tool, Client& client,
56                 gui::IGUIEnvironment* guienv )
57 {
58
59         /* preserve old setup*/
60         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
61         irr::core::vector3df oldTarget   = camera.getCameraNode()->getTarget();
62
63         irr::core::matrix4 startMatrix =
64                         camera.getCameraNode()->getAbsoluteTransformation();
65         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
66                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
67                         + camera.getCameraNode()->getAbsolutePosition();
68
69
70         //Left eye...
71         irr::core::vector3df leftEye;
72         irr::core::matrix4 leftMove;
73         leftMove.setTranslation(
74                         irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
75                                         0.0f, 0.0f));
76         leftEye = (startMatrix * leftMove).getTranslation();
77
78         //clear the depth buffer, and color
79         driver->beginScene( true, true, irr::video::SColor(0, 200, 200, 255));
80         driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED;
81         driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
82         driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
83                         + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
84                         + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
85         camera.getCameraNode()->setPosition(leftEye);
86         camera.getCameraNode()->setTarget(focusPoint);
87         smgr->drawAll();
88         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
89         if (show_hud)
90         {
91                 draw_selectionbox(driver, hud, hilightboxes, show_hud);
92
93                 if (draw_wield_tool)
94                         camera.drawWieldedTool(&leftMove);
95         }
96
97         guienv->drawAll();
98
99         //Right eye...
100         irr::core::vector3df rightEye;
101         irr::core::matrix4 rightMove;
102         rightMove.setTranslation(
103                         irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
104                                         0.0f, 0.0f));
105         rightEye = (startMatrix * rightMove).getTranslation();
106
107         //clear the depth buffer
108         driver->clearZBuffer();
109         driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_GREEN
110                         + irr::video::ECP_BLUE;
111         driver->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
112         driver->getOverrideMaterial().EnablePasses = irr::scene::ESNRP_SKY_BOX
113                         + irr::scene::ESNRP_SOLID + irr::scene::ESNRP_TRANSPARENT
114                         + irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
115         camera.getCameraNode()->setPosition(rightEye);
116         camera.getCameraNode()->setTarget(focusPoint);
117         smgr->drawAll();
118         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
119         if (show_hud)
120         {
121                 draw_selectionbox(driver, hud, hilightboxes, show_hud);
122
123                 if (draw_wield_tool)
124                         camera.drawWieldedTool(&rightMove);
125         }
126
127         guienv->drawAll();
128
129         driver->getOverrideMaterial().Material.ColorMask = irr::video::ECP_ALL;
130         driver->getOverrideMaterial().EnableFlags = 0;
131         driver->getOverrideMaterial().EnablePasses = 0;
132         camera.getCameraNode()->setPosition(oldPosition);
133         camera.getCameraNode()->setTarget(oldTarget);
134 }
135
136 void init_texture(video::IVideoDriver* driver, const v2u32& screensize,
137                 video::ITexture** texture, const char* name)
138 {
139         if (*texture != NULL)
140         {
141                 driver->removeTexture(*texture);
142         }
143         *texture = driver->addRenderTargetTexture(
144                         core::dimension2d<u32>(screensize.X, screensize.Y), name,
145                         irr::video::ECF_A8R8G8B8);
146 }
147
148 video::ITexture* draw_image(const v2u32& screensize,
149                 paralax_sign psign, const irr::core::matrix4& startMatrix,
150                 const irr::core::vector3df& focusPoint, bool show_hud,
151                 video::IVideoDriver* driver, Camera& camera, scene::ISceneManager* smgr,
152                 Hud& hud, std::vector<aabb3f>& hilightboxes,
153                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
154                 video::SColor skycolor )
155 {
156         static video::ITexture* images[2] = { NULL, NULL };
157         static v2u32 last_screensize = v2u32(0,0);
158
159         video::ITexture* image = NULL;
160
161         if (screensize != last_screensize) {
162                 init_texture(driver, screensize, &images[1], "mt_drawimage_img1");
163                 init_texture(driver, screensize, &images[0], "mt_drawimage_img2");
164                 last_screensize = screensize;
165         }
166
167         if (psign == RIGHT)
168                 image = images[1];
169         else
170                 image = images[0];
171
172         driver->setRenderTarget(image, true, true,
173                         irr::video::SColor(255,
174                                         skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
175
176         irr::core::vector3df eye_pos;
177         irr::core::matrix4 movement;
178         movement.setTranslation(
179                         irr::core::vector3df((int) psign *
180                                         g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
181         eye_pos = (startMatrix * movement).getTranslation();
182
183         //clear the depth buffer
184         driver->clearZBuffer();
185         camera.getCameraNode()->setPosition(eye_pos);
186         camera.getCameraNode()->setTarget(focusPoint);
187         smgr->drawAll();
188
189         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
190
191         if (show_hud)
192         {
193                 draw_selectionbox(driver, hud, hilightboxes, show_hud);
194
195                 if (draw_wield_tool)
196                         camera.drawWieldedTool(&movement);
197         }
198
199         guienv->drawAll();
200
201         /* switch back to real renderer */
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 video::ITexture*  draw_hud(video::IVideoDriver* driver, const v2u32& screensize,
210                 bool show_hud, Hud& hud, Client& client, bool draw_crosshair,
211                 video::SColor skycolor, gui::IGUIEnvironment* guienv, Camera& camera )
212 {
213         static video::ITexture* image = NULL;
214         init_texture(driver, screensize, &image, "mt_drawimage_hud");
215         driver->setRenderTarget(image, true, true,
216                         irr::video::SColor(255,0,0,0));
217
218         if (show_hud)
219         {
220                 if (draw_crosshair)
221                         hud.drawCrosshair();
222                 hud.drawHotbar(client.getPlayerItem());
223                 hud.drawLuaElements(camera.getOffset());
224
225                 guienv->drawAll();
226         }
227
228         driver->setRenderTarget(0, true, true,
229                         irr::video::SColor(0,
230                                         skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
231
232         return image;
233 }
234
235 void draw_interlaced_3d_mode(Camera& camera, bool show_hud,
236                 Hud& hud, std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
237                 scene::ISceneManager* smgr, const v2u32& screensize,
238                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
239                 video::SColor skycolor )
240 {
241         /* save current info */
242         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
243         irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
244         irr::core::matrix4 startMatrix =
245                         camera.getCameraNode()->getAbsoluteTransformation();
246         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
247                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
248                         + camera.getCameraNode()->getAbsolutePosition();
249
250         /* create left view */
251         video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
252                         focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
253                         draw_wield_tool, client, guienv, skycolor);
254
255         //Right eye...
256         irr::core::vector3df rightEye;
257         irr::core::matrix4 rightMove;
258         rightMove.setTranslation(
259                         irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
260                                         0.0f, 0.0f));
261         rightEye = (startMatrix * rightMove).getTranslation();
262
263         //clear the depth buffer
264         driver->clearZBuffer();
265         camera.getCameraNode()->setPosition(rightEye);
266         camera.getCameraNode()->setTarget(focusPoint);
267         smgr->drawAll();
268
269         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
270
271         if (show_hud)
272         {
273                 draw_selectionbox(driver, hud, hilightboxes, show_hud);
274
275                 if(draw_wield_tool)
276                         camera.drawWieldedTool(&rightMove);
277         }
278         guienv->drawAll();
279
280         for (unsigned int i = 0; i < screensize.Y; i+=2 ) {
281 #if (IRRLICHT_VERSION_MAJOR >= 1) && (IRRLICHT_VERSION_MINOR >= 8)
282                 driver->draw2DImage(left_image, irr::core::position2d<s32>(0, i),
283 #else
284                 driver->draw2DImage(left_image, irr::core::position2d<s32>(0, screensize.Y-i),
285 #endif
286                                 irr::core::rect<s32>(0, i,screensize.X, i+1), 0,
287                                 irr::video::SColor(255, 255, 255, 255),
288                                 false);
289         }
290
291         /* cleanup */
292         camera.getCameraNode()->setPosition(oldPosition);
293         camera.getCameraNode()->setTarget(oldTarget);
294 }
295
296 void draw_sidebyside_3d_mode(Camera& camera, bool show_hud,
297                 Hud& hud, std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
298                 scene::ISceneManager* smgr, const v2u32& screensize,
299                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
300                 video::SColor skycolor )
301 {
302         /* save current info */
303         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
304         irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
305         irr::core::matrix4 startMatrix =
306                         camera.getCameraNode()->getAbsoluteTransformation();
307         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
308                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
309                         + camera.getCameraNode()->getAbsolutePosition();
310
311         /* create left view */
312         video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
313                         focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
314                         draw_wield_tool, client, guienv, skycolor);
315
316         /* create right view */
317         video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
318                         focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
319                         draw_wield_tool, client, guienv, skycolor);
320
321         /* create hud overlay */
322         video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
323                         false, skycolor, guienv, camera );
324         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
325         //makeColorKeyTexture mirrors texture so we do it twice to get it right again
326         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
327
328         draw2DImageFilterScaled(driver, left_image,
329                         irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
330                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
331
332         draw2DImageFilterScaled(driver, hudtexture,
333                         irr::core::rect<s32>(0, 0, screensize.X/2, screensize.Y),
334                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
335
336         draw2DImageFilterScaled(driver, right_image,
337                         irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
338                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
339
340         draw2DImageFilterScaled(driver, hudtexture,
341                         irr::core::rect<s32>(screensize.X/2, 0, screensize.X, screensize.Y),
342                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
343
344         left_image = NULL;
345         right_image = NULL;
346
347         /* cleanup */
348         camera.getCameraNode()->setPosition(oldPosition);
349         camera.getCameraNode()->setTarget(oldTarget);
350 }
351
352 void draw_top_bottom_3d_mode(Camera& camera, bool show_hud,
353                 Hud& hud, std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
354                 scene::ISceneManager* smgr, const v2u32& screensize,
355                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
356                 video::SColor skycolor )
357 {
358         /* save current info */
359         irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
360         irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
361         irr::core::matrix4 startMatrix =
362                         camera.getCameraNode()->getAbsoluteTransformation();
363         irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
364                         - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
365                         + camera.getCameraNode()->getAbsolutePosition();
366
367         /* create left view */
368         video::ITexture* left_image = draw_image(screensize, LEFT, startMatrix,
369                         focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
370                         draw_wield_tool, client, guienv, skycolor);
371
372         /* create right view */
373         video::ITexture* right_image = draw_image(screensize, RIGHT, startMatrix,
374                         focusPoint, show_hud, driver, camera, smgr, hud, hilightboxes,
375                         draw_wield_tool, client, guienv, skycolor);
376
377         /* create hud overlay */
378         video::ITexture* hudtexture = draw_hud(driver, screensize, show_hud, hud, client,
379                         false, skycolor, guienv, camera );
380         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
381         //makeColorKeyTexture mirrors texture so we do it twice to get it right again
382         driver->makeColorKeyTexture(hudtexture, irr::video::SColor(255, 0, 0, 0));
383
384         draw2DImageFilterScaled(driver, left_image,
385                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
386                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
387
388         draw2DImageFilterScaled(driver, hudtexture,
389                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y/2),
390                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
391
392         draw2DImageFilterScaled(driver, right_image,
393                         irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
394                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, false);
395
396         draw2DImageFilterScaled(driver, hudtexture,
397                         irr::core::rect<s32>(0, screensize.Y/2, screensize.X, screensize.Y),
398                         irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0, true);
399
400         left_image = NULL;
401         right_image = NULL;
402
403         /* cleanup */
404         camera.getCameraNode()->setPosition(oldPosition);
405         camera.getCameraNode()->setTarget(oldTarget);
406 }
407
408 void draw_plain(Camera& camera, bool show_hud, Hud& hud,
409                 std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
410                 bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv)
411 {
412         driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
413
414         draw_selectionbox(driver, hud, hilightboxes, show_hud);
415
416         if(draw_wield_tool)
417                 camera.drawWieldedTool();
418 }
419
420 void draw_scene(video::IVideoDriver* driver, scene::ISceneManager* smgr,
421                 Camera& camera, Client& client, LocalPlayer* player, Hud& hud,
422                 gui::IGUIEnvironment* guienv, std::vector<aabb3f> hilightboxes,
423                 const v2u32& screensize, video::SColor skycolor, bool show_hud)
424 {
425         TimeTaker timer("smgr");
426
427         bool draw_wield_tool = (show_hud &&
428                         (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
429                         camera.getCameraMode() < CAMERA_MODE_THIRD );
430
431         bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
432                         (camera.getCameraMode() != CAMERA_MODE_THIRD_FRONT));
433
434 #ifdef HAVE_TOUCHSCREENGUI
435         try {
436                 draw_crosshair = !g_settings->getBool("touchtarget");
437         }
438         catch(SettingNotFoundException) {}
439 #endif
440
441         std::string draw_mode = g_settings->get("3d_mode");
442
443         smgr->drawAll();
444
445         if (draw_mode == "anaglyph")
446         {
447                 draw_anaglyph_3d_mode(camera, show_hud, hud, hilightboxes, driver,
448                                 smgr, draw_wield_tool, client, guienv);
449                 draw_crosshair = false;
450         }
451         else if (draw_mode == "interlaced")
452         {
453                 draw_interlaced_3d_mode(camera, show_hud, hud, hilightboxes, driver,
454                                 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
455                 draw_crosshair = false;
456         }
457         else if (draw_mode == "sidebyside")
458         {
459                 draw_sidebyside_3d_mode(camera, show_hud, hud, hilightboxes, driver,
460                                 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
461                 show_hud = false;
462         }
463         else if (draw_mode == "topbottom")
464         {
465                 draw_top_bottom_3d_mode(camera, show_hud, hud, hilightboxes, driver,
466                                 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
467                 show_hud = false;
468         }
469         else {
470                 draw_plain(camera, show_hud, hud, hilightboxes, driver,
471                                 draw_wield_tool, client, guienv);
472         }
473
474         /*
475                 Post effects
476         */
477         {
478                 client.getEnv().getClientMap().renderPostFx(camera.getCameraMode());
479         }
480
481         //TODO how to make those 3d too
482         if (show_hud)
483         {
484                 if (draw_crosshair)
485                         hud.drawCrosshair();
486                 hud.drawHotbar(client.getPlayerItem());
487                 hud.drawLuaElements(camera.getOffset());
488         }
489
490         guienv->drawAll();
491
492         timer.stop(true);
493 }
494
495 /*
496         Draws a screen with a single text on it.
497         Text will be removed when the screen is drawn the next time.
498         Additionally, a progressbar can be drawn when percent is set between 0 and 100.
499 */
500 void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
501                 gui::IGUIEnvironment* guienv, float dtime, int percent, bool clouds )
502 {
503         video::IVideoDriver* driver    = device->getVideoDriver();
504         v2u32 screensize               = porting::getWindowSize();
505
506         v2s32 textsize(g_fontengine->getTextWidth(text), g_fontengine->getLineHeight());
507         v2s32 center(screensize.X / 2, screensize.Y / 2);
508         core::rect<s32> textrect(center - textsize / 2, center + textsize / 2);
509
510         gui::IGUIStaticText *guitext = guienv->addStaticText(
511                         text.c_str(), textrect, false, false);
512         guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
513
514         bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
515         if (cloud_menu_background)
516         {
517                 g_menuclouds->step(dtime*3);
518                 g_menuclouds->render();
519                 driver->beginScene(true, true, video::SColor(255, 140, 186, 250));
520                 g_menucloudsmgr->drawAll();
521         }
522         else
523                 driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
524
525         // draw progress bar
526         if ((percent >= 0) && (percent <= 100))
527         {
528                 v2s32 barsize(
529                                 // 342 is (approximately) 256/0.75 to keep bar on same size as
530                                 // before with default settings
531                                 342 * porting::getDisplayDensity() *
532                                 g_settings->getFloat("gui_scaling"),
533                                 g_fontengine->getTextHeight() * 2);
534
535                 core::rect<s32> barrect(center - barsize / 2, center + barsize / 2);
536                 driver->draw2DRectangle(video::SColor(255, 255, 255, 255),barrect, NULL); // border
537                 driver->draw2DRectangle(video::SColor(255, 64, 64, 64), core::rect<s32> (
538                                 barrect.UpperLeftCorner + 1,
539                                 barrect.LowerRightCorner-1), NULL); // black inside the bar
540                 driver->draw2DRectangle(video::SColor(255, 128, 128, 128), core::rect<s32> (
541                                 barrect.UpperLeftCorner + 1,
542                                 core::vector2d<s32>(
543                                                 barrect.LowerRightCorner.X -
544                                                 (barsize.X - 1) + percent * (barsize.X - 2) / 100,
545                                                 barrect.LowerRightCorner.Y - 1)), NULL); // the actual progress
546         }
547         guienv->drawAll();
548         driver->endScene();
549
550         guitext->remove();
551
552         //return guitext;
553 }