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) { }