summaryrefslogtreecommitdiff
path: root/src/client/render
diff options
context:
space:
mode:
authorVitaliy <silverunicorn2011@yandex.ru>2017-10-31 21:27:10 +0300
committerLoïc Blot <nerzhul@users.noreply.github.com>2017-10-31 19:27:10 +0100
commit28841961ba91b943b7478704181604fa3e24e81e (patch)
tree6485c0d4483c1c1e20eefd80510b7e9441f1b58a /src/client/render
parent65c5539035139428ee8354d7c96565fc392112d2 (diff)
downloadminetest-28841961ba91b943b7478704181604fa3e24e81e.tar.gz
minetest-28841961ba91b943b7478704181604fa3e24e81e.tar.bz2
minetest-28841961ba91b943b7478704181604fa3e24e81e.zip
Rewrite rendering engine (#6253)
* Clean draw_*() arguments * Split rendering core * Add anaglyph 3D * Interlaced 3D * Drop obsolete methods
Diffstat (limited to 'src/client/render')
-rw-r--r--src/client/render/anaglyph.cpp51
-rw-r--r--src/client/render/anaglyph.h34
-rw-r--r--src/client/render/core.cpp101
-rw-r--r--src/client/render/core.h75
-rw-r--r--src/client/render/factory.cpp45
-rw-r--r--src/client/render/factory.h25
-rw-r--r--src/client/render/interlaced.cpp116
-rw-r--r--src/client/render/interlaced.h43
-rw-r--r--src/client/render/pageflip.cpp55
-rw-r--r--src/client/render/pageflip.h37
-rw-r--r--src/client/render/plain.cpp76
-rw-r--r--src/client/render/plain.h38
-rw-r--r--src/client/render/sidebyside.cpp74
-rw-r--r--src/client/render/sidebyside.h42
-rw-r--r--src/client/render/stereo.cpp60
-rw-r--r--src/client/render/stereo.h38
16 files changed, 910 insertions, 0 deletions
diff --git a/src/client/render/anaglyph.cpp b/src/client/render/anaglyph.cpp
new file mode 100644
index 000000000..1fad9e8d3
--- /dev/null
+++ b/src/client/render/anaglyph.cpp
@@ -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
index 000000000..6305efb90
--- /dev/null
+++ b/src/client/render/anaglyph.h
@@ -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
index 000000000..7a4230c84
--- /dev/null
+++ b/src/client/render/core.cpp
@@ -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
index 000000000..35def7f20
--- /dev/null
+++ b/src/client/render/core.h
@@ -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
index 000000000..c2c3f341e
--- /dev/null
+++ b/src/client/render/factory.cpp
@@ -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
index 000000000..c7c5cdc1e
--- /dev/null
+++ b/src/client/render/factory.h
@@ -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
index 000000000..ccd4e60cf
--- /dev/null
+++ b/src/client/render/interlaced.cpp
@@ -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
index 000000000..d0c1d9e62
--- /dev/null
+++ b/src/client/render/interlaced.h
@@ -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
index 000000000..8d6fa7423
--- /dev/null
+++ b/src/client/render/pageflip.cpp
@@ -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
index 000000000..ee4567ac4
--- /dev/null
+++ b/src/client/render/pageflip.h
@@ -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
index 000000000..94921245b
--- /dev/null
+++ b/src/client/render/plain.cpp
@@ -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
index 000000000..af9d7036b
--- /dev/null
+++ b/src/client/render/plain.h
@@ -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
index 000000000..2af09ee33
--- /dev/null
+++ b/src/client/render/sidebyside.cpp
@@ -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
index 000000000..70b2bdcf5
--- /dev/null
+++ b/src/client/render/sidebyside.h
@@ -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
index 000000000..eec9f8ced
--- /dev/null
+++ b/src/client/render/stereo.cpp
@@ -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
index 000000000..0b13de376
--- /dev/null
+++ b/src/client/render/stereo.h
@@ -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);
+};