From 41404ba522921d945e14a79919fa062972344b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Tue, 19 Aug 2014 09:41:44 +0300 Subject: [PATCH] Oculus Rift|Client|test_appfw: Revised VR functionality Also tweaking frame begin/end, window redraw requests. --- doomsday/client/include/render/vr.h | 4 +- doomsday/client/src/busymode.cpp | 2 +- doomsday/client/src/clientapp.cpp | 8 +++ doomsday/client/src/gl/gl_main.cpp | 6 +- doomsday/client/src/render/rend_main.cpp | 9 ++- doomsday/client/src/render/viewports.cpp | 4 -- doomsday/client/src/render/vr.cpp | 56 +++++++++++++------ doomsday/client/src/ui/clientwindow.cpp | 29 ++++++---- doomsday/client/src/ui/dd_input.cpp | 4 +- doomsday/client/src/ui/widgets/gamewidget.cpp | 5 +- doomsday/tests/test_appfw/src/mainwindow.cpp | 13 ++++- 11 files changed, 89 insertions(+), 51 deletions(-) diff --git a/doomsday/client/include/render/vr.h b/doomsday/client/include/render/vr.h index dc8f37e2de..af92a5f4c9 100644 --- a/doomsday/client/include/render/vr.h +++ b/doomsday/client/include/render/vr.h @@ -39,11 +39,11 @@ void VR_ConsoleRegister(); /** * Returns the horizontal field of view in Oculus Rift in degrees. */ -float VR_RiftFovX(); +//float VR_RiftFovX(); /** * Load Oculus Rift parameters via Rift SDK. */ -bool VR_LoadRiftParameters(); +//bool VR_LoadRiftParameters(); #endif // CLIENT_RENDER_VR_H diff --git a/doomsday/client/src/busymode.cpp b/doomsday/client/src/busymode.cpp index 587d3f161c..e76ac24fe2 100644 --- a/doomsday/client/src/busymode.cpp +++ b/doomsday/client/src/busymode.cpp @@ -499,7 +499,7 @@ void BusyMode_Loop(void) !Con_IsProgressAnimationCompleted()) { // Let's keep running the busy loop. - ClientWindowSystem::main().draw(); + //ClientWindowSystem::main().draw(); return; } diff --git a/doomsday/client/src/clientapp.cpp b/doomsday/client/src/clientapp.cpp index 8304b892be..68ba6bac40 100644 --- a/doomsday/client/src/clientapp.cpp +++ b/doomsday/client/src/clientapp.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,7 @@ #include "gl/gl_main.h" #include "gl/gl_texmanager.h" #include "ui/inputsystem.h" +#include "ui/sys_input.h" #include "ui/clientwindowsystem.h" #include "ui/clientwindow.h" #include "ui/widgets/taskbarwidget.h" @@ -199,6 +201,8 @@ DENG2_PIMPL(ClientApp) { LogBuffer::get().removeSink(logAlarm); + self.vr().oculusRift().deinit(); + Sys_Shutdown(); DD_Shutdown(); @@ -412,6 +416,10 @@ void ClientApp::postFrame() /// @todo Should these be here? Consider multiple windows, each having a postFrame? /// Or maybe the frames need to be synced? Or only one of them has a postFrame? + // We will arrive here always at the same time in relation to the displayed + // frame: it is a good time to update the mouse state. + Mouse_Poll(); + if(gx.EndFrame) { gx.EndFrame(); diff --git a/doomsday/client/src/gl/gl_main.cpp b/doomsday/client/src/gl/gl_main.cpp index fac89bf086..083294a5e3 100644 --- a/doomsday/client/src/gl/gl_main.cpp +++ b/doomsday/client/src/gl/gl_main.cpp @@ -181,6 +181,8 @@ void GL_AssertContextActive() void GL_DoUpdate() { + if(ClientApp::vr().mode() == VRConfig::OculusRift) return; + // Check for color adjustment changes. if(oldgamma != vid_gamma || oldcontrast != vid_contrast || oldbright != vid_bright) { @@ -197,10 +199,6 @@ void GL_DoUpdate() // Blit screen to video. ClientWindow::main().swapBuffers(); - - // We will arrive here always at the same time in relation to the displayed - // frame: it is a good time to update the mouse state. - Mouse_Poll(); } void GL_GetGammaRamp(DisplayColorTransfer *ramp) diff --git a/doomsday/client/src/render/rend_main.cpp b/doomsday/client/src/render/rend_main.cpp index 716f97024a..0154b8f470 100644 --- a/doomsday/client/src/render/rend_main.cpp +++ b/doomsday/client/src/render/rend_main.cpp @@ -292,6 +292,7 @@ static void unlinkMobjLumobjs() } } +/* static void fieldOfViewChanged() { if(vrCfg().mode() == VRConfig::OculusRift) @@ -304,7 +305,7 @@ static void fieldOfViewChanged() if(Con_GetFloat("rend-vr-nonrift-fovx") != fieldOfView) Con_SetFloat("rend-vr-nonrift-fovx", fieldOfView); } -} +}*/ static void detailFactorChanged() { @@ -341,7 +342,7 @@ static void texQualityChanged() void Rend_Register() { C_VAR_INT ("rend-bias", &useBias, 0, 0, 1); - C_VAR_FLOAT2("rend-camera-fov", &fieldOfView, 0, 1, 179, fieldOfViewChanged); + C_VAR_FLOAT ("rend-camera-fov", &fieldOfView, 0, 1, 179); C_VAR_FLOAT ("rend-glow", &glowFactor, 0, 0, 2); C_VAR_INT ("rend-glow-height", &glowHeightMax, 0, 0, 1024); @@ -495,7 +496,9 @@ float Rend_FieldOfView() { // fieldOfView = VR::riftFovX(); // Update for culling // return VR::riftFovX(); - return fieldOfView; + + // OVR tells us which FOV to use. + return vrCfg().oculusRift().fovX(); } else { diff --git a/doomsday/client/src/render/viewports.cpp b/doomsday/client/src/render/viewports.cpp index 91366dc72b..9a3b099205 100644 --- a/doomsday/client/src/render/viewports.cpp +++ b/doomsday/client/src/render/viewports.cpp @@ -889,10 +889,6 @@ DENG_EXTERN_C void R_RenderPlayerView(int num) vrCfg().setEyeHeightInMapUnits(Con_GetInteger("player-eyeheight")); - // Latest possible time to check the real head angles. After this we'll be - // using the provided values. - vrCfg().oculusRift().update(); - setupViewMatrix(); setupPlayerSprites(); diff --git a/doomsday/client/src/render/vr.cpp b/doomsday/client/src/render/vr.cpp index 454d8f5b13..e72a055c4b 100644 --- a/doomsday/client/src/render/vr.cpp +++ b/doomsday/client/src/render/vr.cpp @@ -31,16 +31,16 @@ namespace VR { } static int vrMode = VRConfig::Mono; -static float vrRiftFovX = 114.8f; -static float vrNonRiftFovX = 95.f; +//static float vrRiftFovX = 114.8f; +//static float vrNonRiftFovX = 95.f; +//static float vrRiftLatency; +//static byte autoLoadRiftParams = 1; +static int vrRiftFBSamples; static float vrHudDistance; -static float vrRiftLatency; static float vrPlayerHeight; static float vrIpd; -static int vrRiftFBSamples; static byte vrSwapEyes; static float vrDominantEye; -static byte autoLoadRiftParams = 1; VRConfig &vrCfg() { @@ -48,10 +48,12 @@ VRConfig &vrCfg() return DENG2_BASE_GUI_APP->vr(); } +/* float VR_RiftFovX() { return vrRiftFovX; } +*/ static void vrConfigVariableChanged() { @@ -59,7 +61,7 @@ static void vrConfigVariableChanged() vrCfg().setScreenDistance(vrHudDistance); vrCfg().setInterpupillaryDistance(vrIpd); vrCfg().setPhysicalPlayerHeight(vrPlayerHeight); - vrCfg().oculusRift().setPredictionLatency(vrRiftLatency); + //vrCfg().oculusRift().setPredictionLatency(vrRiftLatency); vrCfg().setRiftFramebufferSampleCount(vrRiftFBSamples); vrCfg().setSwapEyes(vrSwapEyes); } @@ -68,6 +70,14 @@ static void vrConfigVariableChanged() // see also rend_main.cpp static void vrModeChanged() { + if(vrMode == VRConfig::OculusRift && !vrCfg().oculusRift().isReady()) + { + // Can't activate Oculus Rift mode unless the device is connected. + vrMode = VRConfig::Mono; + + LOG_WARNING("Oculus Rift not connected, reverting to normal 3D mode"); + } + vrCfg().setMode(VRConfig::StereoMode(vrMode)); if(ClientWindow::mainExists()) @@ -78,6 +88,17 @@ static void vrModeChanged() win.updateCanvasFormat(); // possibly changes pixel format } + // Make sure Oculus Rift rendering is (de)initialized as needed. + if(vrCfg().mode() == VRConfig::OculusRift) + { + vrCfg().oculusRift().init(); + } + else + { + vrCfg().oculusRift().deinit(); + } + + /* // Update FOV cvar accordingly. if(vrMode == VRConfig::OculusRift) { @@ -91,9 +112,10 @@ static void vrModeChanged() { if(Con_GetFloat("rend-camera-fov") != vrNonRiftFovX) Con_SetFloat("rend-camera-fov", vrNonRiftFovX); - } + }*/ } +/* static void vrRiftFovXChanged() { if(vrCfg().mode() == VRConfig::OculusRift) @@ -116,7 +138,7 @@ D_CMD(LoadRiftParams) { DENG2_UNUSED3(src, argc, argv); return VR_LoadRiftParameters(); -} +}*/ void VR_ConsoleRegister() { @@ -125,7 +147,7 @@ void VR_ConsoleRegister() vrHudDistance = vrCfg().screenDistance(); vrIpd = vrCfg().interpupillaryDistance(); vrPlayerHeight = vrCfg().physicalPlayerHeight(); - vrRiftLatency = vrCfg().oculusRift().predictionLatency(); + //vrRiftLatency = vrCfg().oculusRift().predictionLatency(); vrRiftFBSamples = vrCfg().riftFramebufferSampleCount(); vrSwapEyes = vrCfg().swapEyes(); @@ -135,25 +157,22 @@ void VR_ConsoleRegister() */ C_VAR_INT2 ("rend-vr-mode", &vrMode, 0, 0, VRConfig::NUM_STEREO_MODES - 1, vrModeChanged); - C_VAR_BYTE ("rend-vr-autoload-rift-params", &autoLoadRiftParams, 0, 0, 1); - C_VAR_FLOAT2("rend-vr-nonrift-fovx", &vrNonRiftFovX, 0, 5.0f, 270.0f, vrNonRiftFovXChanged); - C_VAR_FLOAT2("rend-vr-rift-fovx", &vrRiftFovX, 0, 5.0f, 270.0f, vrRiftFovXChanged); + //C_VAR_BYTE ("rend-vr-autoload-rift-params", &autoLoadRiftParams, 0, 0, 1); + //C_VAR_FLOAT2("rend-vr-nonrift-fovx", &vrNonRiftFovX, 0, 5.0f, 270.0f, vrNonRiftFovXChanged); + //C_VAR_FLOAT2("rend-vr-rift-fovx", &vrRiftFovX, 0, 5.0f, 270.0f, vrRiftFovXChanged); + //C_VAR_FLOAT2("rend-vr-rift-latency", &vrRiftLatency, 0, 0.0f, 0.100f, vrConfigVariableChanged); C_VAR_FLOAT2("rend-vr-dominant-eye", &vrDominantEye, 0, -1.0f, 1.0f, vrConfigVariableChanged); C_VAR_FLOAT2("rend-vr-hud-distance", &vrHudDistance, 0, 0.01f, 40.0f, vrConfigVariableChanged); C_VAR_FLOAT2("rend-vr-ipd", &vrIpd, 0, 0.02f, 0.1f, vrConfigVariableChanged); C_VAR_FLOAT2("rend-vr-player-height", &vrPlayerHeight, 0, 1.0f, 2.4f, vrConfigVariableChanged); - C_VAR_FLOAT2("rend-vr-rift-latency", &vrRiftLatency, 0, 0.0f, 0.100f, vrConfigVariableChanged); C_VAR_INT2 ("rend-vr-rift-samples", &vrRiftFBSamples, 0, 1, 4, vrConfigVariableChanged); C_VAR_BYTE2 ("rend-vr-swap-eyes", &vrSwapEyes, 0, 0, 1, vrConfigVariableChanged); - C_CMD("loadriftparams", NULL, LoadRiftParams); + //C_CMD("loadriftparams", NULL, LoadRiftParams); } -// Warping - -/// @todo warping - +#if 0 bool VR_LoadRiftParameters() { de::OculusRift &ovr = vrCfg().oculusRift(); @@ -173,3 +192,4 @@ bool VR_LoadRiftParameters() } return false; } +#endif diff --git a/doomsday/client/src/ui/clientwindow.cpp b/doomsday/client/src/ui/clientwindow.cpp index 3d7febb941..e7fd1cf7fc 100644 --- a/doomsday/client/src/ui/clientwindow.cpp +++ b/doomsday/client/src/ui/clientwindow.cpp @@ -637,7 +637,11 @@ DENG2_PIMPL(ClientWindow) if(vrCfg().mode() == VRConfig::OculusRift) { - compositor->setCompositeProjection(Matrix4f::ortho(-1.1f, 2.2f, -1.1f, 2.2f)); + /// @todo Adjustable compositor depth? + compositor->setCompositeProjection( + GL_GetProjectionMatrix() + * Matrix4f::scale(Vector3f(1.f, -1.f / vrCfg().oculusRift().aspect(), 1.f)) + * Matrix4f::translate(Vector3f(-.5f, -.5f, -1))); } else { @@ -797,9 +801,6 @@ void ClientWindow::canvasGLInit(Canvas &) void ClientWindow::preDraw() { - // NOTE: This occurs during the Canvas paintGL event. - BaseWindow::preDraw(); - ClientApp::app().preFrame(); /// @todo what about multiwindow? DENG_ASSERT_IN_MAIN_THREAD(); @@ -813,6 +814,9 @@ void ClientWindow::preDraw() d->updateRootSize(); } d->updateCompositor(); + + // NOTE: This occurs during the Canvas paintGL event. + BaseWindow::preDraw(); } void ClientWindow::drawWindowContent() @@ -823,17 +827,20 @@ void ClientWindow::drawWindowContent() void ClientWindow::postDraw() { - // NOTE: This occurs during the Canvas paintGL event. + /// @note This method is called during the Canvas paintGL event. - // Finish GL drawing and swap it on to the screen. Blocks until buffers - // swapped. - GL_DoUpdate(); + // OVR will handle presentation in Oculus Rift mode. + if(ClientApp::vr().mode() != VRConfig::OculusRift) + { + // Finish GL drawing and swap it on to the screen. Blocks until buffers + // swapped. + GL_DoUpdate(); + } - ClientApp::app().postFrame(); /// @todo what about multiwindow? + BaseWindow::postDraw(); + ClientApp::app().postFrame(); /// @todo what about multiwindow? d->updateFpsNotification(frameRate()); - - BaseWindow::postDraw(); } void ClientWindow::canvasGLResized(Canvas &canvas) diff --git a/doomsday/client/src/ui/dd_input.cpp b/doomsday/client/src/ui/dd_input.cpp index a4d7cc9d7d..4192495540 100644 --- a/doomsday/client/src/ui/dd_input.cpp +++ b/doomsday/client/src/ui/dd_input.cpp @@ -1485,8 +1485,8 @@ void DD_ReadHeadTracker(void) I_GetDevice(IDEV_HEAD_TRACKER)->flags |= ID_ACTIVE; // Get the latest values. - vrCfg().oculusRift().allowUpdate(); - vrCfg().oculusRift().update(); + //vrCfg().oculusRift().allowUpdate(); + //vrCfg().oculusRift().update(); ddevent_t ev; diff --git a/doomsday/client/src/ui/widgets/gamewidget.cpp b/doomsday/client/src/ui/widgets/gamewidget.cpp index 9401fdb217..46d3de8a08 100644 --- a/doomsday/client/src/ui/widgets/gamewidget.cpp +++ b/doomsday/client/src/ui/widgets/gamewidget.cpp @@ -153,10 +153,7 @@ void GameWidget::update() GL_ProcessDeferredTasks(FRAME_DEFERRED_UPLOAD_TIMEOUT); // Request update of window contents. - root().as().window().draw(); - - // After the first frame, start timedemo. - //DD_CheckTimeDemo(); + //root().as().window().draw(); } void GameWidget::drawContent() diff --git a/doomsday/tests/test_appfw/src/mainwindow.cpp b/doomsday/tests/test_appfw/src/mainwindow.cpp index 55a59de979..331a711d99 100644 --- a/doomsday/tests/test_appfw/src/mainwindow.cpp +++ b/doomsday/tests/test_appfw/src/mainwindow.cpp @@ -64,6 +64,8 @@ DENG2_PIMPL(MainWindow) ~Instance() { + TestApp::vr().oculusRift().deinit(); + releaseRef(cursorX); releaseRef(cursorY); } @@ -111,6 +113,11 @@ DENG2_PIMPL(MainWindow) contentXf.glInit(); + if(TestApp::vr().mode() == VRConfig::OculusRift) + { + TestApp::vr().oculusRift().init(); + } + self.raise(); self.activateWindow(); self.canvas().setFocus(); @@ -182,7 +189,6 @@ MainWindow::MainWindow(String const &id) vr.setMode(VRConfig::OculusRift); vr.setRiftFramebufferSampleCount(App::commandLine().has("--nofsaa")? 1 : 2); vr.setPhysicalPlayerHeight(1.8f); - vr.oculusRift().setPredictionLatency(.04f); vr.setScreenDistance(.5f); vr.setEyeHeightInMapUnits(vr.physicalPlayerHeight() * .925f); setCursor(Qt::BlankCursor); @@ -242,7 +248,10 @@ void MainWindow::preDraw() void MainWindow::postDraw() { - swapBuffers(); + if(TestApp::vr().mode() != VRConfig::OculusRift) + { + swapBuffers(); + } BaseWindow::postDraw(); Garbage_Recycle();