3 Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
20 #include "drawscene.h"
23 #include "clientmap.h"
24 #include "util/timetaker.h"
25 #include "fontengine.h"
26 #include "guiscalingfilter.h"
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 )
40 /* preserve old setup*/
41 irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
42 irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
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();
52 irr::core::vector3df leftEye;
53 irr::core::matrix4 leftMove;
54 leftMove.setTranslation(
55 irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
57 leftEye = (startMatrix * leftMove).getTranslation();
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);
69 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
71 hud.drawSelectionMesh();
73 camera.drawWieldedTool(&leftMove);
79 irr::core::vector3df rightEye;
80 irr::core::matrix4 rightMove;
81 rightMove.setTranslation(
82 irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
84 rightEye = (startMatrix * rightMove).getTranslation();
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);
97 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
99 hud.drawSelectionMesh();
101 camera.drawWieldedTool(&rightMove);
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);
113 void init_texture(video::IVideoDriver* driver, const v2u32& screensize,
114 video::ITexture** texture, const char* name)
116 if (*texture != NULL)
118 driver->removeTexture(*texture);
120 *texture = driver->addRenderTargetTexture(
121 core::dimension2d<u32>(screensize.X, screensize.Y), name,
122 irr::video::ECF_A8R8G8B8);
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)
132 static video::ITexture* images[2] = { NULL, NULL };
133 static v2u32 last_screensize = v2u32(0, 0);
135 video::ITexture* image = NULL;
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;
148 driver->setRenderTarget(image, true, true,
149 irr::video::SColor(255,
150 skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
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();
159 //clear the depth buffer
160 driver->clearZBuffer();
161 camera.getCameraNode()->setPosition(eye_pos);
162 camera.getCameraNode()->setTarget(focusPoint);
165 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
168 hud.drawSelectionMesh();
170 camera.drawWieldedTool(&movement);
175 /* switch back to real renderer */
176 driver->setRenderTarget(0, true, true,
177 irr::video::SColor(0,
178 skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
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 )
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));
196 hud.drawHotbar(client.getPlayerItem());
197 hud.drawLuaElements(camera.getOffset());
202 driver->setRenderTarget(0, true, true,
203 irr::video::SColor(0,
204 skycolor.getRed(), skycolor.getGreen(), skycolor.getBlue()));
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 )
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();
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);
230 irr::core::vector3df rightEye;
231 irr::core::matrix4 rightMove;
232 rightMove.setTranslation(
233 irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
235 rightEye = (startMatrix * rightMove).getTranslation();
237 //clear the depth buffer
238 driver->clearZBuffer();
239 camera.getCameraNode()->setPosition(rightEye);
240 camera.getCameraNode()->setTarget(focusPoint);
243 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
246 hud.drawSelectionMesh();
248 camera.drawWieldedTool(&rightMove);
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),
256 driver->draw2DImage(left_image, irr::core::position2d<s32>(0, screensize.Y-i),
258 irr::core::rect<s32>(0, i,screensize.X, i+1), 0,
259 irr::video::SColor(255, 255, 255, 255),
264 camera.getCameraNode()->setPosition(oldPosition);
265 camera.getCameraNode()->setTarget(oldTarget);
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 )
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();
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);
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);
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));
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);
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);
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);
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);
320 camera.getCameraNode()->setPosition(oldPosition);
321 camera.getCameraNode()->setTarget(oldTarget);
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 )
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();
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);
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);
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));
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);
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);
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);
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);
376 camera.getCameraNode()->setPosition(oldPosition);
377 camera.getCameraNode()->setTarget(oldTarget);
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)
386 /* preserve old setup*/
387 irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
388 irr::core::vector3df oldTarget = camera.getCameraNode()->getTarget();
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();
397 driver->setRenderTarget(irr::video::ERT_STEREO_LEFT_BUFFER);
399 irr::core::vector3df leftEye;
400 irr::core::matrix4 leftMove;
401 leftMove.setTranslation(
402 irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
404 leftEye = (startMatrix * leftMove).getTranslation();
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);
411 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
414 hud.drawSelectionMesh();
416 camera.drawWieldedTool(&leftMove);
417 hud.drawHotbar(client.getPlayerItem());
418 hud.drawLuaElements(camera.getOffset());
424 driver->setRenderTarget(irr::video::ERT_STEREO_RIGHT_BUFFER);
426 irr::core::vector3df rightEye;
427 irr::core::matrix4 rightMove;
428 rightMove.setTranslation(
429 irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
431 rightEye = (startMatrix * rightMove).getTranslation();
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);
438 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
441 hud.drawSelectionMesh();
443 camera.drawWieldedTool(&rightMove);
444 hud.drawHotbar(client.getPlayerItem());
445 hud.drawLuaElements(camera.getOffset());
450 camera.getCameraNode()->setPosition(oldPosition);
451 camera.getCameraNode()->setTarget(oldTarget);
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)
458 driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
460 hud.drawSelectionMesh();
461 if (draw_wield_tool) {
462 camera.drawWieldedTool();
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)
473 TimeTaker timer("smgr");
475 bool draw_wield_tool = (show_hud &&
476 (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
477 camera.getCameraMode() < CAMERA_MODE_THIRD );
479 bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
480 (camera.getCameraMode() != CAMERA_MODE_THIRD_FRONT));
482 #ifdef HAVE_TOUCHSCREENGUI
484 draw_crosshair = !g_settings->getBool("touchtarget");
486 catch(SettingNotFoundException) {}
489 std::string draw_mode = g_settings->get("3d_mode");
493 if (draw_mode == "anaglyph")
495 draw_anaglyph_3d_mode(camera, show_hud, hud, driver,
496 smgr, draw_wield_tool, client, guienv);
497 draw_crosshair = false;
499 else if (draw_mode == "interlaced")
501 draw_interlaced_3d_mode(camera, show_hud, hud, driver,
502 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
503 draw_crosshair = false;
505 else if (draw_mode == "sidebyside")
507 draw_sidebyside_3d_mode(camera, show_hud, hud, driver,
508 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
511 else if (draw_mode == "topbottom")
513 draw_top_bottom_3d_mode(camera, show_hud, hud, driver,
514 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
517 else if (draw_mode == "pageflip")
519 draw_pageflip_3d_mode(camera, show_hud, hud, driver,
520 smgr, screensize, draw_wield_tool, client, guienv, skycolor);
521 draw_crosshair = false;
525 draw_plain(camera, show_hud, hud, driver,
526 draw_wield_tool, client, guienv);
533 client.getEnv().getClientMap().renderPostFx(camera.getCameraMode());
536 //TODO how to make those 3d too
541 hud.drawHotbar(client.getPlayerItem());
542 hud.drawLuaElements(camera.getOffset());
544 mapper.drawMinimap();
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.
557 void draw_load_screen(const std::wstring &text, IrrlichtDevice* device,
558 gui::IGUIEnvironment* guienv, float dtime, int percent, bool clouds )
560 video::IVideoDriver* driver = device->getVideoDriver();
561 v2u32 screensize = porting::getWindowSize();
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);
567 gui::IGUIStaticText *guitext = guienv->addStaticText(
568 text.c_str(), textrect, false, false);
569 guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
571 bool cloud_menu_background = clouds && g_settings->getBool("menu_clouds");
572 if (cloud_menu_background)
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();
580 driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
583 if ((percent >= 0) && (percent <= 100))
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);
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,
600 barrect.LowerRightCorner.X -
601 (barsize.X - 1) + percent * (barsize.X - 2) / 100,
602 barrect.LowerRightCorner.Y - 1)), NULL); // the actual progress