New 3D Mode: Pageflip
authorDalai Felinto <dfelinto@gmail.com>
Mon, 14 Dec 2015 21:01:32 +0000 (19:01 -0200)
committersfan5 <sfan5@live.de>
Sat, 9 Jan 2016 15:52:29 +0000 (16:52 +0100)
The pageflip mode requires a stereo quadbuffer, and a modern graphic
card. Patch tested with NVidia 3D Vision.

The mini-map is not drawn, but that's what is done for topbottom and
sidebyside modes as well.

Also most of the time the user would prefer the HUD to be off. That's
for the user to decide though, and toggle it manually.

Finally, the interocular distance (aka eye separation) is twice as much
as the "3d_paralax_strength" settings. I find this a strange design
decision. I didn't want to chance this though, since it's how the other
3d modes interpret this settings.

builtin/settingtypes.txt
minetest.conf.example
src/client/clientlauncher.cpp
src/drawscene.cpp
src/game.cpp

index 62f817062dbc6a8259bd59a0e9e706913e110b62..6412ab4f672e90e9290df7a67b03e3d940804abf 100644 (file)
@@ -454,7 +454,8 @@ fall_bobbing_amount (Fall bobbing) float 0.0
 #    -    interlaced: odd/even line based polarisation screen support.
 #    -    topbottom: split screen top/bottom.
 #    -    sidebyside: split screen side by side.
-3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside
+#    -    pageflip: quadbuffer based 3d.
+3d_mode (3D mode) enum none none,anaglyph,interlaced,topbottom,sidebyside,pageflip
 
 #    In-game chat console background color (R,G,B).
 console_color (Console color) string (0,0,0)
index 40456f9530e5be41919c87cd7f0ff0bb3f7f8683..806ce62c2a1e414ea8f3892250362a2838804d97 100644 (file)
 #    -    interlaced: odd/even line based polarisation screen support.
 #    -    topbottom: split screen top/bottom.
 #    -    sidebyside: split screen side by side.
-#    type: enum values: none, anaglyph, interlaced, topbottom, sidebyside
+#    -    pageflip: quadbuffer based 3d.
+#    type: enum values: none, anaglyph, interlaced, topbottom, sidebyside, pageflip
 # 3d_mode = none
 
 #    In-game chat console background color (R,G,B).
index dfddef34eca06c26b95f5e6f43591ad8d5b20e80..be6426627bef449b1cd9c78e3c9a5d1975dfa8cb 100644 (file)
@@ -512,6 +512,9 @@ bool ClientLauncher::create_engine_device()
        u16 bits = g_settings->getU16("fullscreen_bpp");
        u16 fsaa = g_settings->getU16("fsaa");
 
+       // stereo buffer required for pageflip stereo
+       bool stereo_buffer = g_settings->get("3d_mode") == "pageflip";
+
        // Determine driver
        video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
        std::string driverstring = g_settings->get("video_driver");
@@ -537,6 +540,7 @@ bool ClientLauncher::create_engine_device()
        params.AntiAlias     = fsaa;
        params.Fullscreen    = fullscreen;
        params.Stencilbuffer = false;
+       params.Stereobuffer  = stereo_buffer;
        params.Vsync         = vsync;
        params.EventReceiver = receiver;
        params.HighPrecisionFPU = g_settings->getBool("high_precision_fpu");
index 509f341d5741dec798bbf732a1533e3c5739648b..c716ca0d4093982d91d72ee0e312aab9f62246ee 100644 (file)
@@ -404,6 +404,84 @@ void draw_top_bottom_3d_mode(Camera& camera, bool show_hud,
        camera.getCameraNode()->setTarget(oldTarget);
 }
 
