Interlaced 3D
parent
de7ff3f9db
commit
3ac96d2670
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
void main(void)
|
||||
{
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_Position = gl_Vertex;
|
||||
gl_FrontColor = gl_BackColor = gl_Color;
|
||||
}
|
|
@ -11,6 +11,11 @@ RenderingCore::RenderingCore(irr::IrrlichtDevice *_device) :
|
|||
device(_device),
|
||||
driver(device->getVideoDriver()),
|
||||
smgr(device->getSceneManager())
|
||||
{
|
||||
screensize = driver->getScreenSize();
|
||||
}
|
||||
|
||||
void RenderingCore::update_screen_size()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -26,7 +31,10 @@ void RenderingCore::setup(Camera *_camera, Client *_client, LocalPlayer *_player
|
|||
mapper = _mapper;
|
||||
guienv = _guienv;
|
||||
|
||||
screensize = _screensize;
|
||||
if (screensize != _screensize) {
|
||||
screensize = _screensize;
|
||||
update_screen_size();
|
||||
}
|
||||
skycolor = _skycolor;
|
||||
show_hud = _show_hud;
|
||||
show_minimap = _show_minimap;
|
||||
|
@ -94,17 +102,32 @@ RenderingCoreStereo::RenderingCoreStereo(irr::IrrlichtDevice *_device) :
|
|||
parallax_strength = g_settings->getFloat("3d_paralax_strength");
|
||||
}
|
||||
|
||||
void RenderingCoreStereo::use_eye(Eye eye)
|
||||
void RenderingCoreStereo::pre_draw()
|
||||
{
|
||||
irr::scene::ICameraSceneNode *cam = camera->getCameraNode();
|
||||
irr::core::matrix4 transform = cam->getRelativeTransformation();
|
||||
irr::core::matrix4 move;
|
||||
move.setTranslation(irr::core::vector3df(static_cast<int>(eye) * parallax_strength, 0.0f, 0.0f));
|
||||
cam->setPosition((transform * move).getTranslation());
|
||||
cam = camera->getCameraNode();
|
||||
base_transform = cam->getRelativeTransformation();
|
||||
}
|
||||
|
||||
void RenderingCoreStereo::use_default()
|
||||
void RenderingCoreStereo::use_eye(bool right)
|
||||
{
|
||||
irr::core::matrix4 move;
|
||||
move.setTranslation(irr::core::vector3df(right ? parallax_strength : -parallax_strength, 0.0f, 0.0f));
|
||||
cam->setPosition((base_transform * move).getTranslation());
|
||||
}
|
||||
|
||||
void RenderingCoreStereo::reset_eye()
|
||||
{
|
||||
cam->setPosition(base_transform.getTranslation());
|
||||
}
|
||||
|
||||
void RenderingCoreStereo::draw_two()
|
||||
{
|
||||
use_eye(false);
|
||||
draw_3d();
|
||||
reset_eye();
|
||||
use_eye(true);
|
||||
draw_3d();
|
||||
reset_eye();
|
||||
}
|
||||
|
||||
RenderingCoreAnaglyph::RenderingCoreAnaglyph(irr::IrrlichtDevice *_device) :
|
||||
|
@ -114,28 +137,18 @@ RenderingCoreAnaglyph::RenderingCoreAnaglyph(irr::IrrlichtDevice *_device) :
|
|||
|
||||
void RenderingCoreAnaglyph::draw()
|
||||
{
|
||||
use_eye(Eye::Left);
|
||||
draw_3d();
|
||||
use_eye(Eye::Right);
|
||||
draw_3d();
|
||||
use_default();
|
||||
pre_draw();
|
||||
draw_two();
|
||||
draw_last_fx();
|
||||
draw_hud();
|
||||
}
|
||||
|
||||
void RenderingCoreAnaglyph::use_eye(Eye eye)
|
||||
void RenderingCoreAnaglyph::use_eye(bool right)
|
||||
{
|
||||
RenderingCoreStereo::use_eye(eye);
|
||||
RenderingCoreStereo::use_eye(right);
|
||||
driver->clearZBuffer();
|
||||
irr::video::SOverrideMaterial &mat = driver->getOverrideMaterial();
|
||||
switch (eye) {
|
||||
case Eye::Left:
|
||||
mat.Material.ColorMask = irr::video::ECP_RED;
|
||||
break;
|
||||
case Eye::Right:
|
||||
mat.Material.ColorMask = irr::video::ECP_GREEN | irr::video::ECP_BLUE;
|
||||
break;
|
||||
}
|
||||
mat.Material.ColorMask = right ? irr::video::ECP_GREEN | irr::video::ECP_BLUE : irr::video::ECP_RED;
|
||||
mat.EnableFlags = irr::video::EMF_COLOR_MASK;
|
||||
mat.EnablePasses =
|
||||
irr::scene::ESNRP_SKY_BOX | irr::scene::ESNRP_SOLID |
|
||||
|
@ -143,9 +156,8 @@ void RenderingCoreAnaglyph::use_eye(Eye eye)
|
|||
irr::scene::ESNRP_TRANSPARENT_EFFECT | irr::scene::ESNRP_SHADOW;
|
||||
}
|
||||
|
||||
void RenderingCoreAnaglyph::use_default()
|
||||
void RenderingCoreAnaglyph::reset_eye()
|
||||
{
|
||||
RenderingCoreStereo::use_default();
|
||||
irr::video::SOverrideMaterial &mat = driver->getOverrideMaterial();
|
||||
mat.Material.ColorMask = irr::video::ECP_ALL;
|
||||
mat.EnableFlags = irr::video::EMF_COLOR_MASK;
|
||||
|
@ -155,20 +167,220 @@ void RenderingCoreAnaglyph::use_default()
|
|||
irr::scene::ESNRP_TRANSPARENT_EFFECT + irr::scene::ESNRP_SHADOW;
|
||||
}
|
||||
|
||||
RenderingCoreDouble::RenderingCoreDouble(irr::IrrlichtDevice *_device, RenderingCoreDouble::Mode _mode) :
|
||||
RenderingCoreSideBySide::RenderingCoreSideBySide(irr::IrrlichtDevice *_device) :
|
||||
RenderingCoreStereo(_device)
|
||||
{
|
||||
init_textures();
|
||||
}
|
||||
|
||||
void RenderingCoreDouble::draw()
|
||||
RenderingCoreSideBySide::~RenderingCoreSideBySide()
|
||||
{
|
||||
clear_textures();
|
||||
}
|
||||
|
||||
void RenderingCoreSideBySide::init_textures()
|
||||
{
|
||||
image_size = v2u32(screensize.X / 2, screensize.Y);
|
||||
left = driver->addRenderTargetTexture(image_size, "3d_render_left", irr::video::ECF_A8R8G8B8);
|
||||
right = driver->addRenderTargetTexture(image_size, "3d_render_right", irr::video::ECF_A8R8G8B8);
|
||||
hud = driver->addRenderTargetTexture(screensize, "3d_render_hud", irr::video::ECF_A8R8G8B8);
|
||||
}
|
||||
|
||||
void RenderingCoreSideBySide::clear_textures()
|
||||
{
|
||||
driver->removeTexture(left);
|
||||
driver->removeTexture(right);
|
||||
driver->removeTexture(hud);
|
||||
}
|
||||
|
||||
void RenderingCoreSideBySide::update_screen_size()
|
||||
{
|
||||
clear_textures();
|
||||
init_textures();
|
||||
}
|
||||
|
||||
void RenderingCoreSideBySide::draw()
|
||||
{
|
||||
pre_draw();
|
||||
draw_two();
|
||||
driver->setRenderTarget(hud, true, true, video::SColor(0, 0, 0, 0));
|
||||
draw_hud();
|
||||
driver->setRenderTarget(nullptr, false, false, skycolor);
|
||||
|
||||
driver->draw2DImage(left, v2s32(0, 0));
|
||||
driver->draw2DImage(right, v2s32(screensize.X / 2, 0));
|
||||
|
||||
driver->draw2DImage(hud,
|
||||
irr::core::rect<s32>(0, 0, screensize.X / 2, screensize.Y),
|
||||
irr::core::rect<s32>(0, 0, screensize.X, screensize.Y), 0, 0,
|
||||
true);
|
||||
|
||||
driver->draw2DImage(hud,
|
||||
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);
|
||||
}
|
||||
|
||||
void RenderingCoreSideBySide::use_eye(bool _right)
|
||||
{
|
||||
driver->setRenderTarget(_right ? right : left, true, true, skycolor);
|
||||
RenderingCoreStereo::use_eye(_right);
|
||||
}
|
||||
|
||||
void RenderingCoreSideBySide::reset_eye()
|
||||
{
|
||||
driver->setRenderTarget(nullptr, false, false, skycolor);
|
||||
RenderingCoreStereo::reset_eye();
|
||||
}
|
||||
|
||||
RenderingCorePageflip::RenderingCorePageflip(irr::IrrlichtDevice *_device) :
|
||||
RenderingCoreStereo(_device)
|
||||
{
|
||||
init_textures();
|
||||
}
|
||||
|
||||
RenderingCorePageflip::~RenderingCorePageflip()
|
||||
{
|
||||
clear_textures();
|
||||
}
|
||||
|
||||
void RenderingCorePageflip::init_textures()
|
||||
{
|
||||
hud = driver->addRenderTargetTexture(screensize, "3d_render_hud", irr::video::ECF_A8R8G8B8);
|
||||
}
|
||||
|
||||
void RenderingCorePageflip::clear_textures()
|
||||
{
|
||||
driver->removeTexture(hud);
|
||||
}
|
||||
|
||||
void RenderingCorePageflip::update_screen_size()
|
||||
{
|
||||
clear_textures();
|
||||
init_textures();
|
||||
}
|
||||
|
||||
void RenderingCorePageflip::draw()
|
||||
{
|
||||
pre_draw();
|
||||
driver->setRenderTarget(hud, true, true, video::SColor(0, 0, 0, 0));
|
||||
draw_hud();
|
||||
driver->setRenderTarget(nullptr, false, false, skycolor);
|
||||
draw_two();
|
||||
}
|
||||
|
||||
void RenderingCorePageflip::use_eye(bool _right)
|
||||
{
|
||||
driver->setRenderTarget(
|
||||
_right ? irr::video::ERT_STEREO_RIGHT_BUFFER : irr::video::ERT_STEREO_LEFT_BUFFER,
|
||||
true, true, skycolor);
|
||||
RenderingCoreStereo::use_eye(_right);
|
||||
}
|
||||
|
||||
void RenderingCorePageflip::reset_eye()
|
||||
{
|
||||
driver->draw2DImage(hud, v2s32(0, 0));
|
||||
driver->setRenderTarget(irr::video::ERT_FRAME_BUFFER, false, false, skycolor);
|
||||
RenderingCoreStereo::reset_eye();
|
||||
}
|
||||
|
||||
RenderingCoreInterlaced::RenderingCoreInterlaced(irr::IrrlichtDevice *_device) :
|
||||
RenderingCoreStereo(_device)
|
||||
{
|
||||
mat.MaterialType = (video::E_MATERIAL_TYPE)0;
|
||||
init_textures();
|
||||
}
|
||||
|
||||
RenderingCoreInterlaced::~RenderingCoreInterlaced()
|
||||
{
|
||||
clear_textures();
|
||||
}
|
||||
|
||||
void RenderingCoreInterlaced::init_material()
|
||||
{
|
||||
if (mat.MaterialType)
|
||||
return;
|
||||
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 = irr::video::ETC_CLAMP_TO_EDGE;
|
||||
mat.TextureLayer[k].TextureWrapV = irr::video::ETC_CLAMP_TO_EDGE;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderingCoreInterlaced::init_textures()
|
||||
{
|
||||
image_size = v2u32(screensize.X, screensize.Y / 2);
|
||||
left = driver->addRenderTargetTexture(image_size, "3d_render_left", irr::video::ECF_A8R8G8B8);
|
||||
right = driver->addRenderTargetTexture(image_size, "3d_render_right", irr::video::ECF_A8R8G8B8);
|
||||
mask = driver->addTexture(screensize, "3d_render_mask", irr::video::ECF_A8R8G8B8);
|
||||
init_mask();
|
||||
mat.TextureLayer[0].Texture = left;
|
||||
mat.TextureLayer[1].Texture = right;
|
||||
mat.TextureLayer[2].Texture = mask;
|
||||
}
|
||||
|
||||
void RenderingCoreInterlaced::clear_textures()
|
||||
{
|
||||
driver->removeTexture(left);
|
||||
driver->removeTexture(right);
|
||||
driver->removeTexture(mask);
|
||||
}
|
||||
|
||||
void RenderingCoreInterlaced::init_mask()
|
||||
{
|
||||
u8 *data = reinterpret_cast<u8 *>(mask->lock());
|
||||
for (unsigned 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::update_screen_size()
|
||||
{
|
||||
clear_textures();
|
||||
init_textures();
|
||||
}
|
||||
|
||||
void RenderingCoreInterlaced::draw()
|
||||
{
|
||||
pre_draw();
|
||||
draw_two();
|
||||
merge();
|
||||
draw_hud();
|
||||
}
|
||||
|
||||
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 };
|
||||
init_material();
|
||||
driver->setMaterial(mat);
|
||||
driver->drawVertexPrimitiveList(&vertices, 4, &indices, 2);
|
||||
}
|
||||
|
||||
void RenderingCoreInterlaced::use_eye(bool _right)
|
||||
{
|
||||
driver->setRenderTarget(_right ? right : left, true, true, skycolor);
|
||||
RenderingCoreStereo::use_eye(_right);
|
||||
}
|
||||
|
||||
void RenderingCoreInterlaced::reset_eye()
|
||||
{
|
||||
driver->setRenderTarget(nullptr, false, false, skycolor);
|
||||
RenderingCoreStereo::reset_eye();
|
||||
}
|
||||
|
|
|
@ -48,11 +48,13 @@ protected:
|
|||
irr::scene::ISceneManager *smgr;
|
||||
irr::gui::IGUIEnvironment *guienv;
|
||||
|
||||
virtual void update_screen_size();
|
||||
|
||||
public:
|
||||
RenderingCore(irr::IrrlichtDevice *_device);
|
||||
RenderingCore(const RenderingCore &) = delete;
|
||||
RenderingCore(RenderingCore &&) = delete;
|
||||
~RenderingCore() = default;
|
||||
virtual ~RenderingCore() = default;
|
||||
|
||||
RenderingCore &operator= (const RenderingCore &) = delete;
|
||||
RenderingCore &operator= (RenderingCore &&) = delete;
|
||||
|
@ -78,45 +80,91 @@ public:
|
|||
class RenderingCoreStereo: public RenderingCore
|
||||
{
|
||||
protected:
|
||||
irr::scene::ICameraSceneNode *cam;
|
||||
irr::core::matrix4 base_transform;
|
||||
float parallax_strength;
|
||||
|
||||
void pre_draw();
|
||||
virtual void use_eye(bool right);
|
||||
virtual void reset_eye();
|
||||
void draw_two();
|
||||
|
||||
public:
|
||||
enum class Eye
|
||||
{
|
||||
Left = -1,
|
||||
Right = 1,
|
||||
};
|
||||
RenderingCoreStereo(irr::IrrlichtDevice *_device);
|
||||
virtual void use_eye(Eye eye);
|
||||
virtual void use_default();
|
||||
};
|
||||
|
||||
class RenderingCoreAnaglyph: public RenderingCoreStereo
|
||||
{
|
||||
protected:
|
||||
void use_eye(bool right) override;
|
||||
void reset_eye() override;
|
||||
|
||||
public:
|
||||
RenderingCoreAnaglyph(irr::IrrlichtDevice *_device);
|
||||
void draw() override;
|
||||
void use_eye(Eye eye) override;
|
||||
void use_default() override;
|
||||
};
|
||||
|
||||
class RenderingCoreDouble: public RenderingCoreStereo
|
||||
class RenderingCoreSideBySide: public RenderingCoreStereo
|
||||
{
|
||||
public:
|
||||
enum class Mode
|
||||
{
|
||||
SideBySide,
|
||||
TopBottom,
|
||||
Pageflip
|
||||
};
|
||||
protected:
|
||||
v2u32 image_size;
|
||||
video::ITexture *left = nullptr;
|
||||
video::ITexture *right = nullptr;
|
||||
video::ITexture *hud = nullptr;
|
||||
|
||||
RenderingCoreDouble(irr::IrrlichtDevice *_device, Mode _mode);
|
||||
void init_textures();
|
||||
void clear_textures();
|
||||
|
||||
void update_screen_size() override;
|
||||
void use_eye(bool right) override;
|
||||
void reset_eye() override;
|
||||
|
||||
public:
|
||||
RenderingCoreSideBySide(irr::IrrlichtDevice *_device);
|
||||
~RenderingCoreSideBySide() override;
|
||||
void draw() override;
|
||||
};
|
||||
|
||||
class RenderingCorePageflip: public RenderingCoreStereo
|
||||
{
|
||||
protected:
|
||||
video::ITexture *hud = nullptr;
|
||||
|
||||
void init_textures();
|
||||
void clear_textures();
|
||||
|
||||
void update_screen_size() override;
|
||||
void use_eye(bool right) override;
|
||||
void reset_eye() override;
|
||||
|
||||
public:
|
||||
RenderingCorePageflip(irr::IrrlichtDevice *_device);
|
||||
~RenderingCorePageflip() override;
|
||||
void draw() override;
|
||||
};
|
||||
|
||||
class RenderingCoreInterlaced: public RenderingCoreStereo
|
||||
{
|
||||
protected:
|
||||
v2u32 image_size;
|
||||
video::ITexture *left = nullptr;
|
||||
video::ITexture *right = nullptr;
|
||||
video::ITexture *mask = nullptr;
|
||||
video::SMaterial mat;
|
||||
|
||||
void init_material();
|
||||
void init_textures();
|
||||
void clear_textures();
|
||||
void init_mask();
|
||||
|
||||
void update_screen_size() override;
|
||||
void use_eye(bool right) override;
|
||||
void reset_eye() override;
|
||||
|
||||
void merge();
|
||||
|
||||
public:
|
||||
RenderingCoreInterlaced(irr::IrrlichtDevice *_device);
|
||||
~RenderingCoreInterlaced() override;
|
||||
void draw() override;
|
||||
};
|
||||
|
|
|
@ -107,11 +107,9 @@ RenderingEngine::RenderingEngine(IEventReceiver *receiver)
|
|||
else if (draw_mode == "interlaced")
|
||||
core.reset(new RenderingCoreInterlaced(m_device));
|
||||
else if (draw_mode == "sidebyside")
|
||||
core.reset(new RenderingCoreDouble(m_device, RenderingCoreDouble::Mode::SideBySide));
|
||||
else if (draw_mode == "topbottom")
|
||||
core.reset(new RenderingCoreDouble(m_device, RenderingCoreDouble::Mode::TopBottom));
|
||||
core.reset(new RenderingCoreSideBySide(m_device));
|
||||
else if (draw_mode == "pageflip")
|
||||
core.reset(new RenderingCoreDouble(m_device, RenderingCoreDouble::Mode::Pageflip));
|
||||
core.reset(new RenderingCorePageflip(m_device));
|
||||
else
|
||||
core.reset(new RenderingCorePlain(m_device));
|
||||
|
||||
|
|
Loading…
Reference in New Issue