Navigation Menu

Skip to content

Commit

Permalink
Rewrite rendering engine (#6253)
Browse files Browse the repository at this point in the history
* Clean draw_*() arguments

* Split rendering core

* Add anaglyph 3D

* Interlaced 3D

* Drop obsolete methods
  • Loading branch information
numberZero authored and nerzhul committed Oct 31, 2017
1 parent 65c5539 commit 2884196
Show file tree
Hide file tree
Showing 25 changed files with 1,008 additions and 618 deletions.
1 change: 1 addition & 0 deletions builtin/settingtypes.txt
Expand Up @@ -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%).
Expand Down
21 changes: 21 additions & 0 deletions client/shaders/3d_interlaced_merge/opengl_fragment.glsl
@@ -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;
}
6 changes: 6 additions & 0 deletions client/shaders/3d_interlaced_merge/opengl_vertex.glsl
@@ -0,0 +1,6 @@
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = gl_Vertex;
gl_FrontColor = gl_BackColor = gl_Color;
}
1 change: 1 addition & 0 deletions minetest.conf.example
Expand Up @@ -700,6 +700,7 @@
# - 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

Expand Down
9 changes: 8 additions & 1 deletion src/client/CMakeLists.txt
@@ -1,9 +1,16 @@
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
${CMAKE_CURRENT_SOURCE_DIR}/tile.cpp
${CMAKE_CURRENT_SOURCE_DIR}/joystick_controller.cpp
PARENT_SCOPE
)

51 changes: 51 additions & 0 deletions 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();
}
34 changes: 34 additions & 0 deletions 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;
};
101 changes: 101 additions & 0 deletions 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());
}
75 changes: 75 additions & 0 deletions 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; }
};
45 changes: 45 additions & 0 deletions 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);
}
25 changes: 25 additions & 0 deletions 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);

0 comments on commit 2884196

Please sign in to comment.