+void draw_pageflip_3d_mode(Camera& camera, bool show_hud,
+               Hud& hud, std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
+               scene::ISceneManager* smgr, const v2u32& screensize,
+               bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv,
+               video::SColor skycolor)
+{
+       /* preserve old setup*/
+       irr::core::vector3df oldPosition = camera.getCameraNode()->getPosition();
+       irr::core::vector3df oldTarget   = camera.getCameraNode()->getTarget();
+
+       irr::core::matrix4 startMatrix =
+                       camera.getCameraNode()->getAbsoluteTransformation();
+       irr::core::vector3df focusPoint = (camera.getCameraNode()->getTarget()
+                       - camera.getCameraNode()->getAbsolutePosition()).setLength(1)
+                       + camera.getCameraNode()->getAbsolutePosition();
+
+       //Left eye...
+       driver->setRenderTarget(irr::video::ERT_STEREO_LEFT_BUFFER);
+
+       irr::core::vector3df leftEye;
+       irr::core::matrix4 leftMove;
+       leftMove.setTranslation(
+                       irr::core::vector3df(-g_settings->getFloat("3d_paralax_strength"),
+                                       0.0f, 0.0f));
+       leftEye = (startMatrix * leftMove).getTranslation();
+
+       //clear the depth buffer, and color
+       driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
+       camera.getCameraNode()->setPosition(leftEye);
+       camera.getCameraNode()->setTarget(focusPoint);
+       smgr->drawAll();
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
+
+       if (show_hud) {
+               draw_selectionbox(driver, hud, hilightboxes, show_hud);
+
+               if (draw_wield_tool)
+                       camera.drawWieldedTool(&leftMove);
+
+               hud.drawHotbar(client.getPlayerItem());
+               hud.drawLuaElements(camera.getOffset());
+       }
+
+       guienv->drawAll();
+
+       //Right eye...
+       driver->setRenderTarget(irr::video::ERT_STEREO_RIGHT_BUFFER);
+
+       irr::core::vector3df rightEye;
+       irr::core::matrix4 rightMove;
+       rightMove.setTranslation(
+                       irr::core::vector3df(g_settings->getFloat("3d_paralax_strength"),
+                                       0.0f, 0.0f));
+       rightEye = (startMatrix * rightMove).getTranslation();
+
+       //clear the depth buffer, and color
+       driver->beginScene(true, true, irr::video::SColor(200, 200, 200, 255));
+       camera.getCameraNode()->setPosition(rightEye);
+       camera.getCameraNode()->setTarget(focusPoint);
+       smgr->drawAll();
+       driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
+
+       if (show_hud) {
+               draw_selectionbox(driver, hud, hilightboxes, show_hud);
+
+               if (draw_wield_tool)
+                       camera.drawWieldedTool(&rightMove);
+
+               hud.drawHotbar(client.getPlayerItem());
+               hud.drawLuaElements(camera.getOffset());
+       }
+
+       guienv->drawAll();
+
+       camera.getCameraNode()->setPosition(oldPosition);
+       camera.getCameraNode()->setTarget(oldTarget);
+}
+
 void draw_plain(Camera& camera, bool show_hud, Hud& hud,
                std::vector<aabb3f> hilightboxes, video::IVideoDriver* driver,
                bool draw_wield_tool, Client& client, gui::IGUIEnvironment* guienv)
@@ -466,6 +544,13 @@ void draw_scene(video::IVideoDriver *driver, scene::ISceneManager *smgr,
                                smgr, screensize, draw_wield_tool, client, guienv, skycolor);
                show_hud = false;
        }
+       else if (draw_mode == "pageflip")
+       {
+               draw_pageflip_3d_mode(camera, show_hud, hud, hilightboxes, driver,
+                               smgr, screensize, draw_wield_tool, client, guienv, skycolor);
+               draw_crosshair = false;
+               show_hud = false;
+       }
        else {
                draw_plain(camera, show_hud, hud, hilightboxes, driver,
                                draw_wield_tool, client, guienv);
index 7ada1791e7c86f4cbc8abf47973b4c6be065fdfa..92d919931fd3346fce62b905cb36b431ee742e74 100644 (file)
@@ -1872,6 +1872,10 @@ void Game::run()
 
 void Game::shutdown()
 {
+       if (g_settings->get("3d_mode") == "pageflip") {
+               driver->setRenderTarget(irr::video::ERT_STEREO_BOTH_BUFFERS);
+       }
+
        showOverlayMessage(wgettext("Shutting down..."), 0, 0, false);
 
        if (clouds)