Rewrite rendering engine (#6253)
authorVitaliy <silverunicorn2011@yandex.ru>
Tue, 31 Oct 2017 18:27:10 +0000 (21:27 +0300)
committerLoïc Blot <nerzhul@users.noreply.github.com>
Tue, 31 Oct 2017 18:27:10 +0000 (19:27 +0100)
* Clean draw_*() arguments

* Split rendering core

* Add anaglyph 3D

* Interlaced 3D

* Drop obsolete methods

25 files changed:
builtin/settingtypes.txt
client/shaders/3d_interlaced_merge/opengl_fragment.glsl [new file with mode: 0644]
client/shaders/3d_interlaced_merge/opengl_vertex.glsl [new file with mode: 0644]
minetest.conf.example
src/client/CMakeLists.txt
src/client/render/anaglyph.cpp [new file with mode: 0644]
src/client/render/anaglyph.h [new file with mode: 0644]
src/client/render/core.cpp [new file with mode: 0644]
src/client/render/core.h [new file with mode: 0644]
src/client/render/factory.cpp [new file with mode: 0644]
src/client/render/factory.h [new file with mode: 0644]
src/client/render/interlaced.cpp [new file with mode: 0644]
src/client/render/interlaced.h [new file with mode: 0644]
src/client/render/pageflip.cpp [new file with mode: 0644]
src/client/render/pageflip.h [new file with mode: 0644]
src/client/render/plain.cpp [new file with mode: 0644]
src/client/render/plain.h [new file with mode: 0644]
src/client/render/sidebyside.cpp [new file with mode: 0644]
src/client/render/sidebyside.h [new file with mode: 0644]
src/client/render/stereo.cpp [new file with mode: 0644]
src/client/render/stereo.h [new file with mode: 0644]
src/client/renderingengine.cpp
src/client/renderingengine.h
src/game.cpp
src/settings_translation_file.cpp

index ad88b97d0cc6d12cee904261ce2080c3f85a3824..dac135363d1cfb37ec0f15c5827295d44c20ee50 100644 (file)
@@ -608,6 +608,7 @@ fall_bobbing_amount (Fall bobbing factor) float 0.0
 #    -    topbottom: split screen top/bottom.
 #    -    sidebyside: split screen side by side.
 #    -    pageflip: quadbuffer based 3d.
+#    Note that the interlaced mode requires shaders to be enabled.
 3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,pageflip
 
 #    In-game chat console height, between 0.1 (10%) and 1.0 (100%).
diff --git a/client/shaders/3d_interlaced_merge/opengl_fragment.glsl b/client/shaders/3d_interlaced_merge/opengl_fragment.glsl
new file mode 100644 (file)
index 0000000..25945ad
--- /dev/null
@@ -0,0 +1,21 @@
+uniform sampler2D baseTexture;
+uniform sampler2D normalTexture;
+uniform sampler2D textureFlags;
+
+#define leftImage baseTexture
+#define rightImage normalTexture
+#define maskImage textureFlags
+
+void main(void)
+{
+       vec2 uv = gl_TexCoord[0].st;
+       vec4 left = texture2D(leftImage, uv).rgba;
+       vec4 right = texture2D(rightImage, uv).rgba;
+       vec4 mask = texture2D(maskImage, uv).rgba;
+       vec4 color;
+       if (mask.r > 0.5)
+               color = right;
+       else
+               color = left;
+       gl_FragColor = color;
+}
diff --git a/client/shaders/3d_interlaced_merge/opengl_vertex.glsl b/client/shaders/3d_interlaced_merge/opengl_vertex.glsl
new file mode 100644 (file)
index 0000000..4e0b2b1
--- /dev/null
@@ -0,0 +1,6 @@
+void main(void)
+{
+       gl_TexCoord[0] = gl_MultiTexCoord0;
+       gl_Position = gl_Vertex;
+       gl_FrontColor = gl_BackColor = gl_Color;
+}
index 684904a2281327b5927a26d4e70b5b721c6115a6..40adcf5032eedc4dc14004751841748855fcc128 100644 (file)
 #    -    topbottom: split screen top/bottom.
 #    -    sidebyside: split screen side by side.
 #    -    pageflip: quadbuffer based 3d.
+#    Note that the interlaced mode requires shaders to be enabled.
 #    type: enum values: none, anaglyph, interlaced, topbottom, sidebyside, pageflip
 # 3d_mode = none
 
index 4ba8fea5bc879dfefaebb95164d943b5d5d2e7d5..3cc6c03512b4634c2d46fd1f2bd9ee67df8deba9 100644 (file)
@@ -1,4 +1,12 @@
 set(client_SRCS
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/anaglyph.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/core.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/factory.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/interlaced.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/pageflip.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/plain.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/sidebyside.cpp
+       ${CMAKE_CURRENT_SOURCE_DIR}/render/stereo.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/renderingengine.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/clientlauncher.cpp
        ${CMAKE_CURRENT_SOURCE_DIR}/inputhandler.cpp
@@ -6,4 +14,3 @@ set(client_SRCS
        ${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp
        PARENT_SCOPE
 )
-
diff --git a/src/client/render/anaglyph.cpp b/src/client/render/anaglyph.cpp
new file mode 100644 (file)
index 0000000..1fad9e8
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "anaglyph.h"
+
+void RenderingCoreAnaglyph::drawAll()
+{
+       renderBothImages();
+       drawPostFx();
+       drawHUD();
+}
+
+void RenderingCoreAnaglyph::setupMaterial(int color_mask)
+{
+       video::SOverrideMaterial &mat = driver->getOverrideMaterial();
+       mat.Material.ColorMask = color_mask;
+       mat.EnableFlags = video::EMF_COLOR_MASK;
+       mat.EnablePasses = scene::ESNRP_SKY_BOX | scene::ESNRP_SOLID |
+                          scene::ESNRP_TRANSPARENT | scene::ESNRP_TRANSPARENT_EFFECT |
+                          scene::ESNRP_SHADOW;
+}
+
+void RenderingCoreAnaglyph::useEye(bool right)
+{
+       RenderingCoreStereo::useEye(right);
+       driver->clearZBuffer();
+       setupMaterial(right ? video::ECP_GREEN | video::ECP_BLUE : video::ECP_RED);
+}
+
+void RenderingCoreAnaglyph::resetEye()
+{
+       setupMaterial(video::ECP_ALL);
+       RenderingCoreStereo::resetEye();
+}
diff --git a/src/client/render/anaglyph.h b/src/client/render/anaglyph.h
new file mode 100644 (file)
index 0000000..6305efb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+#include "stereo.h"
+
+class RenderingCoreAnaglyph : public RenderingCoreStereo
+{
+protected:
+       void setupMaterial(int color_mask);
+       void useEye(bool right) override;
+       void resetEye() override;
+
+public:
+       using RenderingCoreStereo::RenderingCoreStereo;
+       void drawAll() override;
+};
diff --git a/src/client/render/core.cpp b/src/client/render/core.cpp
new file mode 100644 (file)
index 0000000..7a4230c
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "core.h"
+#include "camera.h"
+#include "client.h"
+#include "clientmap.h"
+#include "hud.h"
+#include "minimap.h"
+
+RenderingCore::RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud)
+    : device(_device), driver(device->getVideoDriver()), smgr(device->getSceneManager()),
+      guienv(device->getGUIEnvironment()), client(_client), camera(client->getCamera()),
+      mapper(client->getMinimap()), hud(_hud)
+{
+       screensize = driver->getScreenSize();
+       virtual_size = screensize;
+}
+
+RenderingCore::~RenderingCore()
+{
+       clearTextures();
+}
+
+void RenderingCore::initialize()
+{
+       // have to be called late as the VMT is not ready in the constructor:
+       initTextures();
+}
+
+void RenderingCore::updateScreenSize()
+{
+       virtual_size = screensize;
+       clearTextures();
+       initTextures();
+}
+
+void RenderingCore::draw(video::SColor _skycolor, bool _show_hud, bool _show_minimap,
+               bool _draw_wield_tool, bool _draw_crosshair)
+{
+       v2u32 ss = driver->getScreenSize();
+       if (screensize != ss) {
+               screensize = ss;
+               updateScreenSize();
+       }
+       skycolor = _skycolor;
+       show_hud = _show_hud;
+       show_minimap = _show_minimap;
+       draw_wield_tool = _draw_wield_tool;
+       draw_crosshair = _draw_crosshair;
+
+       beforeDraw();
+       drawAll();
+}
+
+void RenderingCore::draw3D()
+{
+       smgr->drawAll();
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
+       if (!show_hud)
+               return;
+       hud->drawSelectionMesh();
+       if (draw_wield_tool)
+               camera->drawWieldedTool();
+}
+
+void RenderingCore::drawHUD()
+{
+       if (show_hud) {
+               if (draw_crosshair)
+                       hud->drawCrosshair();
+               hud->drawHotbar(client->getPlayerItem());
+               hud->drawLuaElements(camera->getOffset());
+               camera->drawNametags();
+               if (mapper && show_minimap)
+                       mapper->drawMinimap();
+       }
+       guienv->drawAll();
+}
+
+void RenderingCore::drawPostFx()
+{
+       client->getEnv().getClientMap().renderPostFx(camera->getCameraMode());
+}
diff --git a/src/client/render/core.h b/src/client/render/core.h
new file mode 100644 (file)
index 0000000..35def7f
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+#include "irrlichttypes_extrabloated.h"
+
+class Camera;
+class Client;
+class Hud;
+class Minimap;
+
+class RenderingCore
+{
+protected:
+       v2u32 screensize;
+       v2u32 virtual_size;
+       video::SColor skycolor;
+       bool show_hud;
+       bool show_minimap;
+       bool draw_wield_tool;
+       bool draw_crosshair;
+
+       IrrlichtDevice *device;
+       video::IVideoDriver *driver;
+       scene::ISceneManager *smgr;
+       gui::IGUIEnvironment *guienv;
+
+       Client *client;
+       Camera *camera;
+       Minimap *mapper;
+       Hud *hud;
+
+       void updateScreenSize();
+       virtual void initTextures() {}
+       virtual void clearTextures() {}
+
+       virtual void beforeDraw() {}
+       virtual void drawAll() = 0;
+
+       void draw3D();
+       void drawHUD();
+       void drawPostFx();
+
+public:
+       RenderingCore(IrrlichtDevice *_device, Client *_client, Hud *_hud);
+       RenderingCore(const RenderingCore &) = delete;
+       RenderingCore(RenderingCore &&) = delete;
+       virtual ~RenderingCore();
+
+       RenderingCore &operator=(const RenderingCore &) = delete;
+       RenderingCore &operator=(RenderingCore &&) = delete;
+
+       void initialize();
+       void draw(video::SColor _skycolor, bool _show_hud, bool _show_minimap,
+                       bool _draw_wield_tool, bool _draw_crosshair);
+
+       inline v2u32 getVirtualSize() const { return virtual_size; }
+};
diff --git a/src/client/render/factory.cpp b/src/client/render/factory.cpp
new file mode 100644 (file)
index 0000000..c2c3f34
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "factory.h"
+#include <stdexcept>
+#include "plain.h"
+#include "anaglyph.h"
+#include "interlaced.h"
+#include "pageflip.h"
+#include "sidebyside.h"
+
+RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevice *device,
+               Client *client, Hud *hud)
+{
+       if (stereo_mode == "none")
+               return new RenderingCorePlain(device, client, hud);
+       if (stereo_mode == "anaglyph")
+               return new RenderingCoreAnaglyph(device, client, hud);
+       if (stereo_mode == "interlaced")
+               return new RenderingCoreInterlaced(device, client, hud);
+       if (stereo_mode == "pageflip")
+               return new RenderingCorePageflip(device, client, hud);
+       if (stereo_mode == "sidebyside")
+               return new RenderingCoreSideBySide(device, client, hud);
+       if (stereo_mode == "topbottom")
+               return new RenderingCoreSideBySide(device, client, hud, true);
+       throw std::invalid_argument("Invalid rendering mode: " + stereo_mode);
+}
diff --git a/src/client/render/factory.h b/src/client/render/factory.h
new file mode 100644 (file)
index 0000000..c7c5cdc
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <string>
+#include "core.h"
+
+RenderingCore *createRenderingCore(const std::string &stereo_mode, IrrlichtDevice *device,
+               Client *client, Hud *hud);
diff --git a/src/client/render/interlaced.cpp b/src/client/render/interlaced.cpp
new file mode 100644 (file)
index 0000000..ccd4e60
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "interlaced.h"
+#include "client.h"
+#include "shader.h"
+#include "client/tile.h"
+
+RenderingCoreInterlaced::RenderingCoreInterlaced(
+               IrrlichtDevice *_device, Client *_client, Hud *_hud)
+    : RenderingCoreStereo(_device, _client, _hud)
+{
+       initMaterial();
+}
+
+void RenderingCoreInterlaced::initMaterial()
+{
+       IShaderSource *s = client->getShaderSource();
+       mat.UseMipMaps = false;
+       mat.ZBuffer = false;
+       mat.ZWriteEnable = false;
+       u32 shader = s->getShader("3d_interlaced_merge", TILE_MATERIAL_BASIC, 0);
+       mat.MaterialType = s->getShaderInfo(shader).material;
+       for (int k = 0; k < 3; ++k) {
+               mat.TextureLayer[k].AnisotropicFilter = false;
+               mat.TextureLayer[k].BilinearFilter = false;
+               mat.TextureLayer[k].TrilinearFilter = false;
+               mat.TextureLayer[k].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
+               mat.TextureLayer[k].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
+       }
+}
+
+void RenderingCoreInterlaced::initTextures()
+{
+       v2u32 image_size{screensize.X, screensize.Y / 2};
+       left = driver->addRenderTargetTexture(
+                       image_size, "3d_render_left", video::ECF_A8R8G8B8);
+       right = driver->addRenderTargetTexture(
+                       image_size, "3d_render_right", video::ECF_A8R8G8B8);
+       mask = driver->addTexture(screensize, "3d_render_mask", video::ECF_A8R8G8B8);
+       initMask();
+       mat.TextureLayer[0].Texture = left;
+       mat.TextureLayer[1].Texture = right;
+       mat.TextureLayer[2].Texture = mask;
+}
+
+void RenderingCoreInterlaced::clearTextures()
+{
+       driver->removeTexture(left);
+       driver->removeTexture(right);
+       driver->removeTexture(mask);
+}
+
+void RenderingCoreInterlaced::initMask()
+{
+       u8 *data = reinterpret_cast<u8 *>(mask->lock());
+       for (u32 j = 0; j < screensize.Y; j++) {
+               u8 val = j % 2 ? 0xff : 0x00;
+               memset(data, val, 4 * screensize.X);
+               data += 4 * screensize.X;
+       }
+       mask->unlock();
+}
+
+void RenderingCoreInterlaced::drawAll()
+{
+       renderBothImages();
+       merge();
+       drawHUD();
+}
+
+void RenderingCoreInterlaced::merge()
+{
+       static const video::S3DVertex vertices[4] = {
+                       video::S3DVertex(1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
+                                       video::SColor(255, 0, 255, 255), 1.0, 0.0),
+                       video::S3DVertex(-1.0, -1.0, 0.0, 0.0, 0.0, -1.0,
+                                       video::SColor(255, 255, 0, 255), 0.0, 0.0),
+                       video::S3DVertex(-1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
+                                       video::SColor(255, 255, 255, 0), 0.0, 1.0),
+                       video::S3DVertex(1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
+                                       video::SColor(255, 255, 255, 255), 1.0, 1.0),
+       };
+       static const u16 indices[6] = {0, 1, 2, 2, 3, 0};
+       driver->setMaterial(mat);
+       driver->drawVertexPrimitiveList(&vertices, 4, &indices, 2);
+}
+
+void RenderingCoreInterlaced::useEye(bool _right)
+{
+       driver->setRenderTarget(_right ? right : left, true, true, skycolor);
+       RenderingCoreStereo::useEye(_right);
+}
+
+void RenderingCoreInterlaced::resetEye()
+{
+       driver->setRenderTarget(nullptr, false, false, skycolor);
+       RenderingCoreStereo::resetEye();
+}
diff --git a/src/client/render/interlaced.h b/src/client/render/interlaced.h
new file mode 100644 (file)
index 0000000..d0c1d9e
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+#include "stereo.h"
+
+class RenderingCoreInterlaced : public RenderingCoreStereo
+{
+protected:
+       video::ITexture *left = nullptr;
+       video::ITexture *right = nullptr;
+       video::ITexture *mask = nullptr;
+       video::SMaterial mat;
+
+       void initMaterial();
+       void initTextures() override;
+       void clearTextures() override;
+       void initMask();
+       void useEye(bool right) override;
+       void resetEye() override;
+       void merge();
+
+public:
+       RenderingCoreInterlaced(IrrlichtDevice *_device, Client *_client, Hud *_hud);
+       void drawAll() override;
+};
diff --git a/src/client/render/pageflip.cpp b/src/client/render/pageflip.cpp
new file mode 100644 (file)
index 0000000..8d6fa74
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "pageflip.h"
+
+void RenderingCorePageflip::initTextures()
+{
+       hud = driver->addRenderTargetTexture(
+                       screensize, "3d_render_hud", video::ECF_A8R8G8B8);
+}
+
+void RenderingCorePageflip::clearTextures()
+{
+       driver->removeTexture(hud);
+}
+
+void RenderingCorePageflip::drawAll()
+{
+       driver->setRenderTarget(hud, true, true, video::SColor(0, 0, 0, 0));
+       drawHUD();
+       driver->setRenderTarget(nullptr, false, false, skycolor);
+       renderBothImages();
+}
+
+void RenderingCorePageflip::useEye(bool _right)
+{
+       driver->setRenderTarget(_right ? video::ERT_STEREO_RIGHT_BUFFER
+                                      : video::ERT_STEREO_LEFT_BUFFER,
+                       true, true, skycolor);
+       RenderingCoreStereo::useEye(_right);
+}
+
+void RenderingCorePageflip::resetEye()
+{
+       driver->draw2DImage(hud, v2s32(0, 0));
+       driver->setRenderTarget(video::ERT_FRAME_BUFFER, false, false, skycolor);
+       RenderingCoreStereo::resetEye();
+}
diff --git a/src/client/render/pageflip.h b/src/client/render/pageflip.h
new file mode 100644 (file)
index 0000000..ee4567a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+#include "stereo.h"
+
+class RenderingCorePageflip : public RenderingCoreStereo
+{
+protected:
+       video::ITexture *hud = nullptr;
+
+       void initTextures() override;
+       void clearTextures() override;
+       void useEye(bool right) override;
+       void resetEye() override;
+
+public:
+       using RenderingCoreStereo::RenderingCoreStereo;
+       void drawAll() override;
+};
diff --git a/src/client/render/plain.cpp b/src/client/render/plain.cpp
new file mode 100644 (file)
index 0000000..9492124
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "plain.h"
+#include "settings.h"
+
+inline u32 scaledown(u32 coef, u32 size)
+{
+       return (size + coef - 1) / coef;
+}
+
+RenderingCorePlain::RenderingCorePlain(
+               IrrlichtDevice *_device, Client *_client, Hud *_hud)
+    : RenderingCore(_device, _client, _hud)
+{
+       scale = g_settings->getU16("undersampling");
+}
+
+void RenderingCorePlain::initTextures()
+{
+       if (!scale)
+               return;
+       v2u32 size{scaledown(scale, screensize.X), scaledown(scale, screensize.Y)};
+       lowres = driver->addRenderTargetTexture(
+                       size, "render_lowres", video::ECF_A8R8G8B8);
+}
+
+void RenderingCorePlain::clearTextures()
+{
+       if (!scale)
+               return;
+       driver->removeTexture(lowres);
+}
+
+void RenderingCorePlain::beforeDraw()
+{
+       if (!scale)
+               return;
+       driver->setRenderTarget(lowres, true, true, skycolor);
+}
+
+void RenderingCorePlain::upscale()
+{
+       if (!scale)
+               return;
+       driver->setRenderTarget(0, true, true);
+       v2u32 size{scaledown(scale, screensize.X), scaledown(scale, screensize.Y)};
+       v2u32 dest_size{scale * size.X, scale * size.Y};
+       driver->draw2DImage(lowres, core::rect<s32>(0, 0, dest_size.X, dest_size.Y),
+                       core::rect<s32>(0, 0, size.X, size.Y));
+}
+
+void RenderingCorePlain::drawAll()
+{
+       draw3D();
+       drawPostFx();
+       upscale();
+       drawHUD();
+}
diff --git a/src/client/render/plain.h b/src/client/render/plain.h
new file mode 100644 (file)
index 0000000..af9d703
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+#include "core.h"
+
+class RenderingCorePlain : public RenderingCore
+{
+protected:
+       int scale = 0;
+       video::ITexture *lowres = nullptr;
+
+       void initTextures() override;
+       void clearTextures() override;
+       void beforeDraw() override;
+       void upscale();
+
+public:
+       RenderingCorePlain(IrrlichtDevice *_device, Client *_client, Hud *_hud);
+       void drawAll() override;
+};
diff --git a/src/client/render/sidebyside.cpp b/src/client/render/sidebyside.cpp
new file mode 100644 (file)
index 0000000..2af09ee
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "sidebyside.h"
+#include <ICameraSceneNode.h>
+#include "hud.h"
+
+RenderingCoreSideBySide::RenderingCoreSideBySide(
+               IrrlichtDevice *_device, Client *_client, Hud *_hud, bool _horizontal)
+    : RenderingCoreStereo(_device, _client, _hud), horizontal(_horizontal)
+{
+}
+
+void RenderingCoreSideBySide::initTextures()
+{
+       if (horizontal) {
+               image_size = {screensize.X, screensize.Y / 2};
+               rpos = v2s32(0, screensize.Y / 2);
+       } else {
+               image_size = {screensize.X / 2, screensize.Y};
+               rpos = v2s32(screensize.X / 2, 0);
+       }
+       virtual_size = image_size;
+       left = driver->addRenderTargetTexture(
+                       image_size, "3d_render_left", video::ECF_A8R8G8B8);
+       right = driver->addRenderTargetTexture(
+                       image_size, "3d_render_right", video::ECF_A8R8G8B8);
+}
+
+void RenderingCoreSideBySide::clearTextures()
+{
+       driver->removeTexture(left);
+       driver->removeTexture(right);
+}
+
+void RenderingCoreSideBySide::drawAll()
+{
+       driver->OnResize(image_size); // HACK to make GUI smaller
+       renderBothImages();
+       driver->OnResize(screensize);
+       driver->draw2DImage(left, {});
+       driver->draw2DImage(right, rpos);
+}
+
+void RenderingCoreSideBySide::useEye(bool _right)
+{
+       driver->setRenderTarget(_right ? right : left, true, true, skycolor);
+       RenderingCoreStereo::useEye(_right);
+}
+
+void RenderingCoreSideBySide::resetEye()
+{
+       hud->resizeHotbar();
+       drawHUD();
+       driver->setRenderTarget(nullptr, false, false, skycolor);
+       RenderingCoreStereo::resetEye();
+}
diff --git a/src/client/render/sidebyside.h b/src/client/render/sidebyside.h
new file mode 100644 (file)
index 0000000..70b2bdc
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+#include "stereo.h"
+
+class RenderingCoreSideBySide : public RenderingCoreStereo
+{
+protected:
+       video::ITexture *left = nullptr;
+       video::ITexture *right = nullptr;
+       bool horizontal = false;
+       core::dimension2du image_size;
+       v2s32 rpos;
+
+       void initTextures() override;
+       void clearTextures() override;
+       void useEye(bool right) override;
+       void resetEye() override;
+
+public:
+       RenderingCoreSideBySide(IrrlichtDevice *_device, Client *_client, Hud *_hud,
+                       bool _horizontal = false);
+       void drawAll() override;
+};
diff --git a/src/client/render/stereo.cpp b/src/client/render/stereo.cpp
new file mode 100644 (file)
index 0000000..eec9f8c
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "stereo.h"
+#include "camera.h"
+#include "constants.h"
+#include "settings.h"
+
+RenderingCoreStereo::RenderingCoreStereo(
+               IrrlichtDevice *_device, Client *_client, Hud *_hud)
+    : RenderingCore(_device, _client, _hud)
+{
+       eye_offset = BS * g_settings->getFloat("3d_paralax_strength");
+}
+
+void RenderingCoreStereo::beforeDraw()
+{
+       cam = camera->getCameraNode();
+       base_transform = cam->getRelativeTransformation();
+}
+
+void RenderingCoreStereo::useEye(bool right)
+{
+       core::matrix4 move;
+       move.setTranslation(
+                       core::vector3df(right ? eye_offset : -eye_offset, 0.0f, 0.0f));
+       cam->setPosition((base_transform * move).getTranslation());
+}
+
+void RenderingCoreStereo::resetEye()
+{
+       cam->setPosition(base_transform.getTranslation());
+}
+
+void RenderingCoreStereo::renderBothImages()
+{
+       useEye(false);
+       draw3D();
+       resetEye();
+       useEye(true);
+       draw3D();
+       resetEye();
+}
diff --git a/src/client/render/stereo.h b/src/client/render/stereo.h
new file mode 100644 (file)
index 0000000..0b13de3
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2017 numzero, Lobachesky Vitaly <numzer0@yandex.ru>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#pragma once
+#include "core.h"
+
+class RenderingCoreStereo : public RenderingCore
+{
+protected:
+       scene::ICameraSceneNode *cam;
+       core::matrix4 base_transform;
+       float eye_offset;
+
+       void beforeDraw() override;
+       virtual void useEye(bool right);
+       virtual void resetEye();
+       void renderBothImages();
+
+public:
+       RenderingCoreStereo(IrrlichtDevice *_device, Client *_client, Hud *_hud);
+};
index a57388596790ce6528c5f82549f3fa66e6bb2e95..f9da178b9ad90f2eca68824baebadb800646f894 100644 (file)
@@ -31,6 +31,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "minimap.h"
 #include "clientmap.h"
 #include "renderingengine.h"
+#include "render/core.h"
+#include "render/factory.h"
 #include "inputhandler.h"
 #include "gettext.h"
 
@@ -102,17 +104,22 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
 #endif
 
        m_device = createDeviceEx(params);
+       driver = m_device->getVideoDriver();
+
        s_singleton = this;
 }
 
 RenderingEngine::~RenderingEngine()
 {
+       core.reset();
        m_device->drop();
        s_singleton = nullptr;
 }
 
 v2u32 RenderingEngine::getWindowSize() const
 {
+       if (core)
+               return core->getVirtualSize();
        return m_device->getVideoDriver()->getScreenSize();
 }
 
