diff options
author | Vitaliy <silverunicorn2011@yandex.ru> | 2017-10-31 21:27:10 +0300 |
---|---|---|
committer | Loïc Blot <nerzhul@users.noreply.github.com> | 2017-10-31 19:27:10 +0100 |
commit | 28841961ba91b943b7478704181604fa3e24e81e (patch) | |
tree | 6485c0d4483c1c1e20eefd80510b7e9441f1b58a /src/client/render | |
parent | 65c5539035139428ee8354d7c96565fc392112d2 (diff) | |
download | minetest-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.cpp | 51 | ||||
-rw-r--r-- | src/client/render/anaglyph.h | 34 | ||||
-rw-r--r-- | src/client/render/core.cpp | 101 | ||||
-rw-r--r-- | src/client/render/core.h | 75 | ||||
-rw-r--r-- | src/client/render/factory.cpp | 45 | ||||
-rw-r--r-- | src/client/render/factory.h | 25 | ||||
-rw-r--r-- | src/client/render/interlaced.cpp | 116 | ||||
-rw-r--r-- | src/client/render/interlaced.h | 43 | ||||
-rw-r--r-- | src/client/render/pageflip.cpp | 55 | ||||
-rw-r--r-- | src/client/render/pageflip.h | 37 | ||||
-rw-r--r-- | src/client/render/plain.cpp | 76 | ||||
-rw-r--r-- | src/client/render/plain.h | 38 | ||||
-rw-r--r-- | src/client/render/sidebyside.cpp | 74 | ||||
-rw-r--r-- | src/client/render/sidebyside.h | 42 | ||||
-rw-r--r-- | src/client/render/stereo.cpp | 60 | ||||
-rw-r--r-- | src/client/render/stereo.h | 38 |
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); +}; |