From a8be69146f733416f20cdd36bbe23a46e5fdad33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Tue, 19 Aug 2014 19:36:34 +0300 Subject: [PATCH] Oculus Rift|libappfw|libgui: Frame buffer should not use mipmapping The main problem with the LibOVR rendering was that the frame buffer texture had mipmapping enabled; GLTexture never applied the parameters because the texture wasn't bound using the class. OVR rendering is now (de)initialized as needed from libappfw. Todo: Reconsider ownership of the unwarped frame buffer. --- doomsday/libappfw/src/basewindow.cpp | 22 ++--- doomsday/libappfw/src/vr/oculusrift.cpp | 27 +----- doomsday/libappfw/src/vrwindowtransform.cpp | 91 +------------------ .../libgui/include/de/graphics/gltexture.h | 6 ++ doomsday/libgui/src/graphics/gltexture.cpp | 10 ++ doomsday/tests/test_appfw/src/mainwindow.cpp | 9 +- 6 files changed, 35 insertions(+), 130 deletions(-) diff --git a/doomsday/libappfw/src/basewindow.cpp b/doomsday/libappfw/src/basewindow.cpp index 677929bb8a..0ee3465c3e 100644 --- a/doomsday/libappfw/src/basewindow.cpp +++ b/doomsday/libappfw/src/basewindow.cpp @@ -161,7 +161,15 @@ void BaseWindow::preDraw() auto &vr = DENG2_BASE_GUI_APP->vr(); if(vr.mode() == VRConfig::OculusRift) { - vr.oculusRift().beginFrame(); + if(canvas().isGLReady()) + { + vr.oculusRift().init(); + vr.oculusRift().beginFrame(); + } + } + else + { + vr.oculusRift().deinit(); } } @@ -171,18 +179,6 @@ void BaseWindow::postDraw() if(vr.mode() == VRConfig::OculusRift) { vr.oculusRift().endFrame(); - - /* - GLTarget defaultTarget; - GLState::push() - .setTarget(defaultTarget) - .setViewport(Rectangleui::fromSize(defaultTarget.size())) - .apply(); - glClearColor(1, 0, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - canvas().QGLWidget::swapBuffers(); - GLState::pop().apply(); - */ } // The timer loop was paused when the frame was requested to be drawn. diff --git a/doomsday/libappfw/src/vr/oculusrift.cpp b/doomsday/libappfw/src/vr/oculusrift.cpp index c50d6c6073..5106a17511 100644 --- a/doomsday/libappfw/src/vr/oculusrift.cpp +++ b/doomsday/libappfw/src/vr/oculusrift.cpp @@ -169,7 +169,8 @@ DENG2_PIMPL(OculusRift) uint const w = framebuffer().size().x; uint const h = framebuffer().size().y; - //framebuffer().colorTexture().setFilter(gl::Linear, gl::Linear, gl::MipNone); + framebuffer().colorTexture().setFilter(gl::Linear, gl::Linear, gl::MipNone); + framebuffer().colorTexture().glApplyParameters(); LOG_GL_VERBOSE("Framebuffer size: ") << framebuffer().size().asText(); @@ -258,8 +259,10 @@ DENG2_PIMPL(OculusRift) ovrHmd_AttachToWindow(hmd, window->nativeHandle(), NULL, NULL); + /* float clearColor[4] = { 0.0f, 0.5f, 1.0f, 0.0f }; ovrHmd_SetFloatArray(hmd, "DistortionClearColor", clearColor, 4); + */ #endif } @@ -343,16 +346,7 @@ DENG2_PIMPL(OculusRift) void updateEyePose() { - if(!frameOngoing) - { - //qDebug() << "Tried to updateEyePose without frame ongoing"; - //DENG2_PRINT_BACKTRACE(); - return; - } - //DENG2_ASSERT(frameOngoing); - - //if(!needPose[currentEye]) return; - //needPose[currentEye] = false; + if(!frameOngoing) return; ovrPosef &pose = headPose[currentEye]; @@ -391,19 +385,9 @@ DENG2_PIMPL(OculusRift) { DENG2_ASSERT(frameOngoing); - /*GLTarget defaultTarget; - GLState::push() - .setTarget(defaultTarget) - .setViewport(Rectangleui::fromSize(defaultTarget.size())) - .apply();*/ - ovrHmd_EndFrame(hmd, headPose, textures); dismissHealthAndSafetyWarningOnTap(); - - //GLState::considerNativeStateUndefined(); - //GLState::pop().apply(); - frameOngoing = false; } #endif @@ -451,7 +435,6 @@ void OculusRift::setCurrentEye(int index) if(d->hmd) { d->currentEye = d->hmd->EyeRenderOrder[index]; - //d->needPose[d->currentEye] = true; d->updateEyePose(); } #else diff --git a/doomsday/libappfw/src/vrwindowtransform.cpp b/doomsday/libappfw/src/vrwindowtransform.cpp index a7e99809cc..caffd31f4e 100644 --- a/doomsday/libappfw/src/vrwindowtransform.cpp +++ b/doomsday/libappfw/src/vrwindowtransform.cpp @@ -21,9 +21,6 @@ #include "de/VRConfig" #include "de/BaseGuiApp" #include "de/BaseWindow" -//#include "de_platform.h" -//#include "con_main.h" -//#include "render/vr.h" #include #include @@ -33,60 +30,17 @@ namespace de { DENG2_PIMPL(VRWindowTransform) { VRConfig &vrCfg; - /*Drawable oculusRift; - GLUniform uOculusRiftFB; - GLUniform uOculusDistortionScale; - GLUniform uOculusScreenSize; - GLUniform uOculusLensSeparation; - GLUniform uOculusHmdWarpParam; - GLUniform uOculusChromAbParam; - typedef GLBufferT OculusRiftVBuf;*/ GLFramebuffer unwarpedFB; Instance(Public *i) : Base(i) , vrCfg(DENG2_BASE_GUI_APP->vr()) - /*, uOculusRiftFB ("texture", GLUniform::Sampler2D) - , uOculusDistortionScale("distortionScale", GLUniform::Float) - , uOculusScreenSize ("screenSize", GLUniform::Vec2) - , uOculusLensSeparation ("lensSeparationDistance", GLUniform::Float) - , uOculusHmdWarpParam ("hmdWarpParam", GLUniform::Vec4) - , uOculusChromAbParam ("chromAbParam", GLUniform::Vec4)*/ {} - void init() + ~Instance() { -/* - OculusRiftVBuf *buf = new OculusRiftVBuf; - oculusRift.addBuffer(buf); - - // Set up a simple static quad. - OculusRiftVBuf::Type const verts[4] = { - { Vector3f(-1, 1, 0.5f), Vector2f(0, 1), }, - { Vector3f( 1, 1, 0.5f), Vector2f(1, 1), }, - { Vector3f(-1, -1, 0.5f), Vector2f(0, 0), }, - { Vector3f( 1, -1, 0.5f), Vector2f(1, 0), } - }; - buf->setVertices(gl::TriangleStrip, verts, 4, gl::Static); - - DENG2_BASE_GUI_APP->shaders() - .build(oculusRift.program(), "vr.oculusrift.barrel") - << uOculusRiftFB - << uOculusDistortionScale - << uOculusScreenSize - << uOculusLensSeparation - << uOculusHmdWarpParam - << uOculusChromAbParam;*/ - - //unwarpedFB.glInit(); - //uOculusRiftFB = unwarpedFB.colorTexture(); - } - - void deinit() - { - //oculusRift.clear(); - //unwarpedFB.glDeinit(); + vrCfg.oculusRift().deinit(); } Canvas &canvas() const @@ -129,16 +83,6 @@ DENG2_PIMPL(VRWindowTransform) vrCfg.enableFrustumShift(false); - // Allocate offscreen buffers - larger than Oculus Rift size, to get adequate resolution at center after warp - // For some reason, 1.5X looks best, even though objects are ~2.3X unwarped size at center. - /*float unwarpFactor = 1.5f; - Canvas::Size textureSize = Canvas::Size(1280, 800) * unwarpFactor; - // Canvas::Size textureSize(2560, 1600); // 2 * 1280x800 // Undesirable relative softness at very center of image - // Canvas::Size textureSize(3200, 2000); // 2.5 * 1280x800 // Softness here too - unwarpedFB.resize(textureSize); - - unwarpedFB.colorTexture().setFilter(gl::Linear, gl::Linear, gl::MipNone);*/ - // Use a little bit of multisampling to smooth out the magnified jagged edges. // Note: Independent of the vid-fsaa setting because this is beneficial even when // vid-fsaa is disabled. @@ -150,7 +94,6 @@ DENG2_PIMPL(VRWindowTransform) .setViewport(Rectangleui::fromSize(unwarpedFB.size())) .apply(); unwarpedFB.target().unsetActiveRect(true); - unwarpedFB.target().clear(GLTarget::ColorDepth); GLFramebuffer::Size const fbSize = unwarpedFB.size(); @@ -172,39 +115,13 @@ DENG2_PIMPL(VRWindowTransform) } unwarpedFB.target().unsetActiveRect(true); - GLState::pop().apply(); -/* // Necessary until the legacy code uses GLState, too: - glEnable(GL_TEXTURE_2D); - - target().clear(GLTarget::Color); - GLState::push() - .setDepthTest(false); - - // Copy contents of offscreen buffer to normal screen. - uOculusDistortionScale = vrCfg.oculusRift().distortionScale(); - uOculusScreenSize = vrCfg.oculusRift().screenSize(); - uOculusLensSeparation = vrCfg.oculusRift().lensSeparationDistance(); - uOculusHmdWarpParam = vrCfg.oculusRift().hmdWarpParam(); - uOculusChromAbParam = vrCfg.oculusRift().chromAbParam(); - // - oculusRift.draw(); - - glBindTexture(GL_TEXTURE_2D, 0); - glDepthMask(GL_TRUE); - - GLState::pop().apply();*/ - vrCfg.enableFrustumShift(); // restore default } void draw() { - // Allow Oculus Rift to use the latest head tracking position for the upcoming - // draw operations. - //vrCfg.oculusRift().allowUpdate(); - switch(vrCfg.mode()) { // A) Single view type stereo 3D modes here: @@ -359,12 +276,12 @@ VRWindowTransform::VRWindowTransform(BaseWindow &window) void VRWindowTransform::glInit() { - d->init(); + //d->init(); } void VRWindowTransform::glDeinit() { - d->deinit(); + //d->deinit(); } Vector2ui VRWindowTransform::logicalRootSize(Vector2ui const &physicalCanvasSize) const diff --git a/doomsday/libgui/include/de/graphics/gltexture.h b/doomsday/libgui/include/de/graphics/gltexture.h index 887109cfca..476c7bf0f8 100644 --- a/doomsday/libgui/include/de/graphics/gltexture.h +++ b/doomsday/libgui/include/de/graphics/gltexture.h @@ -226,6 +226,12 @@ class LIBGUI_PUBLIC GLTexture : public Asset void glBindToUnit(int unit) const; + /** + * Applies any cached parameter changes to the GL texture object. The texture is + * bound temporarily while this is done (so any previously bound texture is unbound). + */ + void glApplyParameters(); + /** * Returns the image format that was specified when image content was put * into the texture (with setImage() or setSubImage()). diff --git a/doomsday/libgui/src/graphics/gltexture.cpp b/doomsday/libgui/src/graphics/gltexture.cpp index 83f83e2282..d1f9318a4f 100644 --- a/doomsday/libgui/src/graphics/gltexture.cpp +++ b/doomsday/libgui/src/graphics/gltexture.cpp @@ -501,6 +501,16 @@ void GLTexture::glBindToUnit(int unit) const } } +void GLTexture::glApplyParameters() +{ + if(d->flags.testFlag(ParamsChanged)) + { + d->glBind(); + d->glUpdateParamsOfBoundTexture(); + d->glUnbind(); + } +} + Image::Format GLTexture::imageFormat() const { return d->format; diff --git a/doomsday/tests/test_appfw/src/mainwindow.cpp b/doomsday/tests/test_appfw/src/mainwindow.cpp index 331a711d99..ed56968bac 100644 --- a/doomsday/tests/test_appfw/src/mainwindow.cpp +++ b/doomsday/tests/test_appfw/src/mainwindow.cpp @@ -64,8 +64,6 @@ DENG2_PIMPL(MainWindow) ~Instance() { - TestApp::vr().oculusRift().deinit(); - releaseRef(cursorX); releaseRef(cursorY); } @@ -113,11 +111,6 @@ DENG2_PIMPL(MainWindow) contentXf.glInit(); - if(TestApp::vr().mode() == VRConfig::OculusRift) - { - TestApp::vr().oculusRift().init(); - } - self.raise(); self.activateWindow(); self.canvas().setFocus(); @@ -155,7 +148,7 @@ DENG2_PIMPL(MainWindow) compositor->setCompositeProjection( vr.projectionMatrix(OVR_FOV, root.viewRule().size(), OVR_NEAR_CLIP, OVR_FAR_CLIP) - * Matrix4f::scale(Vector3f(1, -1 / vr.oculusRift().aspect(), 1)) + * Matrix4f::scale(Vector3f(.5f, -.5f / vr.oculusRift().aspect(), 1)) * Matrix4f::translate(Vector3f(-.5f, -.5f, -1))); } else