From 03bd17ed49c97be9911a38a0f273dfd06d15afc9 Mon Sep 17 00:00:00 2001 From: Bradley Austin Davis Date: Fri, 8 May 2015 15:09:46 -0700 Subject: [PATCH 1/5] Rebasing onto scale changes --- cmake/externals/openvr/CMakeLists.txt | 38 +++++++++++ cmake/modules/FindOpenVR.cmake | 21 ++++++ interface/CMakeLists.txt | 15 +++++ interface/src/Application.cpp | 13 ++-- interface/src/devices/OculusManager.cpp | 11 +--- interface/src/devices/TV3DManager.cpp | 64 +++++-------------- interface/src/devices/TV3DManager.h | 7 ++ interface/src/ui/overlays/Overlays.cpp | 5 +- libraries/render-utils/src/GlowEffect.cpp | 33 ++-------- .../render-utils/src/OffscreenGlContext.cpp | 43 +++++++++++++ .../render-utils/src/OffscreenGlContext.h | 33 ++++++++++ .../script-engine/src/MenuItemProperties.cpp | 9 ++- 12 files changed, 195 insertions(+), 97 deletions(-) create mode 100644 cmake/externals/openvr/CMakeLists.txt create mode 100644 cmake/modules/FindOpenVR.cmake create mode 100644 libraries/render-utils/src/OffscreenGlContext.cpp create mode 100644 libraries/render-utils/src/OffscreenGlContext.h diff --git a/cmake/externals/openvr/CMakeLists.txt b/cmake/externals/openvr/CMakeLists.txt new file mode 100644 index 0000000000..b5cd477c02 --- /dev/null +++ b/cmake/externals/openvr/CMakeLists.txt @@ -0,0 +1,38 @@ +include(ExternalProject) +include(SelectLibraryConfigurations) + +set(EXTERNAL_NAME OpenVR) + +string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER) + +ExternalProject_Add( + ${EXTERNAL_NAME} + URL https://github.com/ValveSoftware/openvr/archive/0.9.0.zip + URL_MD5 4fbde7759f604aaa68b9c40d628cc34a + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "" + LOG_DOWNLOAD 1 +) + +ExternalProject_Get_Property(${EXTERNAL_NAME} SOURCE_DIR) + +set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${SOURCE_DIR}/headers CACHE TYPE INTERNAL) + +if (WIN32) + + # FIXME need to account for different architectures + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/win32/openvr_api.lib CACHE TYPE INTERNAL) + +elseif(APPLE) + + # FIXME need to account for different architectures + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/osx32/libopenvr_api.dylib CACHE TYPE INTERNAL) + +elseif(NOT ANDROID) + + # FIXME need to account for different architectures + set(${EXTERNAL_NAME_UPPER}_LIBRARIES ${SOURCE_DIR}/lib/linux32/libopenvr_api.so CACHE TYPE INTERNAL) + +endif() + diff --git a/cmake/modules/FindOpenVR.cmake b/cmake/modules/FindOpenVR.cmake new file mode 100644 index 0000000000..9cbe790a7f --- /dev/null +++ b/cmake/modules/FindOpenVR.cmake @@ -0,0 +1,21 @@ +# +# FindLibOVR.cmake +# +# Try to find the LibOVR library to use the Oculus + +# Once done this will define +# +# OPENVR_FOUND - system found LibOVR +# OPENVR_INCLUDE_DIRS - the LibOVR include directory +# OPENVR_LIBRARIES - Link this to use LibOVR +# +# Distributed under the Apache License, Version 2.0. +# See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +# + +if (NOT ANDROID) + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args(OPENVR DEFAULT_MSG OPENVR_INCLUDE_DIRS OPENVR_LIBRARIES) +endif() + +mark_as_advanced(OPENVR_INCLUDE_DIRS OPENVR_LIBRARIES OPENVR_SEARCH_DIRS) diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 9e282f4725..a0b258fc10 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -36,8 +36,22 @@ endif () configure_file(InterfaceConfig.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceConfig.h") configure_file(InterfaceVersion.h.in "${PROJECT_BINARY_DIR}/includes/InterfaceVersion.h") + +macro(GroupSources curdir) + file(GLOB children RELATIVE ${PROJECT_SOURCE_DIR}/${curdir} ${PROJECT_SOURCE_DIR}/${curdir}/*) + foreach(child ${children}) + if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/${curdir}/${child}) + GroupSources(${curdir}/${child}) + else() + string(REPLACE "/" "\\" groupname ${curdir}) + source_group(${groupname} FILES ${PROJECT_SOURCE_DIR}/${curdir}/${child}) + endif() + endforeach() +endmacro() + # grab the implementation and header files from src dirs file(GLOB_RECURSE INTERFACE_SRCS "src/*.cpp" "src/*.h") +GroupSources("src") # Add SpeechRecognizer if on Windows or OS X, otherwise remove if (WIN32) @@ -58,6 +72,7 @@ find_package(Qt5 COMPONENTS Gui Multimedia Network OpenGL Qml Quick Script Svg W # grab the ui files in resources/ui file (GLOB_RECURSE QT_UI_FILES ui/*.ui) +source_group("UI Files" FILES ${QT_UI_FILES}) # have qt5 wrap them and generate the appropriate header files qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}") diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d8ec35c584..02fcab574c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -831,6 +831,11 @@ void Application::paintGL() { PerformanceWarning warn(showWarnings, "Application::paintGL()"); resizeGL(); + { + PerformanceTimer perfTimer("renderOverlay"); + _applicationOverlay.renderOverlay(); + } + glEnable(GL_LINE_SMOOTH); if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { @@ -913,13 +918,9 @@ void Application::paintGL() { glBlitFramebuffer(0, 0, _renderResolution.x, _renderResolution.y, 0, 0, _glWidget->getDeviceSize().width(), _glWidget->getDeviceSize().height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); - - { - PerformanceTimer perfTimer("renderOverlay"); - _applicationOverlay.renderOverlay(); - _applicationOverlay.displayOverlayTexture(); - } + _applicationOverlay.displayOverlayTexture(); } if (!OculusManager::isConnected() || OculusManager::allowSwap()) { diff --git a/interface/src/devices/OculusManager.cpp b/interface/src/devices/OculusManager.cpp index f4693d3c08..99b196849f 100644 --- a/interface/src/devices/OculusManager.cpp +++ b/interface/src/devices/OculusManager.cpp @@ -520,12 +520,6 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati return; } - ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay(); - - // We only need to render the overlays to a texture once, then we just render the texture on the hemisphere - // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() - applicationOverlay.renderOverlay(); - //Bind our framebuffer object. If we are rendering the glow effect, we let the glow effect shader take care of it if (Menu::getInstance()->isOptionChecked(MenuOption::EnableGlowEffect)) { DependencyManager::get()->prepare(); @@ -614,9 +608,8 @@ void OculusManager::display(QGLWidget * glCanvas, const glm::quat &bodyOrientati //glTranslatef(_eyeRenderDesc[eye].ViewAdjust.x, _eyeRenderDesc[eye].ViewAdjust.y, _eyeRenderDesc[eye].ViewAdjust.z); _camera->setEyeOffsetPosition(glm::vec3(-_eyeRenderDesc[eye].HmdToEyeViewOffset.x, -_eyeRenderDesc[eye].HmdToEyeViewOffset.y, -_eyeRenderDesc[eye].HmdToEyeViewOffset.z)); - Application::getInstance()->displaySide(*_camera, false, RenderArgs::MONO); - - applicationOverlay.displayOverlayTextureHmd(*_camera); + qApp->displaySide(*_camera, false, RenderArgs::MONO); + qApp->getApplicationOverlay().displayOverlayTextureHmd(*_camera); }); _activeEye = ovrEye_Count; diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 5d60bf7e19..751a3d16bb 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -92,74 +92,40 @@ void TV3DManager::display(Camera& whichCamera) { int portalW = deviceSize.width() / 2; int portalH = deviceSize.height(); - ApplicationOverlay& applicationOverlay = Application::getInstance()->getApplicationOverlay(); - - // We only need to render the overlays to a texture once, then we just render the texture as a quad - // PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay() - applicationOverlay.renderOverlay(); DependencyManager::get()->prepare(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glEnable(GL_SCISSOR_TEST); - // render left side view - glViewport(portalX, portalY, portalW, portalH); - glScissor(portalX, portalY, portalW, portalH); Camera eyeCamera; eyeCamera.setRotation(whichCamera.getRotation()); eyeCamera.setPosition(whichCamera.getPosition()); + glEnable(GL_SCISSOR_TEST); glPushMatrix(); - { - _activeEye = &_leftEye; + forEachEye([&](eyeFrustum& eye){ + _activeEye = &eye; + glViewport(portalX, portalY, portalW, portalH); + glScissor(portalX, portalY, portalW, portalH); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // reset projection matrix - glFrustum(_leftEye.left, _leftEye.right, _leftEye.bottom, _leftEye.top, nearZ, farZ); // set left view frustum + glFrustum(eye.left, eye.right, eye.bottom, eye.top, nearZ, farZ); // set left view frustum GLfloat p[4][4]; // Really? glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0])); float cotangent = p[1][1]; GLfloat fov = atan(1.0f / cotangent); - glTranslatef(_leftEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax + glTranslatef(eye.modelTranslation, 0.0, 0.0); // translate to cancel parallax glMatrixMode(GL_MODELVIEW); glLoadIdentity(); eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0)); - Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO); - - applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov); + qApp->displaySide(eyeCamera, false, RenderArgs::MONO); + qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov); _activeEye = NULL; - } - glPopMatrix(); - glDisable(GL_SCISSOR_TEST); - - // render right side view - portalX = deviceSize.width() / 2; - glEnable(GL_SCISSOR_TEST); - // render left side view - glViewport(portalX, portalY, portalW, portalH); - glScissor(portalX, portalY, portalW, portalH); - glPushMatrix(); - { - _activeEye = &_rightEye; - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); // reset projection matrix - glFrustum(_rightEye.left, _rightEye.right, _rightEye.bottom, _rightEye.top, nearZ, farZ); // set right view frustum - GLfloat p[4][4]; - glGetFloatv(GL_PROJECTION_MATRIX, &(p[0][0])); - GLfloat cotangent = p[1][1]; - GLfloat fov = atan(1.0f / cotangent); - glTranslatef(_rightEye.modelTranslation, 0.0, 0.0); // translate to cancel parallax - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - eyeCamera.setEyeOffsetPosition(glm::vec3(-_activeEye->modelTranslation,0,0)); - Application::getInstance()->displaySide(eyeCamera, false, RenderArgs::MONO); - - applicationOverlay.displayOverlayTextureStereo(whichCamera, _aspect, fov); - _activeEye = NULL; - } + }, [&]{ + // render right side view + portalX = deviceSize.width() / 2; + }); glPopMatrix(); glDisable(GL_SCISSOR_TEST); @@ -167,11 +133,13 @@ void TV3DManager::display(Camera& whichCamera) { auto fboSize = finalFbo->getSize(); // Get the ACTUAL device size for the BLIT deviceSize = qApp->getDeviceSize(); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + glBindFramebuffer(GL_READ_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(finalFbo)); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBlitFramebuffer(0, 0, fboSize.x, fboSize.y, 0, 0, deviceSize.width(), deviceSize.height(), GL_COLOR_BUFFER_BIT, GL_NEAREST); + glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); // reset the viewport to how we started glViewport(0, 0, deviceSize.width(), deviceSize.height()); diff --git a/interface/src/devices/TV3DManager.h b/interface/src/devices/TV3DManager.h index 2b2b9e0aa1..dfe5b28e87 100644 --- a/interface/src/devices/TV3DManager.h +++ b/interface/src/devices/TV3DManager.h @@ -44,6 +44,13 @@ private: static eyeFrustum _leftEye; static eyeFrustum _rightEye; static eyeFrustum* _activeEye; + + template + static void forEachEye(F f, FF ff = []{}) { + f(_leftEye); + ff(); + f(_rightEye); + } }; #endif // hifi_TV3DManager_h diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index eb2c0d77a7..0537c62b38 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include "BillboardOverlay.h" @@ -292,8 +291,8 @@ void Overlays::deleteOverlay(unsigned int id) { unsigned int Overlays::getOverlayAtPoint(const glm::vec2& point) { glm::vec2 pointCopy = point; - if (OculusManager::isConnected()) { - pointCopy = Application::getInstance()->getApplicationOverlay().screenToOverlay(point); + if (qApp->isHMDMode()) { + pointCopy = qApp->getApplicationOverlay().screenToOverlay(point); } QReadLocker lock(&_lock); diff --git a/libraries/render-utils/src/GlowEffect.cpp b/libraries/render-utils/src/GlowEffect.cpp index bb18729f12..4aa22ef66e 100644 --- a/libraries/render-utils/src/GlowEffect.cpp +++ b/libraries/render-utils/src/GlowEffect.cpp @@ -117,18 +117,6 @@ void GlowEffect::end() { glBlendColor(0.0f, 0.0f, 0.0f, _intensity = _intensityStack.pop()); } -static void maybeBind(const gpu::FramebufferPointer& fbo) { - if (fbo) { - glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(fbo)); - } -} - -static void maybeRelease(const gpu::FramebufferPointer& fbo) { - if (fbo) { - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } -} - gpu::FramebufferPointer GlowEffect::render() { PerformanceTimer perfTimer("glowEffect"); @@ -154,22 +142,11 @@ gpu::FramebufferPointer GlowEffect::render() { gpu::FramebufferPointer destFBO = textureCache->getSecondaryFramebuffer(); if (!_enabled || _isEmpty) { // copy the primary to the screen - if (QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) { - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO)); - glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO); - glBlitFramebuffer(0, 0, framebufferSize.width(), framebufferSize.height(), - 0, 0, framebufferSize.width(), framebufferSize.height(), - GL_COLOR_BUFFER_BIT, GL_NEAREST); - } else { - glBindFramebuffer(GL_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO)); - glViewport(0, 0, framebufferSize.width(), framebufferSize.height()); - glEnable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - renderFullscreenQuad(); - glDisable(GL_TEXTURE_2D); - glEnable(GL_LIGHTING); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - } + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(destFBO)); + glBindFramebuffer(GL_READ_FRAMEBUFFER, primaryFBO); + glBlitFramebuffer(0, 0, framebufferSize.width(), framebufferSize.height(), + 0, 0, framebufferSize.width(), framebufferSize.height(), + GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { // diffuse into the secondary/tertiary (alternating between frames) auto oldDiffusedFBO = diff --git a/libraries/render-utils/src/OffscreenGlContext.cpp b/libraries/render-utils/src/OffscreenGlContext.cpp new file mode 100644 index 0000000000..96f0a93c3a --- /dev/null +++ b/libraries/render-utils/src/OffscreenGlContext.cpp @@ -0,0 +1,43 @@ +// +// OffscreenGlCanvas.cpp +// interface/src/renderer +// +// Created by Bradley Austin Davis on 2014/04/09. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +#include "OffscreenGlContext.h" + +OffscreenGlContext::OffscreenGlContext() { +} + +void OffscreenGlContext::create(QOpenGLContext * sharedContext) { + QSurfaceFormat format; + format.setDepthBufferSize(16); + format.setStencilBufferSize(8); + format.setMajorVersion(4); + format.setMinorVersion(1); + format.setProfile(QSurfaceFormat::OpenGLContextProfile::CompatibilityProfile); + + _context.setFormat(format); + if (nullptr != sharedContext) { + _context.setShareContext(sharedContext); + } + _context.create(); + + _offscreenSurface.setFormat(_context.format()); + _offscreenSurface.create(); +} + +bool OffscreenGlContext::makeCurrent() { + return _context.makeCurrent(&_offscreenSurface); +} + +void OffscreenGlContext::doneCurrent() { + _context.doneCurrent(); +} + diff --git a/libraries/render-utils/src/OffscreenGlContext.h b/libraries/render-utils/src/OffscreenGlContext.h new file mode 100644 index 0000000000..c0d22b268f --- /dev/null +++ b/libraries/render-utils/src/OffscreenGlContext.h @@ -0,0 +1,33 @@ +// +// OffscreenGlCanvas.h +// interface/src/renderer +// +// Created by Bradley Austin Davis on 2014/04/09. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// +#pragma once +#ifndef hifi_OffscreenGlContext_h +#define hifi_OffscreenGlContext_h + +#include +#include + +class OffscreenGlContext : public QObject { +public: + OffscreenGlContext(); + void create(QOpenGLContext * sharedContext = nullptr); + bool makeCurrent(); + void doneCurrent(); + QOpenGLContext * getContext() { + return &_context; + } + +protected: + QOpenGLContext _context; + QOffscreenSurface _offscreenSurface; +}; + +#endif // hifi_OffscreenGlCanvas_h diff --git a/libraries/script-engine/src/MenuItemProperties.cpp b/libraries/script-engine/src/MenuItemProperties.cpp index 97fbdef1fa..48670e314d 100644 --- a/libraries/script-engine/src/MenuItemProperties.cpp +++ b/libraries/script-engine/src/MenuItemProperties.cpp @@ -23,7 +23,8 @@ MenuItemProperties::MenuItemProperties() : beforeItem(""), afterItem(""), isCheckable(false), - isChecked(false) + isChecked(false), + isSeparator(false) { }; @@ -38,7 +39,8 @@ MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& m beforeItem(""), afterItem(""), isCheckable(checkable), - isChecked(checked) + isChecked(checked), + isSeparator(false) { } @@ -53,7 +55,8 @@ MenuItemProperties::MenuItemProperties(const QString& menuName, const QString& m beforeItem(""), afterItem(""), isCheckable(checkable), - isChecked(checked) + isChecked(checked), + isSeparator(false) { } From abab54aed8ccc8c94fd2b02cb1ef7fb0da1bf7f4 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 11 May 2015 13:08:53 -0700 Subject: [PATCH 2/5] Working on display plugins --- interface/src/Application.cpp | 16 ++++++++++- interface/src/Application.h | 1 + interface/src/devices/TV3DManager.h | 4 +++ libraries/gpu/src/gpu/GLBackend.cpp | 27 +++++++++++++++++++ libraries/gpu/src/gpu/GLBackend.h | 3 +++ libraries/render-utils/src/RenderUtil.h | 2 ++ libraries/render-utils/src/TextRenderer.cpp | 27 +++++++++++-------- .../src/MatrixStack.cpp | 0 .../src/MatrixStack.h | 21 --------------- 9 files changed, 68 insertions(+), 33 deletions(-) rename libraries/{render-utils => shared}/src/MatrixStack.cpp (100%) rename libraries/{render-utils => shared}/src/MatrixStack.h (88%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 67af262595..ba90086017 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3069,7 +3069,11 @@ PickRay Application::computePickRay(float x, float y) const { if (isHMDMode()) { ApplicationOverlay::computeHmdPickRay(glm::vec2(x, y), result.origin, result.direction); } else { - getViewFrustum()->computePickRay(x, y, result.origin, result.direction); + if (activeRenderingThread) { + getDisplayViewFrustum()->computePickRay(x, y, result.origin, result.direction); + } else { + getViewFrustum()->computePickRay(x, y, result.origin, result.direction); + } } return result; } @@ -3124,6 +3128,16 @@ ViewFrustum* Application::getDisplayViewFrustum() { return &_displayViewFrustum; } +const ViewFrustum* Application::getDisplayViewFrustum() const { +#ifdef DEBUG + if (QThread::currentThread() != activeRenderingThread) { + // FIXME, should this be an assert? + qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?"; + } +#endif + return &_displayViewFrustum; +} + void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) { activeRenderingThread = QThread::currentThread(); PROFILE_RANGE(__FUNCTION__); diff --git a/interface/src/Application.h b/interface/src/Application.h index 5a3756e768..3edc968c24 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -205,6 +205,7 @@ public: // which might be different from the viewFrustum, i.e. shadowmap // passes, mirror window passes, etc ViewFrustum* getDisplayViewFrustum(); + const ViewFrustum* getDisplayViewFrustum() const; ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; } const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } EntityTreeRenderer* getEntities() { return &_entities; } diff --git a/interface/src/devices/TV3DManager.h b/interface/src/devices/TV3DManager.h index dfe5b28e87..0424eeecb4 100644 --- a/interface/src/devices/TV3DManager.h +++ b/interface/src/devices/TV3DManager.h @@ -45,6 +45,10 @@ private: static eyeFrustum _rightEye; static eyeFrustum* _activeEye; + // The first function is the code executed for each eye + // while the second is code to be executed between the two eyes. + // The use case here is to modify the output viewport coordinates + // for the new eye. template static void forEachEye(F f, FF ff = []{}) { f(_leftEye); diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 3c0ff4b309..08a9a39d68 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -10,6 +10,7 @@ // #include "GPULogging.h" #include "GLBackendShared.h" +#include GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = { @@ -521,3 +522,29 @@ void GLBackend::do_glColor4f(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +void GLBackend::loadMatrix(GLenum target, const glm::mat4 & m) { + glMatrixMode(target); + glLoadMatrixf(glm::value_ptr(m)); +} + +void GLBackend::fetchMatrix(GLenum target, glm::mat4 & m) { + switch (target) { + case GL_MODELVIEW_MATRIX: + case GL_PROJECTION_MATRIX: + break; + + // Lazy cheating + case GL_MODELVIEW: + target = GL_MODELVIEW_MATRIX; + break; + case GL_PROJECTION: + target = GL_PROJECTION_MATRIX; + break; + default: + Q_ASSERT_X(false, "GLBackend::fetchMatrix", "Bad matrix target"); + } + glGetFloatv(target, glm::value_ptr(m)); +} + + + diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 9943af1679..3551953998 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -79,6 +79,9 @@ public: static GLShader* syncGPUObject(const Shader& shader); static GLuint getShaderID(const ShaderPointer& shader); + static void loadMatrix(GLenum target, const glm::mat4 & m); + static void fetchMatrix(GLenum target, glm::mat4 & m); + class GLState : public GPUObject { public: class Command { diff --git a/libraries/render-utils/src/RenderUtil.h b/libraries/render-utils/src/RenderUtil.h index 8c1b1e12e7..cc823dc177 100644 --- a/libraries/render-utils/src/RenderUtil.h +++ b/libraries/render-utils/src/RenderUtil.h @@ -12,6 +12,8 @@ #ifndef hifi_RenderUtil_h #define hifi_RenderUtil_h +#include + /// Renders a quad from (-1, -1, 0) to (1, 1, 0) with texture coordinates from (sMin, tMin) to (sMax, tMax). void renderFullscreenQuad(float sMin = 0.0f, float sMax = 1.0f, float tMin = 0.0f, float tMax = 1.0f); diff --git a/libraries/render-utils/src/TextRenderer.cpp b/libraries/render-utils/src/TextRenderer.cpp index f459d466f4..87cf9b2728 100644 --- a/libraries/render-utils/src/TextRenderer.cpp +++ b/libraries/render-utils/src/TextRenderer.cpp @@ -548,18 +548,23 @@ float TextRenderer::draw(float x, float y, const QString & str, float scale = (_pointSize / DEFAULT_POINT_SIZE) * 0.25f; glm::vec2 result; - MatrixStack::withGlMatrices([&] { + + MatrixStack::withPushAll([&] { MatrixStack & mv = MatrixStack::modelview(); - // scale the modelview into font units - // FIXME migrate the constant scale factor into the geometry of the - // fonts so we don't have to flip the Y axis here and don't have to - // scale at all. - mv.translate(glm::vec2(x, y)).scale(glm::vec3(scale, -scale, scale)); - // The font does all the OpenGL work - if (_font) { - result = _font->drawString(x, y, str, actualColor, _effectType, bounds / scale); - } - }); + MatrixStack & pr = MatrixStack::projection(); + gpu::GLBackend::fetchMatrix(GL_MODELVIEW_MATRIX, mv.top()); + gpu::GLBackend::fetchMatrix(GL_PROJECTION_MATRIX, pr.top()); + + // scale the modelview into font units + // FIXME migrate the constant scale factor into the geometry of the + // fonts so we don't have to flip the Y axis here and don't have to + // scale at all. + mv.translate(glm::vec2(x, y)).scale(glm::vec3(scale, -scale, scale)); + // The font does all the OpenGL work + if (_font) { + result = _font->drawString(x, y, str, actualColor, _effectType, bounds / scale); + } + }); return result.x; } diff --git a/libraries/render-utils/src/MatrixStack.cpp b/libraries/shared/src/MatrixStack.cpp similarity index 100% rename from libraries/render-utils/src/MatrixStack.cpp rename to libraries/shared/src/MatrixStack.cpp diff --git a/libraries/render-utils/src/MatrixStack.h b/libraries/shared/src/MatrixStack.h similarity index 88% rename from libraries/render-utils/src/MatrixStack.h rename to libraries/shared/src/MatrixStack.h index feeda44058..7850af76f2 100644 --- a/libraries/render-utils/src/MatrixStack.h +++ b/libraries/shared/src/MatrixStack.h @@ -26,10 +26,6 @@ #include #include -#include - - - class MatrixStack : public std::stack { public: @@ -183,22 +179,5 @@ public: stack2.withPush(f); }); } - - template - static void withGlMatrices(Function f) { - // Push the current stack, and then copy the values out of OpenGL - withPushAll([&] { - // Fetch the current matrices out of GL stack - // FIXME, eliminate the usage of deprecated GL - MatrixStack & mv = MatrixStack::modelview(); - MatrixStack & pr = MatrixStack::projection(); - glm::mat4 & mvm = mv.top(); - glGetFloatv(GL_MODELVIEW_MATRIX, &(mvm[0][0])); - - glm::mat4 & prm = pr.top(); - glGetFloatv(GL_PROJECTION_MATRIX, &(prm[0][0])); - f(); - }); - } }; From 332d2091e538156213d79a08f9a1f1c094e3388e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 11 May 2015 13:22:43 -0700 Subject: [PATCH 3/5] Fixing license --- libraries/shared/src/MatrixStack.cpp | 8 ++++++++ libraries/shared/src/MatrixStack.h | 25 +++++++------------------ 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/libraries/shared/src/MatrixStack.cpp b/libraries/shared/src/MatrixStack.cpp index dc22b160d9..2a2817a413 100644 --- a/libraries/shared/src/MatrixStack.cpp +++ b/libraries/shared/src/MatrixStack.cpp @@ -1 +1,9 @@ +// +// Created by Bradley Austin Davis +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + #include "MatrixStack.h" diff --git a/libraries/shared/src/MatrixStack.h b/libraries/shared/src/MatrixStack.h index 7850af76f2..a02e284725 100644 --- a/libraries/shared/src/MatrixStack.h +++ b/libraries/shared/src/MatrixStack.h @@ -1,21 +1,10 @@ -/************************************************************************************ - - Authors : Bradley Austin Davis - Copyright : Copyright Brad Davis. All Rights reserved. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ************************************************************************************/ +// +// Created by Bradley Austin Davis +// Copyright 2013 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// #pragma once #include From 44238d02ae24d338adc47fc985ab0430e632b90d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 11 May 2015 14:30:59 -0700 Subject: [PATCH 4/5] Tweak the tv 3d manager to get around apparent GCC bug --- interface/src/devices/TV3DManager.cpp | 5 +++-- interface/src/devices/TV3DManager.h | 5 ++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 751a3d16bb..e01b4aace3 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -122,8 +122,9 @@ void TV3DManager::display(Camera& whichCamera) { qApp->displaySide(eyeCamera, false, RenderArgs::MONO); qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov); _activeEye = NULL; - }, [&]{ - // render right side view + + // HACK: the gcc compiler didn't like a pair of lambdas in the forEachEye template + // Adjust viewport for next view portalX = deviceSize.width() / 2; }); glPopMatrix(); diff --git a/interface/src/devices/TV3DManager.h b/interface/src/devices/TV3DManager.h index 0424eeecb4..ddebcd7eec 100644 --- a/interface/src/devices/TV3DManager.h +++ b/interface/src/devices/TV3DManager.h @@ -49,10 +49,9 @@ private: // while the second is code to be executed between the two eyes. // The use case here is to modify the output viewport coordinates // for the new eye. - template - static void forEachEye(F f, FF ff = []{}) { + template + static void forEachEye(F f) { f(_leftEye); - ff(); f(_rightEye); } }; From 69937d21f250a37338598a78f6d559bfe885c077 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 11 May 2015 14:40:10 -0700 Subject: [PATCH 5/5] Addressing the actual gcc bug --- interface/src/devices/TV3DManager.cpp | 5 ++--- interface/src/devices/TV3DManager.h | 8 ++++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index e01b4aace3..751a3d16bb 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -122,9 +122,8 @@ void TV3DManager::display(Camera& whichCamera) { qApp->displaySide(eyeCamera, false, RenderArgs::MONO); qApp->getApplicationOverlay().displayOverlayTextureStereo(whichCamera, _aspect, fov); _activeEye = NULL; - - // HACK: the gcc compiler didn't like a pair of lambdas in the forEachEye template - // Adjust viewport for next view + }, [&]{ + // render right side view portalX = deviceSize.width() / 2; }); glPopMatrix(); diff --git a/interface/src/devices/TV3DManager.h b/interface/src/devices/TV3DManager.h index ddebcd7eec..26a57ae259 100644 --- a/interface/src/devices/TV3DManager.h +++ b/interface/src/devices/TV3DManager.h @@ -49,9 +49,13 @@ private: // while the second is code to be executed between the two eyes. // The use case here is to modify the output viewport coordinates // for the new eye. - template - static void forEachEye(F f) { + // FIXME: we'd like to have a default empty lambda for the second parameter, + // but gcc 4.8.1 complains about it due to a bug. See + // http://stackoverflow.com/questions/25490662/lambda-as-default-parameter-to-a-member-function-template + template + static void forEachEye(F f, FF ff) { f(_leftEye); + ff(); f(_rightEye); } };