@@ -121,11 +128,6 @@ void RenderingEngine::setResizable(bool resize)
        m_device->setResizable(resize);
 }
 
-video::IVideoDriver *RenderingEngine::getVideoDriver()
-{
-       return m_device->getVideoDriver();
-}
-
 bool RenderingEngine::print_video_modes()
 {
        IrrlichtDevice *nulldevice;
@@ -213,11 +215,10 @@ bool RenderingEngine::setWindowIcon()
                                                               "-xorg-icon-128.png");
 #endif
 #elif defined(_WIN32)
-       const video::SExposedVideoData exposedData =
-                       m_device->getVideoDriver()->getExposedVideoData();
+       const video::SExposedVideoData exposedData = driver->getExposedVideoData();
        HWND hWnd; // Window handle
 
-       switch (m_device->getVideoDriver()->getDriverType()) {
+       switch (driver->getDriverType()) {
        case video::EDT_DIRECT3D8:
                hWnd = reinterpret_cast<HWND>(exposedData.D3D8.HWnd);
                break;
@@ -253,14 +254,12 @@ bool RenderingEngine::setXorgWindowIconFromPath(const std::string &icon_file)
 {
 #ifdef XORG_USED
 
-       video::IVideoDriver *v_driver = m_device->getVideoDriver();
-
        video::IImageLoader *image_loader = NULL;
-       u32 cnt = v_driver->getImageLoaderCount();
+       u32 cnt = driver->getImageLoaderCount();
        for (u32 i = 0; i < cnt; i++) {
-               if (v_driver->getImageLoader(i)->isALoadableFileExtension(
+               if (driver->getImageLoader(i)->isALoadableFileExtension(
                                    icon_file.c_str())) {
-                       image_loader = v_driver->getImageLoader(i);
+                       image_loader = driver->getImageLoader(i);
                        break;
                }
        }
@@ -313,7 +312,7 @@ bool RenderingEngine::setXorgWindowIconFromPath(const std::string &icon_file)
        img->drop();
        icon_f->drop();
 
-       const video::SExposedVideoData &video_data = v_driver->getExposedVideoData();
+       const video::SExposedVideoData &video_data = driver->getExposedVideoData();
 
        Display *x11_dpl = (Display *)video_data.OpenGLLinux.X11Display;
 
@@ -442,558 +441,22 @@ std::vector<irr::video::E_DRIVER_TYPE> RenderingEngine::getSupportedVideoDrivers
        return drivers;
 }
 
-void RenderingEngine::_draw_scene(Camera *camera, Client *client, LocalPlayer *player,
-               Hud *hud, Minimap *mapper, gui::IGUIEnvironment *guienv,
-               const v2u32 &screensize, const video::SColor &skycolor, bool show_hud,
-               bool show_minimap)
+void RenderingEngine::_initialize(Client *client, Hud *hud)
 {
-       bool draw_wield_tool =
-                       (show_hud && (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
-                                       camera->getCameraMode() < CAMERA_MODE_THIRD);
-
-       bool draw_crosshair = ((player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
-                              (camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
-
-#ifdef HAVE_TOUCHSCREENGUI
-       try {
-               draw_crosshair = !g_settings->getBool("touchtarget");
-       } catch (SettingNotFoundException) {
-       }
-#endif
-
        const std::string &draw_mode = g_settings->get("3d_mode");
-
-       if (draw_mode == "anaglyph") {
-               draw_anaglyph_3d_mode(
-                               camera, show_hud, hud, draw_wield_tool, client, guienv);
-               draw_crosshair = false;
-       } else if (draw_mode == "interlaced") {
-               draw_interlaced_3d_mode(camera, show_hud, hud, screensize,
-                               draw_wield_tool, client, guienv, skycolor);
-               draw_crosshair = false;
-       } else if (draw_mode == "sidebyside") {
-               draw_sidebyside_3d_mode(camera, show_hud, hud, screensize,
-                               draw_wield_tool, client, guienv, skycolor);
-               show_hud = false;
-       } else if (draw_mode == "topbottom") {
-               draw_top_bottom_3d_mode(camera, show_hud, hud, screensize,
-                               draw_wield_tool, client, guienv, skycolor);
-               show_hud = false;
-       } else if (draw_mode == "pageflip") {
-               draw_pageflip_3d_mode(camera, show_hud, hud, screensize, draw_wield_tool,
-                               client, guienv, skycolor);
-               draw_crosshair = false;
-               show_hud = false;
-       } else {
-               draw_plain(camera, show_hud, hud, screensize, draw_wield_tool, client,
-                               guienv, skycolor);
-       }
-
-       /*
-               Post effects
-       */
-       client->getEnv().getClientMap().renderPostFx(camera->getCameraMode());
-
-       // TODO how to make those 3d too
-       if (show_hud) {
-               if (draw_crosshair)
-                       hud->drawCrosshair();
-
-               hud->drawHotbar(client->getPlayerItem());
-               hud->drawLuaElements(camera->getOffset());
-               camera->drawNametags();
-
-               if (mapper && show_minimap)
-                       mapper->drawMinimap();
-       }
-
-       guienv->drawAll();
+       core.reset(createRenderingCore(draw_mode, m_device, client, hud));
+       core->initialize();
 }
 
-void RenderingEngine::draw_anaglyph_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-               bool draw_wield_tool, Client *client, gui::IGUIEnvironment *guienv)
+void RenderingEngine::_finalize()
 {
-
-       /* preserve old setup*/
-       irr::core::vector3df oldPosition = camera->getCameraNode()->getPosition();
-       irr::core::vector3df oldTarget = camera->getCameraNode()->getTarget();
-
-       irr::core::matrix4 startMatrix =
-                       camera->getCameraNode()->getAbsoluteTransformation();
-       irr::core::vector3df focusPoint =
-                       (camera->getCameraNode()->getTarget() -
-                                       camera->getCameraNode()->getAbsolutePosition())
-                                       .setLength(1) +
-                       camera->getCameraNode()->getAbsolutePosition();
-
-       // Left eye...
-       irr::core::vector3df leftEye;
-       irr::core::matrix4 leftMove;
-       leftMove.setTranslation(irr::core::vector3df(
-                       -g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
-       leftEye = (startMatrix * leftMove).getTranslation();
-
-       // clear the depth buffer, and color
-       getVideoDriver()->beginScene(true, true, irr::video::SColor(0, 200, 200, 255));
-       getVideoDriver()->getOverrideMaterial().Material.ColorMask = irr::video::ECP_RED;
-       getVideoDriver()->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
-       getVideoDriver()->getOverrideMaterial().EnablePasses =
-                       irr::scene::ESNRP_SKY_BOX + irr::scene::ESNRP_SOLID +
-                       irr::scene::ESNRP_TRANSPARENT +
-                       irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
-       camera->getCameraNode()->setPosition(leftEye);
-       camera->getCameraNode()->setTarget(focusPoint);
-       get_scene_manager()->drawAll();
-       getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-       if (show_hud) {
-               hud->drawSelectionMesh();
-               if (draw_wield_tool)
-                       camera->drawWieldedTool(&leftMove);
-       }
-
-       guienv->drawAll();
-
-       // Right eye...
-       irr::core::vector3df rightEye;
-       irr::core::matrix4 rightMove;
-       rightMove.setTranslation(irr::core::vector3df(
-                       g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
-       rightEye = (startMatrix * rightMove).getTranslation();
-
-       // clear the depth buffer
-       getVideoDriver()->clearZBuffer();
-       getVideoDriver()->getOverrideMaterial().Material.ColorMask =
-                       irr::video::ECP_GREEN + irr::video::ECP_BLUE;
-       getVideoDriver()->getOverrideMaterial().EnableFlags = irr::video::EMF_COLOR_MASK;
-       getVideoDriver()->getOverrideMaterial().EnablePasses =
-                       irr::scene::ESNRP_SKY_BOX + irr::scene::ESNRP_SOLID +
-                       irr::scene::ESNRP_TRANSPARENT +
-                       irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
-       camera->getCameraNode()->setPosition(rightEye);
-       camera->getCameraNode()->setTarget(focusPoint);
-       get_scene_manager()->drawAll();
-       getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-       if (show_hud) {
-               hud->drawSelectionMesh();
-               if (draw_wield_tool)
-                       camera->drawWieldedTool(&rightMove);
-       }
-
-       guienv->drawAll();
-
-       getVideoDriver()->getOverrideMaterial().Material.ColorMask = irr::video::ECP_ALL;
-       getVideoDriver()->getOverrideMaterial().EnableFlags = 0;
-       getVideoDriver()->getOverrideMaterial().EnablePasses = 0;
-       camera->getCameraNode()->setPosition(oldPosition);
-       camera->getCameraNode()->setTarget(oldTarget);
-}
-
-void RenderingEngine::init_texture(
-               const v2u32 &screensize, video::ITexture **texture, const char *name)
-{
-       if (*texture) {
-               getVideoDriver()->removeTexture(*texture);
-       }
-       *texture = getVideoDriver()->addRenderTargetTexture(
-                       core::dimension2d<u32>(screensize.X, screensize.Y), name,
-                       irr::video::ECF_A8R8G8B8);
-}
-
-video::ITexture *RenderingEngine::draw_image(const v2u32 &screensize, parallax_sign psign,
-               const irr::core::matrix4 &startMatrix,
-               const irr::core::vector3df &focusPoint, bool show_hud, Camera *camera,
-               Hud *hud, bool draw_wield_tool, Client *client,
-               gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
-{
-       static video::ITexture *images[2] = {NULL, NULL};
-       static v2u32 last_screensize = v2u32(0, 0);
-
-       video::ITexture *image = NULL;
-
-       if (screensize != last_screensize) {
-               init_texture(screensize, &images[1], "mt_drawimage_img1");
-               init_texture(screensize, &images[0], "mt_drawimage_img2");
-               last_screensize = screensize;
-       }
-
-       if (psign == RIGHT)
-               image = images[1];
-       else
-               image = images[0];
-
-       getVideoDriver()->setRenderTarget(image, true, true,
-                       irr::video::SColor(255, skycolor.getRed(), skycolor.getGreen(),
-                                       skycolor.getBlue()));
-
-       irr::core::vector3df eye_pos;
-       irr::core::matrix4 movement;
-       movement.setTranslation(irr::core::vector3df(
-                       (int)psign * g_settings->getFloat("3d_paralax_strength"), 0.0f,
-                       0.0f));
-       eye_pos = (startMatrix * movement).getTranslation();
-
-       // clear the depth buffer
-       getVideoDriver()->clearZBuffer();
-       camera->getCameraNode()->setPosition(eye_pos);
-       camera->getCameraNode()->setTarget(focusPoint);
-       get_scene_manager()->drawAll();
-
-       getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-
-       if (show_hud) {
-               hud->drawSelectionMesh();
-               if (draw_wield_tool)
-                       camera->drawWieldedTool(&movement);
-       }
-
-       guienv->drawAll();
-
-       /* switch back to real renderer */
-       getVideoDriver()->setRenderTarget(0, true, true,
-                       irr::video::SColor(0, skycolor.getRed(), skycolor.getGreen(),
-                                       skycolor.getBlue()));
-
-       return image;
+       core.reset();
 }
 
-video::ITexture *RenderingEngine::draw_hud(const v2u32 &screensize, bool show_hud,
-               Hud *hud, Client *client, bool draw_crosshair,
-               const video::SColor &skycolor, gui::IGUIEnvironment *guienv,
-               Camera *camera)
+void RenderingEngine::_draw_scene(video::SColor skycolor, bool show_hud,
+               bool show_minimap, bool draw_wield_tool, bool draw_crosshair)
 {
-       static video::ITexture *image = nullptr;
-       init_texture(screensize, &image, "mt_drawimage_hud");
-       getVideoDriver()->setRenderTarget(
-                       image, true, true, irr::video::SColor(255, 0, 0, 0));
-
-       if (show_hud) {
-               if (draw_crosshair)
-                       hud->drawCrosshair();
-               hud->drawHotbar(client->getPlayerItem());
-               hud->drawLuaElements(camera->getOffset());
-               camera->drawNametags();
-               guienv->drawAll();
-       }
-
-       getVideoDriver()->setRenderTarget(0, true, true,
-                       irr::video::SColor(0, skycolor.getRed(), skycolor.getGreen(),
-                                       skycolor.getBlue()));
-
-       return image;
-}
-
-void RenderingEngine::draw_interlaced_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-               const v2u32 &screensize, bool draw_wield_tool, Client *client,
-               gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
-{
-       /* save current info */
-       irr::core::vector3df oldPosition = camera->getCameraNode()->getPosition();
-       irr::core::vector3df oldTarget = camera->getCameraNode()->getTarget();
-       irr::core::matrix4 startMatrix =
-                       camera->getCameraNode()->getAbsoluteTransformation();
-       irr::core::vector3df focusPoint =
-                       (camera->getCameraNode()->getTarget() -
-                                       camera->getCameraNode()->getAbsolutePosition())
-                                       .setLength(1) +
-                       camera->getCameraNode()->getAbsolutePosition();
-
-       /* create left view */
-       video::ITexture *left_image = draw_image(screensize, LEFT, startMatrix,
-                       focusPoint, show_hud, camera, hud, draw_wield_tool, client,
-                       guienv, skycolor);
-
-       // Right eye...
-       irr::core::vector3df rightEye;
-       irr::core::matrix4 rightMove;
-       rightMove.setTranslation(irr::core::vector3df(
-                       g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
-       rightEye = (startMatrix * rightMove).getTranslation();
-
-       // clear the depth buffer
-       getVideoDriver()->clearZBuffer();
-       camera->getCameraNode()->setPosition(rightEye);
-       camera->getCameraNode()->setTarget(focusPoint);
-       get_scene_manager()->drawAll();
-
-       getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-
-       if (show_hud) {
-               hud->drawSelectionMesh();
-               if (draw_wield_tool)
-                       camera->drawWieldedTool(&rightMove);
-       }
-       guienv->drawAll();
-
-       for (unsigned int i = 0; i < screensize.Y; i += 2) {
-#if (IRRLICHT_VERSION_MAJOR >= 1) && (IRRLICHT_VERSION_MINOR >= 8)
-               getVideoDriver()->draw2DImage(left_image,
-                               irr::core::position2d<s32>(0, i),
-#else
-               getVideoDriver()->draw2DImage(left_image,
-                               irr::core::position2d<s32>(0, screensize.Y - i),
-#endif
-                               irr::core::rect<s32>(0, i, screensize.X, i + 1), 0,
-                               irr::video::SColor(255, 255, 255, 255), false);
-       }
-
-       /* cleanup */
-       camera->getCameraNode()->setPosition(oldPosition);
-       camera->getCameraNode()->setTarget(oldTarget);
-}
-
-void RenderingEngine::draw_sidebyside_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-               const v2u32 &screensize, bool draw_wield_tool, Client *client,
-               gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
-{
-       /* save current info */
-       irr::core::vector3df oldPosition = camera->getCameraNode()->getPosition();
-       irr::core::vector3df oldTarget = camera->getCameraNode()->getTarget();
-       irr::core::matrix4 startMatrix =
-                       camera->getCameraNode()->getAbsoluteTransformation();
-       irr::core::vector3df focusPoint =
-                       (camera->getCameraNode()->getTarget() -
-                                       camera->getCameraNode()->getAbsolutePosition())
-                                       .setLength(1) +
-                       camera->getCameraNode()->getAbsolutePosition();
-
-       /* create left view */
-       video::ITexture *left_image = draw_image(screensize, LEFT, startMatrix,
-                       focusPoint, show_hud, camera, hud, draw_wield_tool, client,
-                       guienv, skycolor);
-
-       /* create right view */
-       video::ITexture *right_image = draw_image(screensize, RIGHT, startMatrix,
-                       focusPoint, show_hud, camera, hud, draw_wield_tool, client,
-                       guienv, skycolor);
-
-       /* create hud overlay */
-       video::ITexture *hudtexture = draw_hud(screensize, show_hud, hud, client, false,
-                       skycolor, guienv, camera);
-       getVideoDriver()->makeColorKeyTexture(
-                       hudtexture, irr::video::SColor(255, 0, 0, 0));
-       // makeColorKeyTexture mirrors texture so we do it twice to get it right again
-       getVideoDriver()->makeColorKeyTexture(
-                       hudtexture, irr::video::SColor(255, 0, 0, 0));
-
-       draw2DImageFilterScaled(getVideoDriver(), left_image,
-                       irr::core::rect<s32>(0, 0, screensize.X / 2, screensize.Y),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       false);
-
-       draw2DImageFilterScaled(getVideoDriver(), hudtexture,
-                       irr::core::rect<s32>(0, 0, screensize.X / 2, screensize.Y),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       true);
-
-       draw2DImageFilterScaled(getVideoDriver(), right_image,
-                       irr::core::rect<s32>(
-                                       screensize.X / 2, 0, screensize.X, screensize.Y),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       false);
-
-       draw2DImageFilterScaled(getVideoDriver(), hudtexture,
-                       irr::core::rect<s32>(
-                                       screensize.X / 2, 0, screensize.X, screensize.Y),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       true);
-
-       left_image = nullptr;
-       right_image = nullptr;
-
-       /* cleanup */
-       camera->getCameraNode()->setPosition(oldPosition);
-       camera->getCameraNode()->setTarget(oldTarget);
-}
-
-void RenderingEngine::draw_top_bottom_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-               const v2u32 &screensize, bool draw_wield_tool, Client *client,
-               gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
-{
-       /* save current info */
-       irr::core::vector3df oldPosition = camera->getCameraNode()->getPosition();
-       irr::core::vector3df oldTarget = camera->getCameraNode()->getTarget();
-       irr::core::matrix4 startMatrix =
-                       camera->getCameraNode()->getAbsoluteTransformation();
-       irr::core::vector3df focusPoint =
-                       (camera->getCameraNode()->getTarget() -
-                                       camera->getCameraNode()->getAbsolutePosition())
-                                       .setLength(1) +
-                       camera->getCameraNode()->getAbsolutePosition();
-
-       /* create left view */
-       video::ITexture *left_image = draw_image(screensize, LEFT, startMatrix,
-                       focusPoint, show_hud, camera, hud, draw_wield_tool, client,
-                       guienv, skycolor);
-
-       /* create right view */
-       video::ITexture *right_image = draw_image(screensize, RIGHT, startMatrix,
-                       focusPoint, show_hud, camera, hud, draw_wield_tool, client,
-                       guienv, skycolor);
-
-       /* create hud overlay */
-       video::ITexture *hudtexture = draw_hud(screensize, show_hud, hud, client, false,
-                       skycolor, guienv, camera);
-       getVideoDriver()->makeColorKeyTexture(
-                       hudtexture, irr::video::SColor(255, 0, 0, 0));
-       // makeColorKeyTexture mirrors texture so we do it twice to get it right again
-       getVideoDriver()->makeColorKeyTexture(
-                       hudtexture, irr::video::SColor(255, 0, 0, 0));
-
-       draw2DImageFilterScaled(getVideoDriver(), left_image,
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y / 2),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       false);
-
-       draw2DImageFilterScaled(getVideoDriver(), hudtexture,
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y / 2),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       true);
-
-       draw2DImageFilterScaled(getVideoDriver(), right_image,
-                       irr::core::rect<s32>(
-                                       0, screensize.Y / 2, screensize.X, screensize.Y),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       false);
-
-       draw2DImageFilterScaled(getVideoDriver(), hudtexture,
-                       irr::core::rect<s32>(
-                                       0, screensize.Y / 2, screensize.X, screensize.Y),
-                       irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
-                       true);
-
-       left_image = NULL;
-       right_image = NULL;
-
-       /* cleanup */
-       camera->getCameraNode()->setPosition(oldPosition);
-       camera->getCameraNode()->setTarget(oldTarget);
-}
-
-void RenderingEngine::draw_pageflip_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-               const v2u32 &screensize, bool draw_wield_tool, Client *client,
-               gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
-{
-#if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR > 8
-       errorstream << "Pageflip 3D mode is not supported"
-                   << " with your Irrlicht version!" << std::endl;
-#else
-       /* preserve old setup*/
-       irr::core::vector3df oldPosition = camera->getCameraNode()->getPosition();
-       irr::core::vector3df oldTarget = camera->getCameraNode()->getTarget();
-
-       irr::core::matrix4 startMatrix =
-                       camera->getCameraNode()->getAbsoluteTransformation();
-       irr::core::vector3df focusPoint =
-                       (camera->getCameraNode()->getTarget() -
-                                       camera->getCameraNode()->getAbsolutePosition())
-                                       .setLength(1) +
-                       camera->getCameraNode()->getAbsolutePosition();
-
-       // Left eye...
-       getVideoDriver()->setRenderTarget(irr::video::ERT_STEREO_LEFT_BUFFER);
-
-       irr::core::vector3df leftEye;
-       irr::core::matrix4 leftMove;
-       leftMove.setTranslation(irr::core::vector3df(
-                       -g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
-       leftEye = (startMatrix * leftMove).getTranslation();
-
-       // clear the depth buffer, and color
-       getVideoDriver()->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
-       camera->getCameraNode()->setPosition(leftEye);
-       camera->getCameraNode()->setTarget(focusPoint);
-       get_scene_manager()->drawAll();
-       getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-
-       if (show_hud) {
-               hud->drawSelectionMesh();
-               if (draw_wield_tool)
-                       camera->drawWieldedTool(&leftMove);
-               hud->drawHotbar(client->getPlayerItem());
-               hud->drawLuaElements(camera->getOffset());
-               camera->drawNametags();
-       }
-
-       guienv->drawAll();
-
-       // Right eye...
-       getVideoDriver()->setRenderTarget(irr::video::ERT_STEREO_RIGHT_BUFFER);
-
-       irr::core::vector3df rightEye;
-       irr::core::matrix4 rightMove;
-       rightMove.setTranslation(irr::core::vector3df(
-                       g_settings->getFloat("3d_paralax_strength"), 0.0f, 0.0f));
-       rightEye = (startMatrix * rightMove).getTranslation();
-
-       // clear the depth buffer, and color
-       getVideoDriver()->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
-       camera->getCameraNode()->setPosition(rightEye);
-       camera->getCameraNode()->setTarget(focusPoint);
-       get_scene_manager()->drawAll();
-       getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-
-       if (show_hud) {
-               hud->drawSelectionMesh();
-               if (draw_wield_tool)
-                       camera->drawWieldedTool(&rightMove);
-               hud->drawHotbar(client->getPlayerItem());
-               hud->drawLuaElements(camera->getOffset());
-               camera->drawNametags();
-       }
-
-       guienv->drawAll();
-
-       camera->getCameraNode()->setPosition(oldPosition);
-       camera->getCameraNode()->setTarget(oldTarget);
-#endif
-}
-
-// returns (size / coef), rounded upwards
-inline int scaledown(int coef, int size)
-{
-       return (size + coef - 1) / coef;
-}
-
-void RenderingEngine::draw_plain(Camera *camera, bool show_hud, Hud *hud,
-               const v2u32 &screensize, bool draw_wield_tool, Client *client,
-               gui::IGUIEnvironment *guienv, const video::SColor &skycolor)
-{
-       // Undersampling-specific stuff
-       static video::ITexture *image = NULL;
-       static v2u32 last_pixelated_size = v2u32(0, 0);
-       static thread_local int undersampling = g_settings->getU16("undersampling");
-       v2u32 pixelated_size;
-       v2u32 dest_size;
-       if (undersampling > 0) {
-               pixelated_size = v2u32(scaledown(undersampling, screensize.X),
-                               scaledown(undersampling, screensize.Y));
-               dest_size = v2u32(undersampling * pixelated_size.X,
-                               undersampling * pixelated_size.Y);
-               if (pixelated_size != last_pixelated_size) {
-                       init_texture(pixelated_size, &image, "mt_drawimage_img1");
-                       last_pixelated_size = pixelated_size;
-               }
-               getVideoDriver()->setRenderTarget(image, true, true, skycolor);
-       }
-
-       // Render
-       get_scene_manager()->drawAll();
-       getVideoDriver()->setTransform(video::ETS_WORLD, core::IdentityMatrix);
-       if (show_hud) {
-               hud->drawSelectionMesh();
-               if (draw_wield_tool) {
-                       camera->drawWieldedTool();
-               }
-       }
-
-       // Upscale lowres render
-       if (undersampling > 0) {
-               getVideoDriver()->setRenderTarget(0, true, true);
-               getVideoDriver()->draw2DImage(image,
-                               irr::core::rect<s32>(0, 0, dest_size.X, dest_size.Y),
-                               irr::core::rect<s32>(0, 0, pixelated_size.X,
-                                               pixelated_size.Y));
-       }
+       core->draw(skycolor, show_hud, show_minimap, draw_wield_tool, draw_crosshair);
 }
 
 const char *RenderingEngine::getVideoDriverName(irr::video::E_DRIVER_TYPE type)
index 40fbaa87dc97de5860886c277003a4c82a1734d9..ac6b6926c5b694f4724a3471c56bf2f4a0a1ede0 100644 (file)
@@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #pragma once
 
 #include <vector>
+#include <memory>
 #include <string>
 #include "irrlichttypes_extrabloated.h"
 #include "debug.h"
@@ -32,6 +33,8 @@ class LocalPlayer;
 class Hud;
 class Minimap;
 
+class RenderingCore;
+
 class RenderingEngine
 {
 public:
@@ -41,7 +44,7 @@ public:
        v2u32 getWindowSize() const;
        void setResizable(bool resize);
 
-       video::IVideoDriver *getVideoDriver();
+       video::IVideoDriver *getVideoDriver() { return driver; }
 
        static const char *getVideoDriverName(irr::video::E_DRIVER_TYPE type);
        static const char *getVideoDriverFriendlyName(irr::video::E_DRIVER_TYPE type);
@@ -107,15 +110,20 @@ public:
                                text, guienv, tsrc, dtime, percent, clouds);
        }
 
-       inline static void draw_scene(Camera *camera, Client *client, LocalPlayer *player,
-                       Hud *hud, Minimap *mapper, gui::IGUIEnvironment *guienv,
-                       const v2u32 &screensize, const video::SColor &skycolor,
-                       bool show_hud, bool show_minimap)
+       inline static void draw_scene(video::SColor skycolor, bool show_hud,
+                       bool show_minimap, bool draw_wield_tool, bool draw_crosshair)
+       {
+               s_singleton->_draw_scene(skycolor, show_hud, show_minimap,
+                               draw_wield_tool, draw_crosshair);
+       }
+
+       inline static void initialize(Client *client, Hud *hud)
        {
-               s_singleton->_draw_scene(camera, client, player, hud, mapper, guienv,
-                               screensize, skycolor, show_hud, show_minimap);
+               s_singleton->_initialize(client, hud);
        }
 
+       inline static void finalize() { s_singleton->_finalize(); }
+
        static bool run()
        {
                sanity_check(s_singleton && s_singleton->m_device);
@@ -126,60 +134,19 @@ public:
        static std::vector<irr::video::E_DRIVER_TYPE> getSupportedVideoDrivers();
 
 private:
-       enum parallax_sign
-       {
-               LEFT = -1,
-               RIGHT = 1,
-               EYECOUNT = 2
-       };
-
        void _draw_load_screen(const std::wstring &text, gui::IGUIEnvironment *guienv,
                        ITextureSource *tsrc, float dtime = 0, int percent = 0,
                        bool clouds = true);
 
-       void _draw_scene(Camera *camera, Client *client, LocalPlayer *player, Hud *hud,
-                       Minimap *mapper, gui::IGUIEnvironment *guienv,
-                       const v2u32 &screensize, const video::SColor &skycolor,
-                       bool show_hud, bool show_minimap);
-
-       void draw_anaglyph_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-                       bool draw_wield_tool, Client *client,
-                       gui::IGUIEnvironment *guienv);
-
-       void draw_interlaced_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-                       const v2u32 &screensize, bool draw_wield_tool, Client *client,
-                       gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
-
-       void draw_sidebyside_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-                       const v2u32 &screensize, bool draw_wield_tool, Client *client,
-                       gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
-
-       void draw_top_bottom_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-                       const v2u32 &screensize, bool draw_wield_tool, Client *client,
-                       gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
-
-       void draw_pageflip_3d_mode(Camera *camera, bool show_hud, Hud *hud,
-                       const v2u32 &screensize, bool draw_wield_tool, Client *client,
-                       gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
-
-       void draw_plain(Camera *camera, bool show_hud, Hud *hud, const v2u32 &screensize,
-                       bool draw_wield_tool, Client *client,
-                       gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
-
-       void init_texture(const v2u32 &screensize, video::ITexture **texture,
-                       const char *name);
+       void _draw_scene(video::SColor skycolor, bool show_hud, bool show_minimap,
+                       bool draw_wield_tool, bool draw_crosshair);
 
-       video::ITexture *draw_image(const v2u32 &screensize, parallax_sign psign,
-                       const irr::core::matrix4 &startMatrix,
-                       const irr::core::vector3df &focusPoint, bool show_hud,
-                       Camera *camera, Hud *hud, bool draw_wield_tool, Client *client,
-                       gui::IGUIEnvironment *guienv, const video::SColor &skycolor);
+       void _initialize(Client *client, Hud *hud);
 
-       video::ITexture *draw_hud(const v2u32 &screensize, bool show_hud, Hud *hud,
-                       Client *client, bool draw_crosshair,
-                       const video::SColor &skycolor, gui::IGUIEnvironment *guienv,
-                       Camera *camera);
+       void _finalize();
 
+       std::unique_ptr<RenderingCore> core;
        irr::IrrlichtDevice *m_device = nullptr;
+       irr::video::IVideoDriver *driver;
        static RenderingEngine *s_singleton;
 };
index fd3914356225f59a3f3204aea55105f37c064a9b..200de2c5942ad0519dc700a0b5a11b2f26917e5e 100644 (file)
@@ -1656,6 +1656,8 @@ bool Game::startup(bool *kill,
        if (!createClient(playername, password, address, port))
                return false;
 
+       RenderingEngine::initialize(client, hud);
+
        return true;
 }
 
@@ -1745,6 +1747,7 @@ void Game::run()
 
 void Game::shutdown()
 {
+       RenderingEngine::finalize();
 #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR <= 8
        if (g_settings->get("3d_mode") == "pageflip") {
                driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS);
@@ -4339,9 +4342,20 @@ void Game::updateFrame(ProfilerGraph *graph, RunStats *stats, f32 dtime,
        TimeTaker tt_draw("mainloop: draw");
        driver->beginScene(true, true, skycolor);
 
-       RenderingEngine::draw_scene(camera, client, player, hud, mapper,
-                       guienv, screensize, skycolor, flags.show_hud,
-                       flags.show_minimap);
+       bool draw_wield_tool = (flags.show_hud &&
+                       (player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE) &&
+                       (camera->getCameraMode() == CAMERA_MODE_FIRST));
+       bool draw_crosshair = (
+                       (player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE) &&
+                       (camera->getCameraMode() != CAMERA_MODE_THIRD_FRONT));
+#ifdef HAVE_TOUCHSCREENGUI
+       try {
+               draw_crosshair = !g_settings->getBool("touchtarget");
+       } catch (SettingNotFoundException) {
+       }
+#endif
+       RenderingEngine::draw_scene(skycolor, flags.show_hud, flags.show_minimap,
+                       draw_wield_tool, draw_crosshair);
 
        /*
                Profiler graph
@@ -4402,7 +4416,7 @@ inline static const char *yawToDirectionString(int yaw)
 
 void Game::updateGui(const RunStats &stats, f32 dtime, const CameraOrientation &cam)
 {
-       v2u32 screensize = driver->getScreenSize();
+       v2u32 screensize = RenderingEngine::get_instance()->getWindowSize();
        LocalPlayer *player = client->getEnv().getLocalPlayer();
        v3f player_position = player->getPosition();
 
index e72b0a9f033c1a333e896ef37294f6811c12a19b..ec0c0db6ba01ca5697f53498142a742faee27fab 100644 (file)
@@ -286,7 +286,7 @@ fake_function() {
        gettext("Fall bobbing factor");
        gettext("Multiplier for fall bobbing.\nFor example: 0 for no view bobbing; 1.0 for normal; 2.0 for double.");
        gettext("3D mode");
-       gettext("3D support.\nCurrently supported:\n-    none: no 3d output.\n-    anaglyph: cyan/magenta color 3d.\n-    interlaced: odd/even line based polarisation screen support.\n-    topbottom: split screen top/bottom.\n-    sidebyside: split screen side by side.\n-    pageflip: quadbuffer based 3d.");
+       gettext("3D support.\nCurrently supported:\n-    none: no 3d output.\n-    anaglyph: cyan/magenta color 3d.\n-    interlaced: odd/even line based polarisation screen support.\n-    topbottom: split screen top/bottom.\n-    sidebyside: split screen side by side.\n-    pageflip: quadbuffer based 3d.\nNote that the interlaced mode requires shaders to be enabled.");
        gettext("Console height");
        gettext("In-game chat console height, between 0.1 (10%) and 1.0 (100%).");
        gettext("Console color");