From 78922704951ae0a3b02bbdb932a346d26e8c9078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 31 Jul 2014 02:12:31 +0200 Subject: [PATCH 01/51] Changes to CMake file to be able to compile 0.4 SDK. --- CMakeLists.txt | 23 +++++++++++- cmake/FindOculusSDK.cmake | 36 ++++++++++++++++--- src/CMakeLists.txt | 76 +++++++++++++++++++-------------------- 3 files changed, 91 insertions(+), 44 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e3c5450..fcc0310 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,16 @@ IF (WIN32) IF(NOT OCULUS_SDK_ROOT_DIR) MESSAGE(FATAL_ERROR "Error: Oculus SDK not found.") ENDIF(NOT OCULUS_SDK_ROOT_DIR) + + IF(MSVC) + OPTION(VISUAL_STUDIO_EXPRESS "Building with Visual Studio Express" OFF) + IF(VISUAL_STUDIO_EXPRESS) + # If building with Visual Studio Express we must specify location of ATL include directory and libraries + # These are not included in then Visual Studio Express install, but must be installed separately via Windows Driver Kit + SET(ATL_INCLUDE_DIR CACHE PATH "Path where to find the ATL include directory") + SET(ATL_LIBRARY_DIR CACHE PATH "Path where to find the ATL libries directory") + ENDIF(VISUAL_STUDIO_EXPRESS) + ENDIF(MSVC) ENDIF(WIN32) #Solution @@ -51,6 +61,12 @@ INCLUDE_DIRECTORIES(BEFORE ${OCULUS_SDK_INCLUDE_DIRS} ) +IF(VISUAL_STUDIO_EXPRESS) + INCLUDE_DIRECTORIES(BEFORE + ${ATL_INCLUDE_DIR} + ) +ENDIF(VISUAL_STUDIO_EXPRESS) + # osgViewer::ViewConfig concept requires osg 3.2 or later IF(NOT OPENSCENEGRAPH_VERSION VERSION_EQUAL 3.2.0 AND NOT OPENSCENEGRAPH_VERSION VERSION_GREATER 3.2.0) @@ -70,8 +86,13 @@ IF(MSVC) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"NOMINMAX\"") # Use Link Time Code Generation - SET(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LTCG") + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG") + # Add ATL libraries for Visual Studio Express builds + IF(VISUAL_STUDIO_EXPRESS) + SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LIBPATH:${ATL_LIBRARY_DIR}") + ENDIF(VISUAL_STUDIO_EXPRESS) + IF(MSVC80) # Detech 64-bit portability Issues SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wp64") diff --git a/cmake/FindOculusSDK.cmake b/cmake/FindOculusSDK.cmake index dfd0ec3..c9ab03a 100644 --- a/cmake/FindOculusSDK.cmake +++ b/cmake/FindOculusSDK.cmake @@ -20,10 +20,21 @@ FIND_PATH(OCULUS_SDK_INCLUDE_DIRS NAMES OVR.h HINTS # Determine architecture IF(CMAKE_SIZEOF_VOID_P MATCHES "8") - SET(OCULUS_SDK_LIB_ARCH "x86_64" CACHE STRING "library location") + IF(UNIX) + SET(OCULUS_SDK_LIB_ARCH "x86_64" CACHE STRING "library location") + ENDIF() + IF(MSVC) + SET(OCULUS_SDK_LIB_ARCH "x64" CACHE STRING "library location") + ENDIF() ELSE() - SET(OCULUS_SDK_LIB_ARCH "i386" CACHE STRING "library location") + IF(UNIX) + SET(OCULUS_SDK_LIB_ARCH "i386" CACHE STRING "library location") + ENDIF() + IF(MSVC) + SET(OCULUS_SDK_LIB_ARCH "Win32" CACHE STRING "library location") + ENDIF() ENDIF() + MARK_AS_ADVANCED(OCULUS_SDK_LIB_ARCH) # Append "d" to debug libs on windows platform @@ -31,16 +42,33 @@ IF (WIN32) SET(CMAKE_DEBUG_POSTFIX d) ENDIF() +# Determine the compiler version for Visual Studio +IF (MSVC) + # Visual Studio 2010 + IF(MSVC10) + SET(OCULUS_MSVC_DIR "VS2010" CACHE STRING "library location") + ENDIF() + # Visual Studio 2012 + IF(MSVC11) + SET(OCULUS_MSVC_DIR "VS2012" CACHE STRING "library location") + ENDIF() + # Visual Studio 2013 + IF(MSVC12) + SET(OCULUS_MSVC_DIR "VS2013" CACHE STRING "library location") + ENDIF() +ENDIF() +MARK_AS_ADVANCED(OCULUS_MSVC_DIR) + # Look for the library. FIND_LIBRARY(OCULUS_SDK_LIBRARY NAMES libovr ovr HINTS ${OCULUS_SDK_ROOT_DIR} - ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Win32 + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} ) # This will find release lib on Linux if no debug is available - on Linux this is no problem and avoids # having to compile in debug when not needed FIND_LIBRARY(OCULUS_SDK_LIBRARY_DEBUG NAMES libovr${CMAKE_DEBUG_POSTFIX} ovr${CMAKE_DEBUG_POSTFIX} ovr HINTS - ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Win32 + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Debug/${OCULUS_SDK_LIB_ARCH} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index af35b79..d3cf5c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,10 +48,10 @@ IF(USE_VIEW_CONFIG) # Link to Oculus libs TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} ${OCULUS_SDK_LIBRARIES} ) - # Link to libraries needed for Oculus on Windows - IF(WIN32) - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} winmm.lib ) - ENDIF(WIN32) + # Link to libraries needed for Oculus on Visual Studio + IF(MSVC) + TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} winmm.lib ws2_32.lib) + ENDIF(MSVC) # Link to libraries needed for Oculus on Linux IF(UNIX) @@ -114,40 +114,38 @@ ENDIF() #################################################################### # Create user file for correct environment string ##################################################################### -IF(WIN32) - IF(MSVC) - IF (OPENSCENEGRAPH_FOUND) - # Build path - SET(USERFILE_ENVIRONMENT_DEBUG "PATH=") - SET(USERFILE_ENVIRONMENT_RELEASE "PATH=") - - # Add OpenSceneGraph to path - IF (EXISTS "${OSG_DIR}/bin") - SET(OSG_BIN_DIR "${OSG_DIR}/bin" CACHE PATH "Path where to find OpenSceneGraph binaries") - ELSE (EXISTS "${OSG_DIR}/bin") - SET (OSG_BIN_DIR CACHE PATH "Path where to find OpenSceneGraph binaries") - ENDIF(EXISTS "${OSG_DIR}/bin") - SET(USERFILE_ENVIRONMENT_DEBUG "${USERFILE_ENVIRONMENT_DEBUG}${OSG_BIN_DIR}") - SET(USERFILE_ENVIRONMENT_RELEASE "${USERFILE_ENVIRONMENT_RELEASE}${OSG_BIN_DIR}") - - IF (OSG_THIRD_PARTY_DIR) - # Add third party to path - SET(USERFILE_ENVIRONMENT_DEBUG "${USERFILE_ENVIRONMENT_DEBUG};${OSG_THIRD_PARTY_DIR}/bin") - SET(USERFILE_ENVIRONMENT_RELEASE "${USERFILE_ENVIRONMENT_RELEASE};${OSG_THIRD_PARTY_DIR}/bin") - ELSE (OSG_THIRD_PARTY_DIR) - MESSAGE("Warning: OpenSceneGraph 3rd Party Directory not found.") - ENDIF(OSG_THIRD_PARTY_DIR) - - # For visual studio 2010 (MSVC10), 2012 (MSVC11) and 2013 (MSVC12) - IF(MSVC10 OR MSVC11 OR MSVC12) - IF (USE_VIEW_CONFIG) - CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME}.vcxproj.user @ONLY) - ENDIF() - IF (BUILD_DEPRECATED) - CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_DEPRECATED}.vcxproj.user @ONLY) - ENDIF() +IF(MSVC) + IF (OPENSCENEGRAPH_FOUND) + # Build path + SET(USERFILE_ENVIRONMENT_DEBUG "PATH=") + SET(USERFILE_ENVIRONMENT_RELEASE "PATH=") + + # Add OpenSceneGraph to path + IF (EXISTS "${OSG_DIR}/bin") + SET(OSG_BIN_DIR "${OSG_DIR}/bin" CACHE PATH "Path where to find OpenSceneGraph binaries") + ELSE (EXISTS "${OSG_DIR}/bin") + SET (OSG_BIN_DIR CACHE PATH "Path where to find OpenSceneGraph binaries") + ENDIF(EXISTS "${OSG_DIR}/bin") + SET(USERFILE_ENVIRONMENT_DEBUG "${USERFILE_ENVIRONMENT_DEBUG}${OSG_BIN_DIR}") + SET(USERFILE_ENVIRONMENT_RELEASE "${USERFILE_ENVIRONMENT_RELEASE}${OSG_BIN_DIR}") + + IF (OSG_THIRD_PARTY_DIR) + # Add third party to path + SET(USERFILE_ENVIRONMENT_DEBUG "${USERFILE_ENVIRONMENT_DEBUG};${OSG_THIRD_PARTY_DIR}/bin") + SET(USERFILE_ENVIRONMENT_RELEASE "${USERFILE_ENVIRONMENT_RELEASE};${OSG_THIRD_PARTY_DIR}/bin") + ELSE (OSG_THIRD_PARTY_DIR) + MESSAGE("Warning: OpenSceneGraph 3rd Party Directory not found.") + ENDIF(OSG_THIRD_PARTY_DIR) + + # For visual studio 2010 (MSVC10), 2012 (MSVC11) and 2013 (MSVC12) + IF(MSVC10 OR MSVC11 OR MSVC12) + IF (USE_VIEW_CONFIG) + CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME}.vcxproj.user @ONLY) + ENDIF() + IF (BUILD_DEPRECATED) + CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_DEPRECATED}.vcxproj.user @ONLY) ENDIF() + ENDIF() - ENDIF (OPENSCENEGRAPH_FOUND) - ENDIF(MSVC) -ENDIF(WIN32) + ENDIF (OPENSCENEGRAPH_FOUND) +ENDIF(MSVC) From aaa94b4f8bfade8fa4e32c8c3a7566230d399f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 31 Jul 2014 02:13:31 +0200 Subject: [PATCH 02/51] Initial changes needed to compile for 0.4 SDK --- src/oculusdevice.cpp | 312 ++++++++++++--------------------------- src/oculusdevice.h | 62 +++----- src/oculusviewconfig.cpp | 56 ++----- src/oculusviewconfig.h | 13 +- 4 files changed, 125 insertions(+), 318 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 50f3a10..216a34c 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -8,237 +8,142 @@ #include "oculusdevice.h" -OculusDevice::OculusDevice() : - m_deviceManager(0), m_hmdDevice(0), m_sensor(0), m_hmdInfo(0), m_sensorFusion(0), - m_useCustomScaleFactor(false), m_customScaleFactor(1.0f), - m_nearClip(0.3f), m_farClip(5000.0f), m_predictionDelta(0.03f) +OculusDevice::OculusDevice() : m_hmdDevice(0), + m_nearClip(0.01f), m_farClip(10000.0f) { - // Init Oculus HMD - OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); - m_deviceManager = *OVR::DeviceManager::Create(); - m_hmdDevice = *m_deviceManager->EnumerateDevices().CreateDevice(); + ovr_Initialize(); + + // Enumerate HMD devices + int hmd_ovrHmd_Detect(); - if (m_hmdDevice) { - m_hmdInfo = new OVR::HMDInfo; - - if (!m_hmdDevice->GetDeviceInfo(m_hmdInfo)) { - osg::notify(osg::FATAL) << "Error: Unable to get device info" << std::endl; - } else { - m_sensor = *m_hmdDevice->GetSensor(); - } - } else { - osg::notify(osg::WARN) << "Warning: Unable to find HMD Device, will use default renderpath instead." << std::endl; - - // Try to connect to sensor only, used for emulated devices - m_sensor = *m_deviceManager->EnumerateDevices().CreateDevice(); - } - - // Attach sensor - if (m_sensor) { - m_sensorFusion = new OVR::SensorFusion; - m_sensorFusion->AttachToSensor(m_sensor); - m_sensorFusion->SetPredictionEnabled(true); - // Get default sensor prediction delta - m_predictionDelta = m_sensorFusion->GetPredictionDelta(); - } else { - osg::notify(osg::WARN) << "Warning: Unable to connect to tracker sensor." << std::endl; - } -} - -OculusDevice::~OculusDevice() -{ - if (m_sensorFusion) { - // Detach sensor - m_sensorFusion->AttachToSensor(NULL); - delete m_sensorFusion; - m_sensorFusion = NULL; - } - - delete m_hmdInfo; - m_hmdInfo = NULL; - m_sensor.Clear(); - m_hmdDevice.Clear(); - m_deviceManager.Clear(); - - // Do a nice shutdown of the Oculus HMD - if (OVR::System::IsInitialized()) { - OVR::System::Destroy(); + // Get first available HMD + m_hmdDevice = ovrHmd_Create(0); + + // If no HMD is found try an emulated device + if (!m_hmdDevice) { + osg::notify(osg::WARN) << "Warning: No device could be found. Creating emulated device " << std::endl; + m_hmdDevice = ovrHmd_CreateDebug(ovrHmd_DK1); } -} -unsigned int OculusDevice::hScreenResolution() const -{ - if (m_hmdInfo) { - return m_hmdInfo->HResolution; - } - - // Default value from dev kit - return 1280; -} + if (m_hmdDevice) { + // Print out some information about the HMD + osg::notify(osg::ALWAYS) << "Product: " << m_hmdDevice->ProductName << std::endl; + osg::notify(osg::ALWAYS) << "Manufacturer: " << m_hmdDevice->Manufacturer << std::endl; + osg::notify(osg::ALWAYS) << "VendorId: " << m_hmdDevice->VendorId << std::endl; + osg::notify(osg::ALWAYS) << "ProductId: " << m_hmdDevice->ProductId << std::endl; + osg::notify(osg::ALWAYS) << "SerialNumber: " << m_hmdDevice->SerialNumber << std::endl; + osg::notify(osg::ALWAYS) << "FirmwareVersion: " << m_hmdDevice->FirmwareMajor << "." << m_hmdDevice->FirmwareMinor << std::endl; + + // Get more details about the HMD. + m_resolution = m_hmdDevice->Resolution; + + // Compute recommended rendertexture size + float pixelsPerDisplayPixel = 1.0f; // Decrease this value to scale the size on render texture on lower performance hardware. Values above 1.0 is unnessesary. -unsigned int OculusDevice::vScreenResolution() const -{ - if (m_hmdInfo) { - return m_hmdInfo->VResolution; - } + ovrSizei recommenedLeftTextureSize = ovrHmd_GetFovTextureSize(m_hmdDevice, ovrEye_Left, m_hmdDevice->DefaultEyeFov[0], pixelsPerDisplayPixel); + ovrSizei recommenedRightTextureSize = ovrHmd_GetFovTextureSize(m_hmdDevice, ovrEye_Right, m_hmdDevice->DefaultEyeFov[1], pixelsPerDisplayPixel); - // Default value from dev kit - return 800; -} + // Compute size of render target + m_renderTargetSize.w = recommenedLeftTextureSize.w + recommenedRightTextureSize.w; + m_renderTargetSize.h = osg::maximum(recommenedLeftTextureSize.h, recommenedRightTextureSize.h); -float OculusDevice::hScreenSize() const -{ - if (m_hmdInfo) { - return m_hmdInfo->HScreenSize; - } + // Initialize ovrEyeRenderDesc struct. + ovrEyeRenderDesc eyeRenderDesc[2]; + eyeRenderDesc[0] = ovrHmd_GetRenderDesc(m_hmdDevice, ovrEye_Left, m_hmdDevice->DefaultEyeFov[0]); + eyeRenderDesc[1] = ovrHmd_GetRenderDesc(m_hmdDevice, ovrEye_Right, m_hmdDevice->DefaultEyeFov[1]); + + ovrVector3f leftEyeAdjust = eyeRenderDesc[0].ViewAdjust; + m_leftEyeAdjust.set(leftEyeAdjust.x, leftEyeAdjust.y, leftEyeAdjust.z); + ovrVector3f rightEyeAdjust = eyeRenderDesc[1].ViewAdjust; + m_rightEyeAdjust.set(rightEyeAdjust.x, rightEyeAdjust.y, rightEyeAdjust.z); - // Default value from dev kit - return 0.14976f; -} + bool isRightHanded = true; + + ovrMatrix4f leftEyeProjectionMatrix = ovrMatrix4f_Projection(eyeRenderDesc[0].Fov, m_nearClip, m_farClip, isRightHanded); + // Test of transpose + m_leftEyeProjectionMatrix.set(leftEyeProjectionMatrix.M[0][0], leftEyeProjectionMatrix.M[1][0], leftEyeProjectionMatrix.M[2][0], leftEyeProjectionMatrix.M[3][0], + leftEyeProjectionMatrix.M[0][1], leftEyeProjectionMatrix.M[1][1], leftEyeProjectionMatrix.M[2][1], leftEyeProjectionMatrix.M[3][1], + leftEyeProjectionMatrix.M[0][2], leftEyeProjectionMatrix.M[1][2], leftEyeProjectionMatrix.M[2][2], leftEyeProjectionMatrix.M[3][2], + leftEyeProjectionMatrix.M[0][3], leftEyeProjectionMatrix.M[1][3], leftEyeProjectionMatrix.M[2][3], leftEyeProjectionMatrix.M[3][3]); + //m_leftEyeProjectionMatrix.set(*leftEyeProjectionMatrix.M); -float OculusDevice::vScreenSize() const -{ - if (m_hmdInfo) { - return m_hmdInfo->VScreenSize; - } + ovrMatrix4f rightEyeProjectionMatrix = ovrMatrix4f_Projection(eyeRenderDesc[1].Fov, m_nearClip, m_farClip, isRightHanded); + + m_rightEyeProjectionMatrix.set(rightEyeProjectionMatrix.M[0][0], rightEyeProjectionMatrix.M[1][0], rightEyeProjectionMatrix.M[2][0], rightEyeProjectionMatrix.M[3][0], + rightEyeProjectionMatrix.M[0][1], rightEyeProjectionMatrix.M[1][1], rightEyeProjectionMatrix.M[2][1], rightEyeProjectionMatrix.M[3][1], + rightEyeProjectionMatrix.M[0][2], rightEyeProjectionMatrix.M[1][2], rightEyeProjectionMatrix.M[2][2], rightEyeProjectionMatrix.M[3][2], + rightEyeProjectionMatrix.M[0][3], rightEyeProjectionMatrix.M[1][3], rightEyeProjectionMatrix.M[2][3], rightEyeProjectionMatrix.M[3][3]); - // Default value from dev kit - return 0.0936f; -} -float OculusDevice::vScreenCenter() const -{ - if (m_hmdInfo) { - return m_hmdInfo->VScreenCenter; - } + //m_rightEyeProjectionMatrix.set(*rightEyeProjectionMatrix.M); - return vScreenSize()*0.5f; -} + // Start the sensor which provides the Rift’s pose and motion. + ovrHmd_ConfigureTracking(m_hmdDevice, ovrTrackingCap_Orientation | + ovrTrackingCap_MagYawCorrection | + ovrTrackingCap_Position, 0); -float OculusDevice::eyeToScreenDistance() const -{ - if (m_hmdInfo) { - return m_hmdInfo->EyeToScreenDistance; } - - // Default value from dev kit - return 0.041f; } -float OculusDevice::lensSeparationDistance() const +OculusDevice::~OculusDevice() { - if (m_hmdInfo) { - return m_hmdInfo->LensSeparationDistance; - } - - // Default value from dev kit - return 0.0635f; + ovrHmd_Destroy(m_hmdDevice); + ovr_Shutdown(); } - -float OculusDevice::interpupillaryDistance() const +unsigned int OculusDevice::hScreenResolution() const { - if (m_hmdInfo) { - return m_hmdInfo->InterpupillaryDistance; + if (m_hmdDevice) { + return m_hmdDevice->Resolution.w; } - - // Default value from dev kit, typical values for average human male - return 0.064f; + + // Default value from dev kit 1 + return 1280; } -osg::Matrix OculusDevice::viewMatrix(EyeSide eye) const +unsigned int OculusDevice::vScreenResolution() const { - osg::Matrix viewMatrix; - - if (eye == LEFT_EYE) { - viewMatrix.makeTranslate(osg::Vec3f(halfIPD(), 0.0f, 0.0f)); - } else if (eye == RIGHT_EYE) { - viewMatrix.makeTranslate(osg::Vec3f(-halfIPD(), 0.0f, 0.0f)); - } else { - viewMatrix.makeTranslate(osg::Vec3f(0.0f, 0.0f, 0.0f)); + if (m_hmdDevice) { + return m_hmdDevice->Resolution.h; } - return viewMatrix; -} - -osg::Matrix OculusDevice::projectionMatrix(EyeSide eye) const -{ - osg::Matrixf projectionMatrix = projectionOffsetMatrix(eye); - projectionMatrix.preMult(projectionCenterMatrix()); - return projectionMatrix; + // Default value from dev kit 1 + return 800; } -osg::Matrix OculusDevice::projectionCenterMatrix() const -{ - osg::Matrix projectionMatrix; - float halfScreenDistance = vScreenSize() * 0.5f * distortionScale(); - float yFov = (180.0f/3.14159f) * 2.0f * atan(halfScreenDistance / eyeToScreenDistance()); - projectionMatrix.makePerspective(yFov, aspectRatio(), m_nearClip, m_farClip); - return projectionMatrix; -} -osg::Matrix OculusDevice::projectionOffsetMatrix(EyeSide eye) const +unsigned int OculusDevice::hRenderTargetSize() const { - osg::Matrix projectionMatrix; - float eyeProjectionShift = viewCenter() - lensSeparationDistance()*0.5f; - float projectionCenterOffset = 4.0f * eyeProjectionShift / hScreenSize(); - - if (eye == LEFT_EYE) { - projectionMatrix.makeTranslate(osg::Vec3d(projectionCenterOffset, 0, 0)); - } else if (eye == RIGHT_EYE) { - projectionMatrix.makeTranslate(osg::Vec3d(-projectionCenterOffset, 0, 0)); - } else { - projectionMatrix.makeIdentity(); - } - - return projectionMatrix; -} - -osg::Vec2f OculusDevice::lensCenter(EyeSide eye) const -{ - if (eye == LEFT_EYE) { - return osg::Vec2f(1.0f-lensSeparationDistance()/hScreenSize(), 0.5f); - } else if (eye == RIGHT_EYE) { - return osg::Vec2f(lensSeparationDistance()/hScreenSize(), 0.5f); - } - - return osg::Vec2f(0.5f, 0.5f); + return m_renderTargetSize.w; } -osg::Vec2f OculusDevice::screenCenter() const +unsigned int OculusDevice::vRenderTargetSize() const { - return osg::Vec2f(0.5f, 0.5f); + return m_renderTargetSize.h; } -osg::Vec2f OculusDevice::scale() const +osg::Matrix OculusDevice::projectionMatrixLeft() const { - float scaleFactor = 1.0f/distortionScale(); - return osg::Vec2f(0.5*scaleFactor, 0.5f*scaleFactor*aspectRatio()); + return m_leftEyeProjectionMatrix; } -osg::Vec2f OculusDevice::scaleIn() const +osg::Matrix OculusDevice::projectionMatrixRight() const { - return osg::Vec2f(2.0f, 2.0f/aspectRatio()); + return m_rightEyeProjectionMatrix; } -osg::Vec4f OculusDevice::warpParameters() const +osg::Matrix OculusDevice::viewMatrixLeft() const { - if (m_hmdInfo) { - return osg::Vec4f(m_hmdInfo->DistortionK[0], m_hmdInfo->DistortionK[1], m_hmdInfo->DistortionK[2], m_hmdInfo->DistortionK[3]); - } - - // Default values from devkit - return osg::Vec4f(1.0f, 0.22f, 0.24f, 0.0f); + osg::Matrix viewMatrix; + viewMatrix.makeTranslate(m_leftEyeAdjust); + return viewMatrix; } -osg::Vec4f OculusDevice::chromAbParameters() const +osg::Matrix OculusDevice::viewMatrixRight() const { - if (m_hmdInfo) { - return osg::Vec4f(m_hmdInfo->ChromaAbCorrection[0], m_hmdInfo->ChromaAbCorrection[1], m_hmdInfo->ChromaAbCorrection[2], m_hmdInfo->ChromaAbCorrection[3]); - } - - // Default values from devkit - return osg::Vec4f(0.996f, -0.004f, 1.014f, 0.0f); + osg::Matrix viewMatrix; + viewMatrix.makeTranslate(m_rightEyeAdjust); + return viewMatrix; } osg::Quat OculusDevice::getOrientation() const @@ -246,40 +151,5 @@ osg::Quat OculusDevice::getOrientation() const // Create identity quaternion osg::Quat osgQuat(0.0f, 0.0f, 0.0f, 1.0f); - if (m_sensorFusion && m_sensorFusion->IsAttachedToSensor()) { - OVR::Quatf quat; - - if (m_sensorFusion->IsPredictionEnabled()) { - quat = m_sensorFusion->GetPredictedOrientation(m_predictionDelta); - } else { - quat = m_sensorFusion->GetOrientation(); - } - - osgQuat.set(quat.x, quat.y, quat.z, -quat.w); - } - return osgQuat; -} - -void OculusDevice::setSensorPredictionEnabled(bool prediction) -{ - if (m_sensorFusion) { - m_sensorFusion->SetPredictionEnabled(prediction); - } -} - -float OculusDevice::distortionScale() const -{ - // Disable distortion scale calculation and use user suppied value instead - if (m_useCustomScaleFactor) { - return m_customScaleFactor; - } - - float lensShift = hScreenSize() * 0.25f - lensSeparationDistance() * 0.5f; - float lensViewportShift = 4.0f * lensShift / hScreenSize(); - float fitRadius = fabs(-1 - lensViewportShift); - float rsq = fitRadius*fitRadius; - osg::Vec4f k = warpParameters(); - float scale = (k[0] + k[1] * rsq + k[2] * rsq * rsq + k[3] * rsq * rsq * rsq); - return scale; } \ No newline at end of file diff --git a/src/oculusdevice.h b/src/oculusdevice.h index f681bc7..776f3cc 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -8,8 +8,10 @@ #ifndef _OSG_OCULUSDEVICE_H_ #define _OSG_OCULUSDEVICE_H_ -#include +// Include the OculusVR SDK +#include "OVR.h" #include +#include class OculusDevice : public osg::Referenced { @@ -17,63 +19,37 @@ class OculusDevice : public osg::Referenced { public: OculusDevice(); - enum EyeSide { - CENTER_EYE = 0, - LEFT_EYE = 1, - RIGHT_EYE = 2 - }; - unsigned int hScreenResolution() const; unsigned int vScreenResolution() const; - float hScreenSize() const; - float vScreenSize() const; - float vScreenCenter() const; - float eyeToScreenDistance() const; - float lensSeparationDistance() const; - float interpupillaryDistance() const; - - osg::Matrix viewMatrix(EyeSide eye = CENTER_EYE) const; - osg::Matrix projectionMatrix(EyeSide eye = CENTER_EYE) const; - osg::Matrix projectionOffsetMatrix(EyeSide eye = CENTER_EYE) const; - osg::Matrix projectionCenterMatrix() const; - osg::Vec2f lensCenter(EyeSide eye = CENTER_EYE) const; - osg::Vec2f screenCenter() const; - osg::Vec4f warpParameters() const; - osg::Vec4f chromAbParameters() const; - osg::Vec2f scale() const; - osg::Vec2f scaleIn() const; + unsigned int hRenderTargetSize() const; + unsigned int vRenderTargetSize() const; - float scaleFactor() const { return distortionScale(); } + osg::Matrix projectionMatrixLeft() const; + osg::Matrix projectionMatrixRight() const; - float aspectRatio() const { return float (hScreenResolution()/2) / float (vScreenResolution()); } - osg::Quat getOrientation() const; + osg::Matrix viewMatrixLeft() const; + osg::Matrix viewMatrixRight() const; void setNearClip(float nearClip) { m_nearClip = nearClip; } void setFarClip(float farclip) { m_farClip = farclip; } - void setSensorPredictionEnabled(bool prediction); - void setSensorPredictionDelta(float delta) { m_predictionDelta = delta; } - void setCustomScaleFactor(const float& customScaleFactor) { m_useCustomScaleFactor = true; m_customScaleFactor = customScaleFactor; } - - void resetSensorOrientation() { if (m_sensorFusion) m_sensorFusion->Reset(); } + void resetSensorOrientation() { } + osg::Quat getOrientation() const; protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected - float viewCenter() const { return hScreenSize() * 0.25f; } - float halfIPD() const { return interpupillaryDistance() * 0.5f; } - float distortionScale() const; - OVR::Ptr m_deviceManager; - OVR::Ptr m_hmdDevice; - OVR::Ptr m_sensor; - OVR::HMDInfo* m_hmdInfo; - OVR::SensorFusion* m_sensorFusion; - bool m_useCustomScaleFactor; - float m_customScaleFactor; + ovrHmd m_hmdDevice; + ovrSizei m_resolution; + ovrSizei m_renderTargetSize; + osg::Matrixf m_leftEyeProjectionMatrix; + osg::Matrixf m_rightEyeProjectionMatrix; + osg::Vec3f m_leftEyeAdjust; + osg::Vec3f m_rightEyeAdjust; + float m_nearClip; float m_farClip; - float m_predictionDelta; private: OculusDevice(const OculusDevice&); // Do not allow copy }; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index b334bb2..b53a458 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -69,29 +69,10 @@ osg::Geode* OculusViewConfig::createHUDQuad( float width, float height, float sc return quad.release(); } -void OculusViewConfig::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, - osg::Texture2D* texture, OculusDevice::EyeSide eye) const { - stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); - stateSet->setAttributeAndModes( program, osg::StateAttribute::ON ); - stateSet->addUniform( new osg::Uniform("WarpTexture", 0) ); - stateSet->addUniform( new osg::Uniform("LensCenter", m_device->lensCenter(eye))); - stateSet->addUniform( new osg::Uniform("ScreenCenter", m_device->screenCenter())); - stateSet->addUniform( new osg::Uniform("Scale", m_device->scale())); - stateSet->addUniform( new osg::Uniform("ScaleIn", m_device->scaleIn())); - stateSet->addUniform( new osg::Uniform("HmdWarpParam", m_device->warpParameters())); - stateSet->addUniform( new osg::Uniform("ChromAbParam", m_device->chromAbParameters())); -} - void OculusViewConfig::configure(osgViewer::View& view) const { m_device->setNearClip(m_nearClip); m_device->setFarClip(m_farClip); - m_device->setSensorPredictionEnabled(m_useSensorPrediction); - m_device->setSensorPredictionDelta(m_predictionDelta); - - if (m_useCustomScaleFactor) { - m_device->setCustomScaleFactor(m_customScaleFactor); - } // Create screen with match the Oculus Rift resolution osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); @@ -143,10 +124,10 @@ void OculusViewConfig::configure(osgViewer::View& view) const camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); // Disable automatic computation of near and far plane on main camera, will propagate to slave cameras camera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); - const int textureWidth = m_device->scaleFactor() * m_device->hScreenResolution()/2; - const int textureHeight = m_device->scaleFactor() * m_device->vScreenResolution(); + const int textureWidth = m_device->hRenderTargetSize()/2; + const int textureHeight = m_device->vRenderTargetSize(); // master projection matrix - camera->setProjectionMatrix(m_device->projectionCenterMatrix()); + camera->setProjectionMatrix(m_device->projectionMatrixLeft()); // Create textures for RTT cameras osg::ref_ptr textureLeft = new osg::Texture2D; textureLeft->setTextureSize( textureWidth, textureHeight ); @@ -176,37 +157,24 @@ void OculusViewConfig::configure(osgViewer::View& view) const cameraHUDLeft->addChild(leftQuad); osg::ref_ptr rightQuad = createHUDQuad(1.0f, 1.0f); cameraHUDRight->addChild(rightQuad); - + // Set up shaders from the Oculus SDK documentation - osg::ref_ptr program = new osg::Program; - osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp.vert")); - osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); - - // Fragment shader with or without correction for chromatic aberration - if (m_useChromaticAberrationCorrection) { - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithChromeAb.frag")); - } else { - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithoutChromeAb.frag")); - } - program->addShader(vertexShader); - program->addShader(fragmentShader); - // Attach shaders to each HUD osg::StateSet* leftEyeStateSet = leftQuad->getOrCreateStateSet(); + leftEyeStateSet->setTextureAttributeAndModes(0, textureLeft, osg::StateAttribute::ON); + osg::StateSet* rightEyeStateSet = rightQuad->getOrCreateStateSet(); - applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT_EYE); - applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT_EYE); - + rightEyeStateSet->setTextureAttributeAndModes(0, textureRight, osg::StateAttribute::ON); + // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, - m_device->projectionOffsetMatrix(OculusDevice::LEFT_EYE), - m_device->viewMatrix(OculusDevice::LEFT_EYE), + m_device->projectionMatrixLeft(), + m_device->viewMatrixLeft(), true); view.addSlave(cameraRTTRight, - m_device->projectionOffsetMatrix(OculusDevice::RIGHT_EYE), - m_device->viewMatrix(OculusDevice::RIGHT_EYE), + m_device->projectionMatrixRight(), + m_device->viewMatrixRight(), true); // Add HUD cameras as slaves diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index 9c59c80..81b9a0e 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -17,12 +17,10 @@ class OculusViewConfig : public osgViewer::ViewConfig { m_configured(false), m_useChromaticAberrationCorrection(true), m_useOrientations(true), - m_useSensorPrediction(true), m_useCustomScaleFactor(false), - m_customScaleFactor(1.25f), - m_nearClip(0.3f), - m_farClip(5000.0f), - m_predictionDelta(0.03f), + m_customScaleFactor(1.0f), + m_nearClip(0.01f), + m_farClip(10000.0f), m_sceneNodeMask(0x1), m_device(0) { m_device = new OculusDevice; @@ -31,8 +29,6 @@ class OculusViewConfig : public osgViewer::ViewConfig { void setEnableChromaticAberrationCorrection(bool correctionEnabled) { m_useChromaticAberrationCorrection = correctionEnabled; } void setNearClip(float nearClip) { m_nearClip = nearClip; } void setFarClip(float farclip) { m_farClip = farclip; } - void setSensorPredictionEnabled(bool prediction); - void setSensorPredictionDelta(float delta) { m_predictionDelta = delta; } void resetSensorOrientation() { if (m_device) m_device->resetSensorOrientation(); } void setUseDefaultScaleFactor(bool useDefault) { m_useCustomScaleFactor = !useDefault; } void setCustomScaleFactor(const float& customScaleFactor) { m_useCustomScaleFactor = true; m_customScaleFactor = customScaleFactor; } @@ -44,13 +40,10 @@ class OculusViewConfig : public osgViewer::ViewConfig { osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc) const; osg::Camera* createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; osg::Geode* createHUDQuad( float width, float height, float scale = 1.0f ) const; - void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, - osg::Texture2D* texture, OculusDevice::EyeSide eye) const; bool m_configured; bool m_useOrientations; bool m_useChromaticAberrationCorrection; - bool m_useSensorPrediction; bool m_useCustomScaleFactor; float m_customScaleFactor; float m_nearClip; From de2a07d7d170c035bec88618f4b10210d38fb1f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 31 Jul 2014 11:36:10 +0200 Subject: [PATCH 03/51] Added left and right projection offset matrix and a center projection matrix. --- src/oculusdevice.cpp | 23 +++++++++++++++++++++++ src/oculusdevice.h | 4 ++++ src/oculusviewconfig.cpp | 6 +++--- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 216a34c..99095dd 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -122,6 +122,14 @@ unsigned int OculusDevice::vRenderTargetSize() const return m_renderTargetSize.h; } +osg::Matrix OculusDevice::projectionMatrixCenter() const +{ + osg::Matrix projectionMatrixCenter; + projectionMatrixCenter = m_leftEyeProjectionMatrix; + projectionMatrixCenter(2, 0) = 0; // Ugly hack to make left projection matrix into a center projection matrix + return projectionMatrixCenter; +} + osg::Matrix OculusDevice::projectionMatrixLeft() const { return m_leftEyeProjectionMatrix; @@ -132,6 +140,21 @@ osg::Matrix OculusDevice::projectionMatrixRight() const return m_rightEyeProjectionMatrix; } +osg::Matrix OculusDevice::projectionOffsetMatrixLeft() const +{ + osg::Matrix projectionOffsetMatrix; + float offset = m_leftEyeProjectionMatrix(2, 0); // Ugly hack to extract projection offset + projectionOffsetMatrix(3, 0) = offset; + return projectionOffsetMatrix; +} + +osg::Matrix OculusDevice::projectionOffsetMatrixRight() const +{ + osg::Matrix projectionOffsetMatrix; + float offset = m_rightEyeProjectionMatrix(2, 0); // Ugly hack to extract projection offset + projectionOffsetMatrix(3, 0) = offset; + return projectionOffsetMatrix; +} osg::Matrix OculusDevice::viewMatrixLeft() const { osg::Matrix viewMatrix; diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 776f3cc..6d62dc7 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -25,9 +25,13 @@ class OculusDevice : public osg::Referenced { unsigned int hRenderTargetSize() const; unsigned int vRenderTargetSize() const; + osg::Matrix projectionMatrixCenter() const; osg::Matrix projectionMatrixLeft() const; osg::Matrix projectionMatrixRight() const; + osg::Matrix projectionOffsetMatrixLeft() const; + osg::Matrix projectionOffsetMatrixRight() const; + osg::Matrix viewMatrixLeft() const; osg::Matrix viewMatrixRight() const; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index b53a458..35d8d82 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -127,7 +127,7 @@ void OculusViewConfig::configure(osgViewer::View& view) const const int textureWidth = m_device->hRenderTargetSize()/2; const int textureHeight = m_device->vRenderTargetSize(); // master projection matrix - camera->setProjectionMatrix(m_device->projectionMatrixLeft()); + camera->setProjectionMatrix(m_device->projectionMatrixCenter()); // Create textures for RTT cameras osg::ref_ptr textureLeft = new osg::Texture2D; textureLeft->setTextureSize( textureWidth, textureHeight ); @@ -169,11 +169,11 @@ void OculusViewConfig::configure(osgViewer::View& view) const // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, - m_device->projectionMatrixLeft(), + m_device->projectionOffsetMatrixLeft(), m_device->viewMatrixLeft(), true); view.addSlave(cameraRTTRight, - m_device->projectionMatrixRight(), + m_device->projectionOffsetMatrixRight(), m_device->viewMatrixRight(), true); From 7dcb3f2248e91ca06525f3ad87edaa8b124d65b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 31 Jul 2014 21:51:10 +0200 Subject: [PATCH 04/51] Added basic warping via distortion mesh. --- src/CMakeLists.txt | 5 +- src/oculusdevice.cpp | 113 ++++++++++++++++++++++++++++++----- src/oculusdevice.h | 9 +++ src/oculusviewconfig.cpp | 74 +++++++++++------------ src/oculusviewconfig.h | 1 - src/warp.vert | 7 --- src/warpWithChromeAb.frag | 38 ------------ src/warpWithoutChromeAb.frag | 31 ---------- src/warp_mesh.frag | 16 +++++ src/warp_mesh.vert | 32 ++++++++++ 10 files changed, 192 insertions(+), 134 deletions(-) delete mode 100644 src/warp.vert delete mode 100644 src/warpWithChromeAb.frag delete mode 100644 src/warpWithoutChromeAb.frag create mode 100644 src/warp_mesh.frag create mode 100644 src/warp_mesh.vert diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d3cf5c8..ec3fcfb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -106,9 +106,8 @@ ENDIF() ##################################################################### STRING(COMPARE NOTEQUAL ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} CMAKE_OUT_OF_SOURCE_BUILD) IF (CMAKE_OUT_OF_SOURCE_BUILD) - CONFIGURE_FILE(warp.vert warp.vert COPYONLY) - CONFIGURE_FILE(warpWithChromeAb.frag warpWithChromeAb.frag COPYONLY) - CONFIGURE_FILE(warpWithoutChromeAb.frag warpWithoutChromeAb.frag COPYONLY) + CONFIGURE_FILE(warp_mesh.vert warp_mesh.vert COPYONLY) + CONFIGURE_FILE(warp_mesh.frag warp_mesh.frag COPYONLY) ENDIF() #################################################################### diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 99095dd..79970d2 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -7,6 +7,8 @@ #include "oculusdevice.h" +#include + OculusDevice::OculusDevice() : m_hmdDevice(0), m_nearClip(0.01f), m_farClip(10000.0f) @@ -48,40 +50,34 @@ OculusDevice::OculusDevice() : m_hmdDevice(0), m_renderTargetSize.h = osg::maximum(recommenedLeftTextureSize.h, recommenedRightTextureSize.h); // Initialize ovrEyeRenderDesc struct. - ovrEyeRenderDesc eyeRenderDesc[2]; - eyeRenderDesc[0] = ovrHmd_GetRenderDesc(m_hmdDevice, ovrEye_Left, m_hmdDevice->DefaultEyeFov[0]); - eyeRenderDesc[1] = ovrHmd_GetRenderDesc(m_hmdDevice, ovrEye_Right, m_hmdDevice->DefaultEyeFov[1]); + m_eyeRenderDesc[0] = ovrHmd_GetRenderDesc(m_hmdDevice, ovrEye_Left, m_hmdDevice->DefaultEyeFov[0]); + m_eyeRenderDesc[1] = ovrHmd_GetRenderDesc(m_hmdDevice, ovrEye_Right, m_hmdDevice->DefaultEyeFov[1]); - ovrVector3f leftEyeAdjust = eyeRenderDesc[0].ViewAdjust; + ovrVector3f leftEyeAdjust = m_eyeRenderDesc[0].ViewAdjust; m_leftEyeAdjust.set(leftEyeAdjust.x, leftEyeAdjust.y, leftEyeAdjust.z); - ovrVector3f rightEyeAdjust = eyeRenderDesc[1].ViewAdjust; + ovrVector3f rightEyeAdjust = m_eyeRenderDesc[1].ViewAdjust; m_rightEyeAdjust.set(rightEyeAdjust.x, rightEyeAdjust.y, rightEyeAdjust.z); bool isRightHanded = true; - ovrMatrix4f leftEyeProjectionMatrix = ovrMatrix4f_Projection(eyeRenderDesc[0].Fov, m_nearClip, m_farClip, isRightHanded); - // Test of transpose + ovrMatrix4f leftEyeProjectionMatrix = ovrMatrix4f_Projection(m_eyeRenderDesc[0].Fov, m_nearClip, m_farClip, isRightHanded); + // Transpose matrix m_leftEyeProjectionMatrix.set(leftEyeProjectionMatrix.M[0][0], leftEyeProjectionMatrix.M[1][0], leftEyeProjectionMatrix.M[2][0], leftEyeProjectionMatrix.M[3][0], leftEyeProjectionMatrix.M[0][1], leftEyeProjectionMatrix.M[1][1], leftEyeProjectionMatrix.M[2][1], leftEyeProjectionMatrix.M[3][1], leftEyeProjectionMatrix.M[0][2], leftEyeProjectionMatrix.M[1][2], leftEyeProjectionMatrix.M[2][2], leftEyeProjectionMatrix.M[3][2], leftEyeProjectionMatrix.M[0][3], leftEyeProjectionMatrix.M[1][3], leftEyeProjectionMatrix.M[2][3], leftEyeProjectionMatrix.M[3][3]); - //m_leftEyeProjectionMatrix.set(*leftEyeProjectionMatrix.M); - ovrMatrix4f rightEyeProjectionMatrix = ovrMatrix4f_Projection(eyeRenderDesc[1].Fov, m_nearClip, m_farClip, isRightHanded); - + ovrMatrix4f rightEyeProjectionMatrix = ovrMatrix4f_Projection(m_eyeRenderDesc[1].Fov, m_nearClip, m_farClip, isRightHanded); + // Transpose matrix m_rightEyeProjectionMatrix.set(rightEyeProjectionMatrix.M[0][0], rightEyeProjectionMatrix.M[1][0], rightEyeProjectionMatrix.M[2][0], rightEyeProjectionMatrix.M[3][0], rightEyeProjectionMatrix.M[0][1], rightEyeProjectionMatrix.M[1][1], rightEyeProjectionMatrix.M[2][1], rightEyeProjectionMatrix.M[3][1], rightEyeProjectionMatrix.M[0][2], rightEyeProjectionMatrix.M[1][2], rightEyeProjectionMatrix.M[2][2], rightEyeProjectionMatrix.M[3][2], rightEyeProjectionMatrix.M[0][3], rightEyeProjectionMatrix.M[1][3], rightEyeProjectionMatrix.M[2][3], rightEyeProjectionMatrix.M[3][3]); - - //m_rightEyeProjectionMatrix.set(*rightEyeProjectionMatrix.M); - // Start the sensor which provides the Rift’s pose and motion. ovrHmd_ConfigureTracking(m_hmdDevice, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0); - } } @@ -175,4 +171,91 @@ osg::Quat OculusDevice::getOrientation() const osg::Quat osgQuat(0.0f, 0.0f, 0.0f, 1.0f); return osgQuat; -} \ No newline at end of file +} + +osg::Geode* OculusDevice::distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h) { + osg::ref_ptr geode = new osg::Geode; + // Allocate & generate distortion mesh vertices. + ovrDistortionMesh meshData; + ovrHmd_CreateDistortionMesh(m_hmdDevice, m_eyeRenderDesc[eyeNum].Eye, m_eyeRenderDesc[eyeNum].Fov, ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp, &meshData); + + // Now parse the vertex data and create a render ready vertex buffer from it + ovrDistortionVertex* ov = meshData.pVertexData; + osg::Vec2Array* positionArray = new osg::Vec2Array; + osg::Vec4Array* colorArray = new osg::Vec4Array; + osg::Vec2Array* textureRArray = new osg::Vec2Array; + osg::Vec2Array* textureGArray = new osg::Vec2Array; + osg::Vec2Array* textureBArray = new osg::Vec2Array; + + for (unsigned vertNum = 0; vertNum < meshData.VertexCount; ++vertNum) + { + positionArray->push_back(osg::Vec2f(ov[vertNum].ScreenPosNDC.x, ov[vertNum].ScreenPosNDC.y)); + colorArray->push_back(osg::Vec4f(ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].TimeWarpFactor)); + textureRArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesR.x, ov[vertNum].TanEyeAnglesR.y)); + textureGArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesG.x, ov[vertNum].TanEyeAnglesG.y)); + textureBArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesB.x, ov[vertNum].TanEyeAnglesB.y)); + } + + // Get triangle indicies + osg::UShortArray* indexArray = new osg::UShortArray; + unsigned short* index = meshData.pIndexData; + for (unsigned indexNum = 0; indexNum < meshData.IndexCount; ++indexNum) { + indexArray->push_back(index[indexNum]); + } + + // Deallocate the mesh data + ovrHmd_DestroyDistortionMesh(&meshData); + + osg::ref_ptr geometry = new osg::Geometry; + osg::ref_ptr drawElement = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, indexArray->size(), (GLushort*) indexArray->getDataPointer()); + geometry->addPrimitiveSet(drawElement); + + GLuint positionLoc = 0; + GLuint colorLoc = 1; + GLuint texCoord0Loc = 2; + GLuint texCoord1Loc = 3; + GLuint texCoord2Loc = 4; + + program->addBindAttribLocation("Position", positionLoc); + geometry->setVertexAttribArray(positionLoc, positionArray); + geometry->setVertexAttribBinding(positionLoc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("Color", colorLoc); + geometry->setVertexAttribArray(colorLoc, colorArray); + geometry->setVertexAttribBinding(colorLoc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("TexCoord0", texCoord0Loc); + geometry->setVertexAttribArray(texCoord0Loc, textureRArray); + geometry->setVertexAttribBinding(texCoord0Loc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("TexCoord1", texCoord1Loc); + geometry->setVertexAttribArray(texCoord1Loc, textureGArray); + geometry->setVertexAttribBinding(texCoord1Loc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("TexCoord2", texCoord2Loc); + geometry->setVertexAttribArray(texCoord2Loc, textureBArray); + geometry->setVertexAttribBinding(texCoord2Loc, osg::Geometry::BIND_PER_VERTEX); + + + // Compute UV scale and offset + ovrRecti eyeRenderViewport; + eyeRenderViewport.Pos.x = x; + eyeRenderViewport.Pos.y = y; + eyeRenderViewport.Size.w = w; + eyeRenderViewport.Size.h = h; + ovrHmd_GetRenderScaleAndOffset(m_eyeRenderDesc[eyeNum].Fov, m_renderTargetSize, eyeRenderViewport, m_UVScaleOffset[eyeNum]); + geode->addDrawable(geometry); + return geode.release(); +} + +osg::Vec2f OculusDevice::eyeToSourceUVScale(int eyeNum) const +{ + osg::Vec2f uvScale(m_UVScaleOffset[eyeNum][0].x, m_UVScaleOffset[eyeNum][0].y); + return uvScale; +} +osg::Vec2f OculusDevice::eyeToSourceUVOffset(int eyeNum) const +{ + osg::Vec2f uvOffset(m_UVScaleOffset[eyeNum][1].x, m_UVScaleOffset[eyeNum][1].y); + return uvOffset; +} + diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 6d62dc7..9ea36d3 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -12,6 +12,8 @@ #include "OVR.h" #include #include +#include +#include class OculusDevice : public osg::Referenced { @@ -40,6 +42,10 @@ class OculusDevice : public osg::Referenced { void resetSensorOrientation() { } osg::Quat getOrientation() const; + + osg::Geode* distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h); + osg::Vec2f eyeToSourceUVScale(int eyeNum) const; + osg::Vec2f eyeToSourceUVOffset(int eyeNum) const; protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected @@ -47,6 +53,9 @@ class OculusDevice : public osg::Referenced { ovrHmd m_hmdDevice; ovrSizei m_resolution; ovrSizei m_renderTargetSize; + ovrEyeRenderDesc m_eyeRenderDesc[2]; + ovrVector2f m_UVScaleOffset[2][2]; + osg::Matrixf m_leftEyeProjectionMatrix; osg::Matrixf m_rightEyeProjectionMatrix; osg::Vec3f m_leftEyeAdjust; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 35d8d82..c661795 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include @@ -44,7 +43,7 @@ osg::Camera* OculusViewConfig::createRTTCamera(osg::Texture* texture, osg::Graph osg::Camera* OculusViewConfig::createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const { osg::ref_ptr camera = new osg::Camera; - camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); + camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); camera->setClearMask( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setAllowEventFocus(false); @@ -55,20 +54,6 @@ osg::Camera* OculusViewConfig::createHUDCamera(double left, double right, double return camera.release(); } -osg::Geode* OculusViewConfig::createHUDQuad( float width, float height, float scale ) const -{ - osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(), - osg::Vec3(width, 0.0f, 0.0f), - osg::Vec3(0.0f, height, 0.0f), - 0.0f, 0.0f, width*scale, height*scale ); - osg::ref_ptr quad = new osg::Geode; - quad->addDrawable( geom ); - int values = osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED; - quad->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), values ); - quad->getOrCreateStateSet()->setMode( GL_LIGHTING, values ); - return quad.release(); -} - void OculusViewConfig::configure(osgViewer::View& view) const { m_device->setNearClip(m_nearClip); @@ -142,30 +127,42 @@ void OculusViewConfig::configure(osgViewer::View& view) const cameraRTTRight->setName("RightRTT"); cameraRTTLeft->setCullMask(m_sceneNodeMask); cameraRTTRight->setCullMask(m_sceneNodeMask); - // Create HUD cameras for left eye - osg::ref_ptr cameraHUDLeft = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc); - cameraHUDLeft->setName("LeftHUD"); - cameraHUDLeft->setViewport(new osg::Viewport(0, 0, - m_device->hScreenResolution() / 2.0f, m_device->vScreenResolution())); - // Create HUD cameras for right eye - osg::ref_ptr cameraHUDRight = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc); - cameraHUDRight->setName("RightHUD"); - cameraHUDRight->setViewport(new osg::Viewport(m_device->hScreenResolution() / 2.0f, 0, - m_device->hScreenResolution() / 2.0f, m_device->vScreenResolution())); - // Create quads for each camera - osg::ref_ptr leftQuad = createHUDQuad(1.0f, 1.0f); - cameraHUDLeft->addChild(leftQuad); - osg::ref_ptr rightQuad = createHUDQuad(1.0f, 1.0f); - cameraHUDRight->addChild(rightQuad); - // Set up shaders from the Oculus SDK documentation + // Create HUD camera + osg::ref_ptr cameraHUD = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc); + cameraHUD->setName("OrthoCamera"); + cameraHUD->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); - // Attach shaders to each HUD - osg::StateSet* leftEyeStateSet = leftQuad->getOrCreateStateSet(); + // Set up shaders from the Oculus SDK documentation + osg::ref_ptr program = new osg::Program; + osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); + osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); + fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); + program->addShader(vertexShader); + program->addShader(fragmentShader); + + // Create distortionMesh for each camera + osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(0, program, 0, 0, textureWidth, textureHeight); + cameraHUD->addChild(leftDistortionMesh); + + osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(1, program, textureWidth, 0, textureWidth, textureHeight); + cameraHUD->addChild(rightDistortionMesh); + + // Attach shaders to each distortion mesh + osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); leftEyeStateSet->setTextureAttributeAndModes(0, textureLeft, osg::StateAttribute::ON); + leftEyeStateSet->setAttributeAndModes(program, osg::StateAttribute::ON); + leftEyeStateSet->addUniform(new osg::Uniform("Texture", 0)); + leftEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(0))); + leftEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(0))); - osg::StateSet* rightEyeStateSet = rightQuad->getOrCreateStateSet(); + osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); rightEyeStateSet->setTextureAttributeAndModes(0, textureRight, osg::StateAttribute::ON); + rightEyeStateSet->setAttributeAndModes(program, osg::StateAttribute::ON); + rightEyeStateSet->addUniform(new osg::Uniform("Texture", 0)); + rightEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(1))); + rightEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(1))); // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, @@ -177,11 +174,10 @@ void OculusViewConfig::configure(osgViewer::View& view) const m_device->viewMatrixRight(), true); - // Add HUD cameras as slaves - view.addSlave(cameraHUDLeft, false); - view.addSlave(cameraHUDRight, false); - + // Add HUD camera as slave + view.addSlave(cameraHUD, false); view.setName("Oculus"); + // Connect main camera to node callback that get HMD orientation if (m_useOrientations) { camera->setDataVariance(osg::Object::DYNAMIC); diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index 81b9a0e..e098260 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -39,7 +39,6 @@ class OculusViewConfig : public osgViewer::ViewConfig { osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc) const; osg::Camera* createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; - osg::Geode* createHUDQuad( float width, float height, float scale = 1.0f ) const; bool m_configured; bool m_useOrientations; diff --git a/src/warp.vert b/src/warp.vert deleted file mode 100644 index f93f8e8..0000000 --- a/src/warp.vert +++ /dev/null @@ -1,7 +0,0 @@ -varying vec2 Texcoord; - -void main( void ) -{ - gl_Position = ftransform(); - Texcoord = gl_MultiTexCoord0.xy; -} diff --git a/src/warpWithChromeAb.frag b/src/warpWithChromeAb.frag deleted file mode 100644 index f710751..0000000 --- a/src/warpWithChromeAb.frag +++ /dev/null @@ -1,38 +0,0 @@ -uniform sampler2D WarpTexture; -uniform vec2 LensCenter; -uniform vec2 ScreenCenter; -uniform vec2 Scale; -uniform vec2 ScaleIn; -uniform vec4 HmdWarpParam; -uniform vec4 ChromAbParam; - -varying vec2 Texcoord; - -void main(void) -{ - vec2 theta = (Texcoord - LensCenter) * ScaleIn; // Scales texture coordinates to [-1, 1] - float rSq = theta.x * theta.x + theta.y * theta.y; - vec2 theta1 = theta * ( HmdWarpParam.x + - HmdWarpParam.y * rSq + - HmdWarpParam.z * rSq * rSq + - HmdWarpParam.w * rSq * rSq * rSq); - // Detect whether blue texture coordinates are out of range since these will scaled out the furthest. - vec2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq); - vec2 tcBlue = LensCenter + Scale * thetaBlue; - - if (any(bvec2(clamp(tcBlue, ScreenCenter - vec2(0.5, 0.5), ScreenCenter + vec2(0.5, 0.5)) - tcBlue))) { - gl_FragColor = vec4(0, 0, 0, 0); - return; - } - - // Now do blue texture lookup. - float blue = texture2D(WarpTexture, tcBlue).b; - // Do green lookup (no scaling). - vec2 tcGreen = LensCenter + Scale * theta1; - float green = texture2D(WarpTexture, tcGreen).g; - // Do red scale and lookup. - vec2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq); - vec2 tcRed = LensCenter + Scale * thetaRed; - float red = texture2D(WarpTexture, tcRed).r; - gl_FragColor = vec4(red, green, blue, 1); -} diff --git a/src/warpWithoutChromeAb.frag b/src/warpWithoutChromeAb.frag deleted file mode 100644 index abc7917..0000000 --- a/src/warpWithoutChromeAb.frag +++ /dev/null @@ -1,31 +0,0 @@ -uniform sampler2D WarpTexture; -uniform vec2 LensCenter; -uniform vec2 ScreenCenter; -uniform vec2 Scale; -uniform vec2 ScaleIn; -uniform vec4 HmdWarpParam; - -varying vec2 Texcoord; - -// Scales input texture coordinates for distortion. -vec2 HmdWarp(vec2 texCoord) -{ - vec2 theta = (texCoord - LensCenter) * ScaleIn; // Scales texture coordinates to [-1, 1] - float rSq = theta.x * theta.x + theta.y * theta.y; - vec2 rvector= theta * ( HmdWarpParam.x + - HmdWarpParam.y * rSq + - HmdWarpParam.z * rSq * rSq + - HmdWarpParam.w * rSq * rSq * rSq); - return LensCenter + Scale * rvector; -} - -void main(void) -{ - vec2 tc = HmdWarp(Texcoord); - - if (any(bvec2(clamp(tc, ScreenCenter - vec2(0.5, 0.5), ScreenCenter + vec2(0.5, 0.5)) - tc))) { - gl_FragColor = vec4(0, 0, 0, 0); - } else { - gl_FragColor = texture2D(WarpTexture, tc); - } -} diff --git a/src/warp_mesh.frag b/src/warp_mesh.frag new file mode 100644 index 0000000..bbac9cb --- /dev/null +++ b/src/warp_mesh.frag @@ -0,0 +1,16 @@ +#version 110 + +uniform sampler2D Texture; + +varying vec4 oColor; +varying vec2 oTexCoord0; +varying vec2 oTexCoord1; +varying vec2 oTexCoord2; + +void main() +{ + gl_FragColor.r = oColor.r * texture2D(Texture, oTexCoord0).r; + gl_FragColor.g = oColor.g * texture2D(Texture, oTexCoord1).g; + gl_FragColor.b = oColor.b * texture2D(Texture, oTexCoord2).b; + gl_FragColor.a = 1.0; +}; diff --git a/src/warp_mesh.vert b/src/warp_mesh.vert new file mode 100644 index 0000000..27bf26f --- /dev/null +++ b/src/warp_mesh.vert @@ -0,0 +1,32 @@ +#version 110 + +uniform vec2 EyeToSourceUVScale; +uniform vec2 EyeToSourceUVOffset; + +attribute vec2 Position; +attribute vec4 Color; +attribute vec2 TexCoord0; +attribute vec2 TexCoord1; +attribute vec2 TexCoord2; + +varying vec4 oColor; +varying vec2 oTexCoord0; +varying vec2 oTexCoord1; +varying vec2 oTexCoord2; + +void main() +{ + gl_Position.x = Position.x; + gl_Position.y = Position.y; + gl_Position.z = 0.5; + gl_Position.w = 1.0; + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset; + oTexCoord0.y = 1.0-oTexCoord0.y; + oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset; + oTexCoord1.y = 1.0-oTexCoord1.y; + oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset; + oTexCoord2.y = 1.0-oTexCoord2.y; + oColor = Color; // Used for vignette fade. +}; \ No newline at end of file From 68be6a600235a03303fd7acb59e819bc42f60e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 1 Aug 2014 22:19:33 +0200 Subject: [PATCH 05/51] Commented out code paths in CMakefile that currently is not working. --- CMakeLists.txt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fcc0310..90879d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -70,11 +70,15 @@ ENDIF(VISUAL_STUDIO_EXPRESS) # osgViewer::ViewConfig concept requires osg 3.2 or later IF(NOT OPENSCENEGRAPH_VERSION VERSION_EQUAL 3.2.0 AND NOT OPENSCENEGRAPH_VERSION VERSION_GREATER 3.2.0) - SET (USE_VIEW_CONFIG OFF) - SET (BUILD_DEPRECATED ON) + #SET (USE_VIEW_CONFIG OFF) + #SET (BUILD_DEPRECATED ON) + MESSAGE(FATAL_ERROR "Error: Currently only supporting OpenSceneGraph 3.2.0 or later.") ELSE() SET (USE_VIEW_CONFIG ON) OPTION(BUILD_DEPRECATED "Enable to build deprecated version as well" OFF) + IF (BUILD_DEPRECATED) + MESSAGE(FATAL_ERROR "Error: Only supports Viewer Config.") + ENDIF() ENDIF() ############################################################################### From 8e3c08125001e86b993785cf3fb7bc7be7128418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 1 Aug 2014 22:22:18 +0200 Subject: [PATCH 06/51] Added orientation change support. --- src/oculusdevice.cpp | 13 +++++++++++++ src/oculusdevice.h | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 79970d2..ca56366 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -170,9 +170,22 @@ osg::Quat OculusDevice::getOrientation() const // Create identity quaternion osg::Quat osgQuat(0.0f, 0.0f, 0.0f, 1.0f); + // Query the HMD for the current tracking state. + ovrTrackingState ts = ovrHmd_GetTrackingState(m_hmdDevice, ovr_GetTimeInSeconds()); + if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { + ovrPoseStatef headpose = ts.HeadPose; + ovrPosef pose = headpose.ThePose; + ovrQuatf quat = pose.Orientation; + osgQuat.set(quat.x, quat.y, quat.z, -quat.w); + } + return osgQuat; } +void OculusDevice::resetSensorOrientation() { + ovrHmd_RecenterPose(m_hmdDevice); +} + osg::Geode* OculusDevice::distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h) { osg::ref_ptr geode = new osg::Geode; // Allocate & generate distortion mesh vertices. diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 9ea36d3..c4d4e9d 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -40,7 +40,7 @@ class OculusDevice : public osg::Referenced { void setNearClip(float nearClip) { m_nearClip = nearClip; } void setFarClip(float farclip) { m_farClip = farclip; } - void resetSensorOrientation() { } + void resetSensorOrientation(); osg::Quat getOrientation() const; osg::Geode* distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h); From 180f497c97163924f97d4452a2f2d7c11d11d0fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 1 Aug 2014 22:23:46 +0200 Subject: [PATCH 07/51] ProjectionOffset modified by aspect ratio. --- src/oculusdevice.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index ca56366..1608363 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -139,16 +139,19 @@ osg::Matrix OculusDevice::projectionMatrixRight() const osg::Matrix OculusDevice::projectionOffsetMatrixLeft() const { osg::Matrix projectionOffsetMatrix; - float offset = m_leftEyeProjectionMatrix(2, 0); // Ugly hack to extract projection offset - projectionOffsetMatrix(3, 0) = offset; + float aspectRatio = float(m_eyeRenderDesc[0].DistortedViewport.Size.w) / float(m_eyeRenderDesc[0].DistortedViewport.Size.h); + float offset = m_leftEyeProjectionMatrix(2, 0) * aspectRatio; // Ugly hack to extract projection offset + projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0));// + return projectionOffsetMatrix; } osg::Matrix OculusDevice::projectionOffsetMatrixRight() const { osg::Matrix projectionOffsetMatrix; - float offset = m_rightEyeProjectionMatrix(2, 0); // Ugly hack to extract projection offset - projectionOffsetMatrix(3, 0) = offset; + float aspectRatio = float(m_eyeRenderDesc[1].DistortedViewport.Size.w) / float(m_eyeRenderDesc[1].DistortedViewport.Size.h); + float offset = m_rightEyeProjectionMatrix(2, 0) * aspectRatio; // Ugly hack to extract projection offset + projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0)); return projectionOffsetMatrix; } osg::Matrix OculusDevice::viewMatrixLeft() const From ae99169484400d349ccca27ef471e8ac75961914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 1 Aug 2014 22:31:28 +0200 Subject: [PATCH 08/51] Set up Oculus render window on correct screen. --- src/oculusdevice.h | 3 +++ src/oculusviewconfig.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/oculusdevice.h b/src/oculusdevice.h index c4d4e9d..3e23197 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -27,6 +27,9 @@ class OculusDevice : public osg::Referenced { unsigned int hRenderTargetSize() const; unsigned int vRenderTargetSize() const; + int displayId() const { return m_hmdDevice->DisplayId; } + osg::Vec2i windowPos() const { return osg::Vec2i(m_hmdDevice->WindowsPos.x, m_hmdDevice->WindowsPos.y); } + osg::Matrix projectionMatrixCenter() const; osg::Matrix projectionMatrixLeft() const; osg::Matrix projectionMatrixRight() const; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index c661795..05973c0 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -85,8 +85,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const traits->screenNum = si.screenNum; traits->displayNum = si.displayNum; traits->windowDecoration = false; - traits->x = 0; - traits->y = 0; + traits->x = m_device->windowPos().x(); + traits->y = m_device->windowPos().y(); traits->width = m_device->hScreenResolution(); traits->height = m_device->vScreenResolution(); traits->doubleBuffer = true; From 18e01b6d4a9b0e8c4c83e6e4306addf4d5faeea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 1 Aug 2014 22:32:35 +0200 Subject: [PATCH 09/51] Updated readme file. --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 463b357..d71c5c5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,10 @@ OsgOculusViewer An OsgViewer with support for the Oculus Rift -Last tested against Oculus SDK 0.2.5 +**NOTE! This is work in progress and is NOT intended for production.** +**Currently only supporting OpenSceneGraph 3.2.0 or later.** + +Last tested against Oculus SDK 0.4.0 Beta To be able to use the osgViewer::ViewConfig version you will need to use OpenSceneGraph 3.2.0 or later. From d1377e3004676c0124c4f61bf6e1eed60761048e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 2 Aug 2014 00:49:54 +0200 Subject: [PATCH 10/51] Moved aspect ratio calculation to own function. --- src/oculusdevice.cpp | 9 +++++---- src/oculusdevice.h | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 1608363..dff7222 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -139,8 +139,7 @@ osg::Matrix OculusDevice::projectionMatrixRight() const osg::Matrix OculusDevice::projectionOffsetMatrixLeft() const { osg::Matrix projectionOffsetMatrix; - float aspectRatio = float(m_eyeRenderDesc[0].DistortedViewport.Size.w) / float(m_eyeRenderDesc[0].DistortedViewport.Size.h); - float offset = m_leftEyeProjectionMatrix(2, 0) * aspectRatio; // Ugly hack to extract projection offset + float offset = m_leftEyeProjectionMatrix(2, 0) * aspectRatio(0); // Ugly hack to extract projection offset projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0));// return projectionOffsetMatrix; @@ -149,8 +148,7 @@ osg::Matrix OculusDevice::projectionOffsetMatrixLeft() const osg::Matrix OculusDevice::projectionOffsetMatrixRight() const { osg::Matrix projectionOffsetMatrix; - float aspectRatio = float(m_eyeRenderDesc[1].DistortedViewport.Size.w) / float(m_eyeRenderDesc[1].DistortedViewport.Size.h); - float offset = m_rightEyeProjectionMatrix(2, 0) * aspectRatio; // Ugly hack to extract projection offset + float offset = m_rightEyeProjectionMatrix(2, 0) * aspectRatio(1); // Ugly hack to extract projection offset projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0)); return projectionOffsetMatrix; } @@ -275,3 +273,6 @@ osg::Vec2f OculusDevice::eyeToSourceUVOffset(int eyeNum) const return uvOffset; } +float OculusDevice::aspectRatio(int eyeNum) const { + return float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.w) / float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.h); +} diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 3e23197..afedd2a 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -52,6 +52,7 @@ class OculusDevice : public osg::Referenced { protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected + float aspectRatio(int eyeNum) const; ovrHmd m_hmdDevice; ovrSizei m_resolution; From b032ed4c30b666a9a546c8bba89b7740bb8bb800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 2 Aug 2014 10:56:39 +0200 Subject: [PATCH 11/51] Fixed aspect ratio problem which caused shearing when HMD rolled. --- src/oculusdevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index dff7222..c288f59 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -123,7 +123,7 @@ osg::Matrix OculusDevice::projectionMatrixCenter() const osg::Matrix projectionMatrixCenter; projectionMatrixCenter = m_leftEyeProjectionMatrix; projectionMatrixCenter(2, 0) = 0; // Ugly hack to make left projection matrix into a center projection matrix - return projectionMatrixCenter; + return projectionMatrixCenter * osg::Matrix::scale(osg::Vec3(0.5, 1.0, 1.0)); // Scale for correct aspect ratio } osg::Matrix OculusDevice::projectionMatrixLeft() const From 6c5b87517b0d50b90e74ab8d089e17c8520d7fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Mon, 4 Aug 2014 17:25:26 +0200 Subject: [PATCH 12/51] Updated CMake script to find Oculus library on Win64 platform. --- cmake/FindOculusSDK.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/FindOculusSDK.cmake b/cmake/FindOculusSDK.cmake index c9ab03a..b7fd801 100644 --- a/cmake/FindOculusSDK.cmake +++ b/cmake/FindOculusSDK.cmake @@ -60,14 +60,14 @@ ENDIF() MARK_AS_ADVANCED(OCULUS_MSVC_DIR) # Look for the library. -FIND_LIBRARY(OCULUS_SDK_LIBRARY NAMES libovr ovr HINTS ${OCULUS_SDK_ROOT_DIR} +FIND_LIBRARY(OCULUS_SDK_LIBRARY NAMES libovr libovr64 ovr HINTS ${OCULUS_SDK_ROOT_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} ) # This will find release lib on Linux if no debug is available - on Linux this is no problem and avoids # having to compile in debug when not needed -FIND_LIBRARY(OCULUS_SDK_LIBRARY_DEBUG NAMES libovr${CMAKE_DEBUG_POSTFIX} ovr${CMAKE_DEBUG_POSTFIX} ovr HINTS +FIND_LIBRARY(OCULUS_SDK_LIBRARY_DEBUG NAMES libovr${CMAKE_DEBUG_POSTFIX} libovr64${CMAKE_DEBUG_POSTFIX} ovr${CMAKE_DEBUG_POSTFIX} ovr HINTS ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Debug/${OCULUS_SDK_LIB_ARCH} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} From 7c15c09b3b551cc0dc1ddc1074fa5ac5277b9f96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Wed, 6 Aug 2014 01:32:35 +0200 Subject: [PATCH 13/51] Detect swap buffer message, needed to be able to implement support for time warp #14 and for better tracking #16. --- src/oculusdevice.cpp | 19 +++++++++++++++---- src/oculusdevice.h | 8 ++++++-- src/oculusviewconfig.cpp | 17 +++++++++++++++-- src/oculusviewconfig.h | 16 +++++++++++++++- 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index c288f59..ddfd1dd 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -31,7 +31,7 @@ OculusDevice::OculusDevice() : m_hmdDevice(0), // Print out some information about the HMD osg::notify(osg::ALWAYS) << "Product: " << m_hmdDevice->ProductName << std::endl; osg::notify(osg::ALWAYS) << "Manufacturer: " << m_hmdDevice->Manufacturer << std::endl; - osg::notify(osg::ALWAYS) << "VendorId: " << m_hmdDevice->VendorId << std::endl; + osg::notify(osg::ALWAYS) << "VendorId: " << m_hmdDevice->VendorId << std::endl; osg::notify(osg::ALWAYS) << "ProductId: " << m_hmdDevice->ProductId << std::endl; osg::notify(osg::ALWAYS) << "SerialNumber: " << m_hmdDevice->SerialNumber << std::endl; osg::notify(osg::ALWAYS) << "FirmwareVersion: " << m_hmdDevice->FirmwareMajor << "." << m_hmdDevice->FirmwareMinor << std::endl; @@ -166,13 +166,16 @@ osg::Matrix OculusDevice::viewMatrixRight() const return viewMatrix; } -osg::Quat OculusDevice::getOrientation() const +osg::Quat OculusDevice::getOrientation(unsigned int frameIndex) { // Create identity quaternion osg::Quat osgQuat(0.0f, 0.0f, 0.0f, 1.0f); + // Ask the API for the times when this frame is expected to be displayed. + m_frameTiming = ovrHmd_GetFrameTiming(m_hmdDevice, frameIndex); + // Query the HMD for the current tracking state. - ovrTrackingState ts = ovrHmd_GetTrackingState(m_hmdDevice, ovr_GetTimeInSeconds()); + ovrTrackingState ts = ovrHmd_GetTrackingState(m_hmdDevice, m_frameTiming.ScanoutMidpointSeconds); if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { ovrPoseStatef headpose = ts.HeadPose; ovrPosef pose = headpose.ThePose; @@ -183,7 +186,7 @@ osg::Quat OculusDevice::getOrientation() const return osgQuat; } -void OculusDevice::resetSensorOrientation() { +void OculusDevice::resetSensorOrientation() const { ovrHmd_RecenterPose(m_hmdDevice); } @@ -276,3 +279,11 @@ osg::Vec2f OculusDevice::eyeToSourceUVOffset(int eyeNum) const float OculusDevice::aspectRatio(int eyeNum) const { return float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.w) / float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.h); } + +void OculusDevice::beginFrameTiming(unsigned int frameIndex) { + m_frameTiming = ovrHmd_BeginFrameTiming(m_hmdDevice, frameIndex); +} + +void OculusDevice::endFrameTiming() { + ovrHmd_EndFrameTiming(m_hmdDevice); +} \ No newline at end of file diff --git a/src/oculusdevice.h b/src/oculusdevice.h index afedd2a..5481771 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -43,13 +43,15 @@ class OculusDevice : public osg::Referenced { void setNearClip(float nearClip) { m_nearClip = nearClip; } void setFarClip(float farclip) { m_farClip = farclip; } - void resetSensorOrientation(); - osg::Quat getOrientation() const; + void resetSensorOrientation() const; + osg::Quat getOrientation(unsigned int frameIndex=0); osg::Geode* distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h); osg::Vec2f eyeToSourceUVScale(int eyeNum) const; osg::Vec2f eyeToSourceUVOffset(int eyeNum) const; + void beginFrameTiming(unsigned int frameIndex=0); + void endFrameTiming(); protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected float aspectRatio(int eyeNum) const; @@ -59,11 +61,13 @@ class OculusDevice : public osg::Referenced { ovrSizei m_renderTargetSize; ovrEyeRenderDesc m_eyeRenderDesc[2]; ovrVector2f m_UVScaleOffset[2][2]; + ovrFrameTiming m_frameTiming; osg::Matrixf m_leftEyeProjectionMatrix; osg::Matrixf m_rightEyeProjectionMatrix; osg::Vec3f m_leftEyeAdjust; osg::Vec3f m_rightEyeAdjust; + float m_nearClip; float m_farClip; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 05973c0..3c02afb 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -99,6 +99,10 @@ void OculusViewConfig::configure(osgViewer::View& view) const osg::notify(osg::NOTICE) << "Error, GraphicsWindow has not been created successfully" << std::endl; return; } + + // Attach a callback to detect swap + osg::ref_ptr swapCallback = new OculusSwapCallback(m_device); + gc->setSwapCallback(swapCallback); osg::ref_ptr camera = view.getCamera(); camera->setName("Main"); @@ -181,17 +185,26 @@ void OculusViewConfig::configure(osgViewer::View& view) const // Connect main camera to node callback that get HMD orientation if (m_useOrientations) { camera->setDataVariance(osg::Object::DYNAMIC); - camera->setUpdateCallback(new OculusViewConfigOrientationCallback(cameraRTTLeft, cameraRTTRight, m_device)); + camera->setUpdateCallback(new OculusViewConfigOrientationCallback(cameraRTTLeft, cameraRTTRight, m_device, swapCallback)); } } +void OculusSwapCallback::swapBuffersImplementation(osg::GraphicsContext *gc) { + // Run the default system swapBufferImplementation + gc->swapBuffersImplementation(); + // End frame timing when swap buffer is done + m_device->endFrameTiming(); + // Start a new frame with incremented frame index + m_device->beginFrameTiming(++m_frameIndex); +} + void OculusViewConfigOrientationCallback::operator() (osg::Node* node, osg::NodeVisitor* nv) { osg::Camera* mainCamera = static_cast(node); osg::View* view = mainCamera->getView(); if (view) { - osg::Quat orient = m_device.get()->getOrientation(); + osg::Quat orient = m_device.get()->getOrientation(m_swapCallback->frameIndex()); // Nasty hack to update the view offset for each of the slave cameras // There doesn't seem to be an accessor for this, fortunately the offsets are public view->findSlaveForCamera(m_cameraRTTLeft.get())->_viewOffset.setRotate(orient); diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index e098260..2dfd07f 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -53,13 +53,27 @@ class OculusViewConfig : public osgViewer::ViewConfig { osg::ref_ptr m_device; }; +class OculusSwapCallback : public osg::GraphicsContext::SwapCallback { +public: + OculusSwapCallback(osg::ref_ptr device) : m_device(device), m_frameIndex(0) {} + void swapBuffersImplementation(osg::GraphicsContext *gc); + int frameIndex() const { return m_frameIndex; } +private: + osg::observer_ptr m_device; + int m_frameIndex; +}; + class OculusViewConfigOrientationCallback : public osg::NodeCallback { public: - OculusViewConfigOrientationCallback(osg::ref_ptr rttLeft, osg::ref_ptr rttRight, osg::observer_ptr device) : m_cameraRTTLeft(rttLeft), m_cameraRTTRight(rttRight), m_device(device) {}; + OculusViewConfigOrientationCallback(osg::ref_ptr rttLeft, + osg::ref_ptr rttRight, + osg::observer_ptr device, + osg::observer_ptr swapCallback) : m_cameraRTTLeft(rttLeft), m_cameraRTTRight(rttRight), m_device(device), m_swapCallback(swapCallback) {}; virtual void operator() (osg::Node* node, osg::NodeVisitor* nv); protected: osg::observer_ptr m_cameraRTTLeft, m_cameraRTTRight; osg::observer_ptr m_device; + osg::observer_ptr m_swapCallback; }; #endif /* _OSG_OCULUSVIEWCONFIG_H_ */ \ No newline at end of file From 2979d0a527ba3d9664b99fc4e70c16dc04f4eb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Wed, 6 Aug 2014 02:06:17 +0200 Subject: [PATCH 14/51] Get time before warp camera is rendered, needed to be able to implement support for time warp #14. --- src/oculusdevice.cpp | 7 ++++++- src/oculusdevice.h | 3 ++- src/oculusviewconfig.cpp | 27 ++++++++++++++++++--------- src/oculusviewconfig.h | 11 ++++++++++- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index ddfd1dd..4c2b9cd 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -284,6 +284,11 @@ void OculusDevice::beginFrameTiming(unsigned int frameIndex) { m_frameTiming = ovrHmd_BeginFrameTiming(m_hmdDevice, frameIndex); } -void OculusDevice::endFrameTiming() { +void OculusDevice::endFrameTiming() const { ovrHmd_EndFrameTiming(m_hmdDevice); +} + +void OculusDevice::waitTillTime() const { + // Wait till time-warp point to reduce latency. + ovr_WaitTillTime(m_frameTiming.TimewarpPointSeconds); } \ No newline at end of file diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 5481771..f79d43e 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -51,7 +51,8 @@ class OculusDevice : public osg::Referenced { osg::Vec2f eyeToSourceUVOffset(int eyeNum) const; void beginFrameTiming(unsigned int frameIndex=0); - void endFrameTiming(); + void endFrameTiming() const; + void waitTillTime() const; protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected float aspectRatio(int eyeNum) const; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 3c02afb..7ae7fe9 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -40,7 +40,7 @@ osg::Camera* OculusViewConfig::createRTTCamera(osg::Texture* texture, osg::Graph return camera.release(); } -osg::Camera* OculusViewConfig::createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const +osg::Camera* OculusViewConfig::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const { osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); @@ -132,10 +132,10 @@ void OculusViewConfig::configure(osgViewer::View& view) const cameraRTTLeft->setCullMask(m_sceneNodeMask); cameraRTTRight->setCullMask(m_sceneNodeMask); - // Create HUD camera - osg::ref_ptr cameraHUD = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc); - cameraHUD->setName("OrthoCamera"); - cameraHUD->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); + // Create warp ortho camera + osg::ref_ptr cameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); + cameraWarp->setName("WarpOrtho"); + cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); // Set up shaders from the Oculus SDK documentation osg::ref_ptr program = new osg::Program; @@ -148,10 +148,13 @@ void OculusViewConfig::configure(osgViewer::View& view) const // Create distortionMesh for each camera osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(0, program, 0, 0, textureWidth, textureHeight); - cameraHUD->addChild(leftDistortionMesh); + cameraWarp->addChild(leftDistortionMesh); osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(1, program, textureWidth, 0, textureWidth, textureHeight); - cameraHUD->addChild(rightDistortionMesh); + cameraWarp->addChild(rightDistortionMesh); + + // Add pre draw camera to handle time warp + cameraWarp->setPreDrawCallback(new WarpCameraPreDrawCallback(m_device)); // Attach shaders to each distortion mesh osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); @@ -178,8 +181,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const m_device->viewMatrixRight(), true); - // Add HUD camera as slave - view.addSlave(cameraHUD, false); + // Add warp camera as slave + view.addSlave(cameraWarp, false); view.setName("Oculus"); // Connect main camera to node callback that get HMD orientation @@ -189,6 +192,12 @@ void OculusViewConfig::configure(osgViewer::View& view) const } } +void WarpCameraPreDrawCallback::operator()(osg::RenderInfo&) const +{ + // Wait till time - warp point to reduce latency. + m_device->waitTillTime(); +} + void OculusSwapCallback::swapBuffersImplementation(osg::GraphicsContext *gc) { // Run the default system swapBufferImplementation gc->swapBuffersImplementation(); diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index 2dfd07f..baa1355 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -38,7 +38,7 @@ class OculusViewConfig : public osgViewer::ViewConfig { ~OculusViewConfig() {}; osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc) const; - osg::Camera* createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; + osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; bool m_configured; bool m_useOrientations; @@ -53,6 +53,15 @@ class OculusViewConfig : public osgViewer::ViewConfig { osg::ref_ptr m_device; }; +class WarpCameraPreDrawCallback : public osg::Camera::DrawCallback +{ +public: + WarpCameraPreDrawCallback(osg::ref_ptr device) : m_device(device) {} + virtual void operator()(osg::RenderInfo& renderInfo) const; +protected: + osg::observer_ptr m_device; +}; + class OculusSwapCallback : public osg::GraphicsContext::SwapCallback { public: OculusSwapCallback(osg::ref_ptr device) : m_device(device), m_frameIndex(0) {} From 0573b28d2fd9d9e5eaa6e39f273b83e264d3cb32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Wed, 6 Aug 2014 21:20:59 +0200 Subject: [PATCH 15/51] Run beginFrameTiming during constuctor otherwise we will get an ASSERT when running in debug mode. --- src/oculusdevice.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 4c2b9cd..c41d887 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -78,6 +78,8 @@ OculusDevice::OculusDevice() : m_hmdDevice(0), ovrHmd_ConfigureTracking(m_hmdDevice, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0); + + beginFrameTiming(); } } From a4060af23e9257a3f98b441fc5587080ccc3c0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Wed, 6 Aug 2014 21:23:02 +0200 Subject: [PATCH 16/51] Support for positional tracking added. This closes #16. --- src/oculusdevice.cpp | 15 ++++++--------- src/oculusdevice.h | 9 +++++++-- src/oculusviewconfig.cpp | 14 +++++++++++--- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index c41d887..991b9a1 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -11,7 +11,9 @@ OculusDevice::OculusDevice() : m_hmdDevice(0), - m_nearClip(0.01f), m_farClip(10000.0f) + m_nearClip(0.01f), m_farClip(10000.0f), + m_position(osg::Vec3(0.0f, 0.0f, 0.0f)), + m_orientation(osg::Quat(0.0f, 0.0f, 0.0f, 1.0f)) { ovr_Initialize(); @@ -168,11 +170,8 @@ osg::Matrix OculusDevice::viewMatrixRight() const return viewMatrix; } -osg::Quat OculusDevice::getOrientation(unsigned int frameIndex) +void OculusDevice::updatePose(unsigned int frameIndex) { - // Create identity quaternion - osg::Quat osgQuat(0.0f, 0.0f, 0.0f, 1.0f); - // Ask the API for the times when this frame is expected to be displayed. m_frameTiming = ovrHmd_GetFrameTiming(m_hmdDevice, frameIndex); @@ -181,11 +180,9 @@ osg::Quat OculusDevice::getOrientation(unsigned int frameIndex) if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { ovrPoseStatef headpose = ts.HeadPose; ovrPosef pose = headpose.ThePose; - ovrQuatf quat = pose.Orientation; - osgQuat.set(quat.x, quat.y, quat.z, -quat.w); + m_position.set(pose.Position.x, pose.Position.y, pose.Position.z); + m_orientation.set(pose.Orientation.x, pose.Orientation.y, pose.Orientation.z, -pose.Orientation.w); } - - return osgQuat; } void OculusDevice::resetSensorOrientation() const { diff --git a/src/oculusdevice.h b/src/oculusdevice.h index f79d43e..11f5eae 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -44,7 +44,10 @@ class OculusDevice : public osg::Referenced { void setFarClip(float farclip) { m_farClip = farclip; } void resetSensorOrientation() const; - osg::Quat getOrientation(unsigned int frameIndex=0); + void updatePose(unsigned int frameIndex = 0); + + osg::Vec3 position() const { return m_position; } + osg::Quat orientation() const { return m_orientation; } osg::Geode* distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h); osg::Vec2f eyeToSourceUVScale(int eyeNum) const; @@ -68,7 +71,9 @@ class OculusDevice : public osg::Referenced { osg::Matrixf m_rightEyeProjectionMatrix; osg::Vec3f m_leftEyeAdjust; osg::Vec3f m_rightEyeAdjust; - + + osg::Vec3 m_position; + osg::Quat m_orientation; float m_nearClip; float m_farClip; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 7ae7fe9..379eacc 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -213,11 +213,19 @@ void OculusViewConfigOrientationCallback::operator() (osg::Node* node, osg::Node osg::View* view = mainCamera->getView(); if (view) { - osg::Quat orient = m_device.get()->getOrientation(m_swapCallback->frameIndex()); + m_device.get()->updatePose(m_swapCallback->frameIndex()); + osg::Vec3 position = m_device.get()->position(); + osg::Quat orientation = m_device.get()->orientation(); + osg::Matrix viewOffsetLeft = m_device.get()->viewMatrixLeft(); + osg::Matrix viewOffsetRight = m_device.get()->viewMatrixRight(); + viewOffsetLeft.preMultTranslate(position); + viewOffsetRight.preMultTranslate(position); + viewOffsetLeft.postMultRotate(orientation); + viewOffsetRight.postMultRotate(orientation); // Nasty hack to update the view offset for each of the slave cameras // There doesn't seem to be an accessor for this, fortunately the offsets are public - view->findSlaveForCamera(m_cameraRTTLeft.get())->_viewOffset.setRotate(orient); - view->findSlaveForCamera(m_cameraRTTRight.get())->_viewOffset.setRotate(orient); + view->findSlaveForCamera(m_cameraRTTLeft.get())->_viewOffset = viewOffsetLeft; + view->findSlaveForCamera(m_cameraRTTRight.get())->_viewOffset = viewOffsetRight; } traverse(node, nv); From ea5d10743577d059444e4adba514117421b5a41b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 7 Aug 2014 00:57:07 +0200 Subject: [PATCH 17/51] Support for time warp added. This closes #14. --- src/CMakeLists.txt | 1 + src/oculusdevice.cpp | 45 +++++++++++++++++++++--- src/oculusdevice.h | 6 +++- src/oculusviewconfig.cpp | 37 +++++++++++++++++++- src/oculusviewconfig.h | 22 ++++++++++-- src/warp_mesh_with_timewarp.vert | 60 ++++++++++++++++++++++++++++++++ 6 files changed, 162 insertions(+), 9 deletions(-) create mode 100644 src/warp_mesh_with_timewarp.vert diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec3fcfb..e1adf9b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -107,6 +107,7 @@ ENDIF() STRING(COMPARE NOTEQUAL ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} CMAKE_OUT_OF_SOURCE_BUILD) IF (CMAKE_OUT_OF_SOURCE_BUILD) CONFIGURE_FILE(warp_mesh.vert warp_mesh.vert COPYONLY) + CONFIGURE_FILE(warp_mesh_with_timewarp.vert warp_mesh_with_timewarp.vert COPYONLY) CONFIGURE_FILE(warp_mesh.frag warp_mesh.frag COPYONLY) ENDIF() diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 991b9a1..c156ccd 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -182,6 +182,12 @@ void OculusDevice::updatePose(unsigned int frameIndex) ovrPosef pose = headpose.ThePose; m_position.set(pose.Position.x, pose.Position.y, pose.Position.z); m_orientation.set(pose.Orientation.x, pose.Orientation.y, pose.Orientation.z, -pose.Orientation.w); + + // Get head pose for both eyes (used for time warp + for (int eyeIndex = 0; eyeIndex < ovrEye_Count; ++eyeIndex) { + ovrEyeType eye = m_hmdDevice->EyeRenderOrder[eyeIndex]; + m_headPose[eye] = ovrHmd_GetEyePose(m_hmdDevice, eye); + } } } @@ -264,17 +270,41 @@ osg::Geode* OculusDevice::distortionMesh(int eyeNum, osg::Program* program, int return geode.release(); } -osg::Vec2f OculusDevice::eyeToSourceUVScale(int eyeNum) const -{ +osg::Vec2f OculusDevice::eyeToSourceUVScale(int eyeNum) const { osg::Vec2f uvScale(m_UVScaleOffset[eyeNum][0].x, m_UVScaleOffset[eyeNum][0].y); return uvScale; } -osg::Vec2f OculusDevice::eyeToSourceUVOffset(int eyeNum) const -{ +osg::Vec2f OculusDevice::eyeToSourceUVOffset(int eyeNum) const { osg::Vec2f uvOffset(m_UVScaleOffset[eyeNum][1].x, m_UVScaleOffset[eyeNum][1].y); return uvOffset; } +osg::Matrixf OculusDevice::eyeRotationStart(int eyeNum) const { + osg::Matrixf rotationStart; + + ovrMatrix4f rotationMatrix = m_timeWarpMatrices[eyeNum][0]; + // Transpose matrix + rotationStart.set(rotationMatrix.M[0][0], rotationMatrix.M[1][0], rotationMatrix.M[2][0], rotationMatrix.M[3][0], + rotationMatrix.M[0][1], rotationMatrix.M[1][1], rotationMatrix.M[2][1], rotationMatrix.M[3][1], + rotationMatrix.M[0][2], rotationMatrix.M[1][2], rotationMatrix.M[2][2], rotationMatrix.M[3][2], + rotationMatrix.M[0][3], rotationMatrix.M[1][3], rotationMatrix.M[2][3], rotationMatrix.M[3][3]); + + return rotationStart; +} + +osg::Matrixf OculusDevice::eyeRotationEnd(int eyeNum) const { + osg::Matrixf rotationEnd; + + ovrMatrix4f rotationMatrix = m_timeWarpMatrices[eyeNum][1]; + // Transpose matrix + rotationEnd.set(rotationMatrix.M[0][0], rotationMatrix.M[1][0], rotationMatrix.M[2][0], rotationMatrix.M[3][0], + rotationMatrix.M[0][1], rotationMatrix.M[1][1], rotationMatrix.M[2][1], rotationMatrix.M[3][1], + rotationMatrix.M[0][2], rotationMatrix.M[1][2], rotationMatrix.M[2][2], rotationMatrix.M[3][2], + rotationMatrix.M[0][3], rotationMatrix.M[1][3], rotationMatrix.M[2][3], rotationMatrix.M[3][3]); + + return rotationEnd; +} + float OculusDevice::aspectRatio(int eyeNum) const { return float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.w) / float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.h); } @@ -287,7 +317,12 @@ void OculusDevice::endFrameTiming() const { ovrHmd_EndFrameTiming(m_hmdDevice); } -void OculusDevice::waitTillTime() const { +void OculusDevice::waitTillTime() { // Wait till time-warp point to reduce latency. ovr_WaitTillTime(m_frameTiming.TimewarpPointSeconds); + + // Get time warp properties + for (int eyeIndex = 0; eyeIndex < ovrEye_Count; ++eyeIndex) { + ovrHmd_GetEyeTimewarpMatrices(m_hmdDevice, (ovrEyeType)eyeIndex, m_headPose[eyeIndex], m_timeWarpMatrices[eyeIndex]); + } } \ No newline at end of file diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 11f5eae..eb92fa3 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -52,10 +52,12 @@ class OculusDevice : public osg::Referenced { osg::Geode* distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h); osg::Vec2f eyeToSourceUVScale(int eyeNum) const; osg::Vec2f eyeToSourceUVOffset(int eyeNum) const; + osg::Matrixf eyeRotationStart(int eyeNum) const; + osg::Matrixf eyeRotationEnd(int eyeNum) const; void beginFrameTiming(unsigned int frameIndex=0); void endFrameTiming() const; - void waitTillTime() const; + void waitTillTime(); protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected float aspectRatio(int eyeNum) const; @@ -66,6 +68,8 @@ class OculusDevice : public osg::Referenced { ovrEyeRenderDesc m_eyeRenderDesc[2]; ovrVector2f m_UVScaleOffset[2][2]; ovrFrameTiming m_frameTiming; + ovrPosef m_headPose[2]; + ovrMatrix4f m_timeWarpMatrices[2][2]; osg::Matrixf m_leftEyeProjectionMatrix; osg::Matrixf m_rightEyeProjectionMatrix; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 379eacc..f36abbe 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -140,7 +140,13 @@ void OculusViewConfig::configure(osgViewer::View& view) const // Set up shaders from the Oculus SDK documentation osg::ref_ptr program = new osg::Program; osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); + + if (m_useTimeWarp) { + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); + } else { + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); + } + osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); program->addShader(vertexShader); @@ -163,6 +169,16 @@ void OculusViewConfig::configure(osgViewer::View& view) const leftEyeStateSet->addUniform(new osg::Uniform("Texture", 0)); leftEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(0))); leftEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(0))); + + // Uniforms needed for time warp + if (m_useTimeWarp) { + osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(0)); + osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(0)); + leftEyeStateSet->addUniform(eyeRotationStart); + leftEyeStateSet->addUniform(eyeRotationEnd); + eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, 0)); + eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, 0)); + } osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); rightEyeStateSet->setTextureAttributeAndModes(0, textureRight, osg::StateAttribute::ON); @@ -171,6 +187,16 @@ void OculusViewConfig::configure(osgViewer::View& view) const rightEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(1))); rightEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(1))); + // Uniforms needed for time warp + if (m_useTimeWarp) { + osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(1)); + osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(1)); + rightEyeStateSet->addUniform(eyeRotationStart); + rightEyeStateSet->addUniform(eyeRotationEnd); + eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, 1)); + eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, 1)); + } + // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, m_device->projectionOffsetMatrixLeft(), @@ -230,3 +256,12 @@ void OculusViewConfigOrientationCallback::operator() (osg::Node* node, osg::Node traverse(node, nv); } + +void EyeRotationCallback::operator() (osg::Uniform* uniform, osg::NodeVisitor*) { + if (m_mode == START) { + uniform->set(m_device->eyeRotationStart(m_eyeNum)); + } + else if (m_mode == END) { + uniform->set(m_device->eyeRotationEnd(m_eyeNum)); + } +} diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index baa1355..bcb3b0a 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -18,6 +18,7 @@ class OculusViewConfig : public osgViewer::ViewConfig { m_useChromaticAberrationCorrection(true), m_useOrientations(true), m_useCustomScaleFactor(false), + m_useTimeWarp(true), m_customScaleFactor(1.0f), m_nearClip(0.01f), m_farClip(10000.0f), @@ -43,6 +44,7 @@ class OculusViewConfig : public osgViewer::ViewConfig { bool m_configured; bool m_useOrientations; bool m_useChromaticAberrationCorrection; + bool m_useTimeWarp; bool m_useCustomScaleFactor; float m_customScaleFactor; float m_nearClip; @@ -76,8 +78,8 @@ class OculusViewConfigOrientationCallback : public osg::NodeCallback { public: OculusViewConfigOrientationCallback(osg::ref_ptr rttLeft, osg::ref_ptr rttRight, - osg::observer_ptr device, - osg::observer_ptr swapCallback) : m_cameraRTTLeft(rttLeft), m_cameraRTTRight(rttRight), m_device(device), m_swapCallback(swapCallback) {}; + osg::ref_ptr device, + osg::ref_ptr swapCallback) : m_cameraRTTLeft(rttLeft), m_cameraRTTRight(rttRight), m_device(device), m_swapCallback(swapCallback) {}; virtual void operator() (osg::Node* node, osg::NodeVisitor* nv); protected: osg::observer_ptr m_cameraRTTLeft, m_cameraRTTRight; @@ -85,4 +87,20 @@ class OculusViewConfigOrientationCallback : public osg::NodeCallback { osg::observer_ptr m_swapCallback; }; +class EyeRotationCallback : public osg::Uniform::Callback +{ +public: + enum Mode + { + START, + END + }; + EyeRotationCallback(Mode mode, osg::ref_ptr device, int eyeNum) : m_mode(mode), m_device(device), m_eyeNum(eyeNum) {} + virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv); +protected: + Mode m_mode; + osg::observer_ptr m_device; + unsigned int m_eyeNum; +}; + #endif /* _OSG_OCULUSVIEWCONFIG_H_ */ \ No newline at end of file diff --git a/src/warp_mesh_with_timewarp.vert b/src/warp_mesh_with_timewarp.vert new file mode 100644 index 0000000..bd38584 --- /dev/null +++ b/src/warp_mesh_with_timewarp.vert @@ -0,0 +1,60 @@ +#version 110 + +uniform vec2 EyeToSourceUVScale; +uniform vec2 EyeToSourceUVOffset; +uniform mat4 EyeRotationStart; +uniform mat4 EyeRotationEnd; + +attribute vec2 Position; +attribute vec4 Color; +attribute vec2 TexCoord0; +attribute vec2 TexCoord1; +attribute vec2 TexCoord2; + +varying vec4 oColor; +varying vec2 oTexCoord0; +varying vec2 oTexCoord1; +varying vec2 oTexCoord2; + +void main() +{ + gl_Position.x = Position.x; + gl_Position.y = Position.y; + gl_Position.z = 0.0; + gl_Position.w = 1.0; + + // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). + // These are nowreal world" vectors in direction (x,y,1) relative to the eye of the HMD. + vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 ); + vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 ); + vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 ); + + mat3 EyeRotation; + EyeRotation[0] = mix ( EyeRotationStart[0], EyeRotationEnd[0], Color.a ).xyz; + EyeRotation[1] = mix ( EyeRotationStart[1], EyeRotationEnd[1], Color.a ).xyz; + EyeRotation[2] = mix ( EyeRotationStart[2], EyeRotationEnd[2], Color.a ).xyz; + vec3 TransformedR = EyeRotation * TanEyeAngleR; + vec3 TransformedG = EyeRotation * TanEyeAngleG; + vec3 TransformedB = EyeRotation * TanEyeAngleB; + + // Project them back onto the Z=1 plane of the rendered images. + float RecipZR = 1.0 / TransformedR.z; + float RecipZG = 1.0 / TransformedG.z; + float RecipZB = 1.0 / TransformedB.z; + vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR ); + vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG ); + vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB ); + + // These are now still in TanEyeAngle space. + // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) + vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset; + vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset; + vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset; + oTexCoord0 = SrcCoordR; + oTexCoord0.y = 1.0-oTexCoord0.y; + oTexCoord1 = SrcCoordG; + oTexCoord1.y = 1.0-oTexCoord1.y; + oTexCoord2 = SrcCoordB; + oTexCoord2.y = 1.0-oTexCoord2.y; + oColor = vec4(Color.r, Color.r, Color.r, Color.r); // Used for vignette fade. +}; \ No newline at end of file From d960fb8ce14f2115a20bfaabef5bb120431ed282 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 7 Aug 2014 01:18:15 +0200 Subject: [PATCH 18/51] Moved application of shader parameters to an own function to reduce code duplication. --- src/oculusviewconfig.cpp | 50 ++++++++++++++++------------------------ src/oculusviewconfig.h | 1 + 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index f36abbe..4d787eb 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -54,6 +54,24 @@ osg::Camera* OculusViewConfig::createWarpOrthoCamera(double left, double right, return camera.release(); } +void OculusViewConfig::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, int eyeNum) const { + stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); + stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); + stateSet->addUniform(new osg::Uniform("Texture", 0)); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(eyeNum))); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(eyeNum))); + + // Uniforms needed for time warp + if (m_useTimeWarp) { + osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(eyeNum)); + osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(eyeNum)); + stateSet->addUniform(eyeRotationStart); + stateSet->addUniform(eyeRotationEnd); + eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, eyeNum)); + eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, eyeNum)); + } +} + void OculusViewConfig::configure(osgViewer::View& view) const { m_device->setNearClip(m_nearClip); @@ -164,38 +182,10 @@ void OculusViewConfig::configure(osgViewer::View& view) const // Attach shaders to each distortion mesh osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); - leftEyeStateSet->setTextureAttributeAndModes(0, textureLeft, osg::StateAttribute::ON); - leftEyeStateSet->setAttributeAndModes(program, osg::StateAttribute::ON); - leftEyeStateSet->addUniform(new osg::Uniform("Texture", 0)); - leftEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(0))); - leftEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(0))); - - // Uniforms needed for time warp - if (m_useTimeWarp) { - osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(0)); - osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(0)); - leftEyeStateSet->addUniform(eyeRotationStart); - leftEyeStateSet->addUniform(eyeRotationEnd); - eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, 0)); - eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, 0)); - } - osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); - rightEyeStateSet->setTextureAttributeAndModes(0, textureRight, osg::StateAttribute::ON); - rightEyeStateSet->setAttributeAndModes(program, osg::StateAttribute::ON); - rightEyeStateSet->addUniform(new osg::Uniform("Texture", 0)); - rightEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(1))); - rightEyeStateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(1))); - // Uniforms needed for time warp - if (m_useTimeWarp) { - osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(1)); - osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(1)); - rightEyeStateSet->addUniform(eyeRotationStart); - rightEyeStateSet->addUniform(eyeRotationEnd); - eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, 1)); - eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, 1)); - } + applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), 0); + applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), 1); // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index bcb3b0a..999225c 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -40,6 +40,7 @@ class OculusViewConfig : public osgViewer::ViewConfig { osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc) const; osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; + void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, int eyeNum) const; bool m_configured; bool m_useOrientations; From 6f4a5416b07706d260b8b75d47c78c8fd2176f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 7 Aug 2014 01:23:17 +0200 Subject: [PATCH 19/51] Removed unused variable. --- src/oculusviewconfig.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index 999225c..cc201e7 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -50,7 +50,6 @@ class OculusViewConfig : public osgViewer::ViewConfig { float m_customScaleFactor; float m_nearClip; float m_farClip; - float m_predictionDelta; osg::Node::NodeMask m_sceneNodeMask; osg::ref_ptr m_device; From ba02b88bbaef04d9c3fce0e2522e5ea7dc5f4709 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sjo=CC=88lie?= Date: Thu, 7 Aug 2014 11:35:51 +0200 Subject: [PATCH 20/51] Look for OSG_THIRD_PARTY environment variable. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 90879d7..c63feca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ IF (WIN32) ENDIF(NOT OSG_DIR) # Where to find OpenSceneGraph third party dependencies - SET(OSG_THIRD_PARTY_DIR CACHE PATH "Path where to find the OpenSceneGraph third party dependencies") + SET(OSG_THIRD_PARTY_DIR $ENV{OSG_THIRD_PARTY_DIR} CACHE PATH "Path where to find the OpenSceneGraph third party dependencies") IF(NOT OSG_THIRD_PARTY_DIR) MESSAGE(FATAL_ERROR "Error: OpenSceneGraph 3rd Party Directory not found.") ENDIF(NOT OSG_THIRD_PARTY_DIR) From 5c292de0da58f550ddbcf044bbcfeeccdb7761aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 8 Aug 2014 23:00:40 +0200 Subject: [PATCH 21/51] Set eye render order as suggested by SDK. --- src/oculusdevice.cpp | 43 ++++++++++++++++++++++++++-------------- src/oculusdevice.h | 19 ++++++++++++------ src/oculusviewconfig.cpp | 34 +++++++++++++++---------------- src/oculusviewconfig.h | 8 ++++---- 4 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index c156ccd..ed98e69 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -143,7 +143,7 @@ osg::Matrix OculusDevice::projectionMatrixRight() const osg::Matrix OculusDevice::projectionOffsetMatrixLeft() const { osg::Matrix projectionOffsetMatrix; - float offset = m_leftEyeProjectionMatrix(2, 0) * aspectRatio(0); // Ugly hack to extract projection offset + float offset = m_leftEyeProjectionMatrix(2, 0) * aspectRatio(LEFT); // Ugly hack to extract projection offset projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0));// return projectionOffsetMatrix; @@ -152,7 +152,7 @@ osg::Matrix OculusDevice::projectionOffsetMatrixLeft() const osg::Matrix OculusDevice::projectionOffsetMatrixRight() const { osg::Matrix projectionOffsetMatrix; - float offset = m_rightEyeProjectionMatrix(2, 0) * aspectRatio(1); // Ugly hack to extract projection offset + float offset = m_rightEyeProjectionMatrix(2, 0) * aspectRatio(RIGHT); // Ugly hack to extract projection offset projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0)); return projectionOffsetMatrix; } @@ -195,11 +195,24 @@ void OculusDevice::resetSensorOrientation() const { ovrHmd_RecenterPose(m_hmdDevice); } -osg::Geode* OculusDevice::distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h) { +int OculusDevice::renderOrder(Eye eye) const { + for (int eyeIndex = 0; eyeIndex < ovrEye_Count; ++eyeIndex) { + ovrEyeType ovrEye = m_hmdDevice->EyeRenderOrder[eyeIndex]; + if (ovrEye == ovrEye_Left && eye == LEFT) { + return eyeIndex; + } + if (ovrEye == ovrEye_Right && eye == RIGHT) { + return eyeIndex; + } + } + return 0; +} + +osg::Geode* OculusDevice::distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h) { osg::ref_ptr geode = new osg::Geode; // Allocate & generate distortion mesh vertices. ovrDistortionMesh meshData; - ovrHmd_CreateDistortionMesh(m_hmdDevice, m_eyeRenderDesc[eyeNum].Eye, m_eyeRenderDesc[eyeNum].Fov, ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp, &meshData); + ovrHmd_CreateDistortionMesh(m_hmdDevice, m_eyeRenderDesc[eye].Eye, m_eyeRenderDesc[eye].Fov, ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp, &meshData); // Now parse the vertex data and create a render ready vertex buffer from it ovrDistortionVertex* ov = meshData.pVertexData; @@ -265,24 +278,24 @@ osg::Geode* OculusDevice::distortionMesh(int eyeNum, osg::Program* program, int eyeRenderViewport.Pos.y = y; eyeRenderViewport.Size.w = w; eyeRenderViewport.Size.h = h; - ovrHmd_GetRenderScaleAndOffset(m_eyeRenderDesc[eyeNum].Fov, m_renderTargetSize, eyeRenderViewport, m_UVScaleOffset[eyeNum]); + ovrHmd_GetRenderScaleAndOffset(m_eyeRenderDesc[eye].Fov, m_renderTargetSize, eyeRenderViewport, m_UVScaleOffset[eye]); geode->addDrawable(geometry); return geode.release(); } -osg::Vec2f OculusDevice::eyeToSourceUVScale(int eyeNum) const { - osg::Vec2f uvScale(m_UVScaleOffset[eyeNum][0].x, m_UVScaleOffset[eyeNum][0].y); +osg::Vec2f OculusDevice::eyeToSourceUVScale(Eye eye) const { + osg::Vec2f uvScale(m_UVScaleOffset[eye][0].x, m_UVScaleOffset[eye][0].y); return uvScale; } -osg::Vec2f OculusDevice::eyeToSourceUVOffset(int eyeNum) const { - osg::Vec2f uvOffset(m_UVScaleOffset[eyeNum][1].x, m_UVScaleOffset[eyeNum][1].y); +osg::Vec2f OculusDevice::eyeToSourceUVOffset(Eye eye) const { + osg::Vec2f uvOffset(m_UVScaleOffset[eye][1].x, m_UVScaleOffset[eye][1].y); return uvOffset; } -osg::Matrixf OculusDevice::eyeRotationStart(int eyeNum) const { +osg::Matrixf OculusDevice::eyeRotationStart(Eye eye) const { osg::Matrixf rotationStart; - ovrMatrix4f rotationMatrix = m_timeWarpMatrices[eyeNum][0]; + ovrMatrix4f rotationMatrix = m_timeWarpMatrices[eye][0]; // Transpose matrix rotationStart.set(rotationMatrix.M[0][0], rotationMatrix.M[1][0], rotationMatrix.M[2][0], rotationMatrix.M[3][0], rotationMatrix.M[0][1], rotationMatrix.M[1][1], rotationMatrix.M[2][1], rotationMatrix.M[3][1], @@ -292,10 +305,10 @@ osg::Matrixf OculusDevice::eyeRotationStart(int eyeNum) const { return rotationStart; } -osg::Matrixf OculusDevice::eyeRotationEnd(int eyeNum) const { +osg::Matrixf OculusDevice::eyeRotationEnd(Eye eye) const { osg::Matrixf rotationEnd; - ovrMatrix4f rotationMatrix = m_timeWarpMatrices[eyeNum][1]; + ovrMatrix4f rotationMatrix = m_timeWarpMatrices[eye][1]; // Transpose matrix rotationEnd.set(rotationMatrix.M[0][0], rotationMatrix.M[1][0], rotationMatrix.M[2][0], rotationMatrix.M[3][0], rotationMatrix.M[0][1], rotationMatrix.M[1][1], rotationMatrix.M[2][1], rotationMatrix.M[3][1], @@ -305,8 +318,8 @@ osg::Matrixf OculusDevice::eyeRotationEnd(int eyeNum) const { return rotationEnd; } -float OculusDevice::aspectRatio(int eyeNum) const { - return float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.w) / float(m_eyeRenderDesc[eyeNum].DistortedViewport.Size.h); +float OculusDevice::aspectRatio(Eye eye) const { + return float(m_eyeRenderDesc[eye].DistortedViewport.Size.w) / float(m_eyeRenderDesc[eye].DistortedViewport.Size.h); } void OculusDevice::beginFrameTiming(unsigned int frameIndex) { diff --git a/src/oculusdevice.h b/src/oculusdevice.h index eb92fa3..29e41a7 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -19,6 +19,12 @@ class OculusDevice : public osg::Referenced { public: + enum Eye + { + LEFT = 0, + RIGHT = 1, + COUNT = 2 + }; OculusDevice(); unsigned int hScreenResolution() const; @@ -49,18 +55,19 @@ class OculusDevice : public osg::Referenced { osg::Vec3 position() const { return m_position; } osg::Quat orientation() const { return m_orientation; } - osg::Geode* distortionMesh(int eyeNum, osg::Program* program, int x, int y, int w, int h); - osg::Vec2f eyeToSourceUVScale(int eyeNum) const; - osg::Vec2f eyeToSourceUVOffset(int eyeNum) const; - osg::Matrixf eyeRotationStart(int eyeNum) const; - osg::Matrixf eyeRotationEnd(int eyeNum) const; + int renderOrder(Eye eye) const; + osg::Geode* distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h); + osg::Vec2f eyeToSourceUVScale(Eye eye) const; + osg::Vec2f eyeToSourceUVOffset(Eye eye) const; + osg::Matrixf eyeRotationStart(Eye eye) const; + osg::Matrixf eyeRotationEnd(Eye eye) const; void beginFrameTiming(unsigned int frameIndex=0); void endFrameTiming() const; void waitTillTime(); protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected - float aspectRatio(int eyeNum) const; + float aspectRatio(Eye eye) const; ovrHmd m_hmdDevice; ovrSizei m_resolution; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 4d787eb..5cfbd01 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -17,7 +17,7 @@ #include "oculusviewconfig.h" #include "oculusdevice.h" -osg::Camera* OculusViewConfig::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc) const +osg::Camera* OculusViewConfig::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const { osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); @@ -25,7 +25,7 @@ osg::Camera* OculusViewConfig::createRTTCamera(osg::Texture* texture, osg::Graph camera->setDrawBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); - camera->setRenderOrder(osg::Camera::PRE_RENDER); + camera->setRenderOrder(osg::Camera::PRE_RENDER, (int) m_device->renderOrder(eye)); camera->setAllowEventFocus(false); camera->setGraphicsContext(gc); camera->setReferenceFrame(osg::Camera::RELATIVE_RF); @@ -54,21 +54,21 @@ osg::Camera* OculusViewConfig::createWarpOrthoCamera(double left, double right, return camera.release(); } -void OculusViewConfig::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, int eyeNum) const { +void OculusViewConfig::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); stateSet->addUniform(new osg::Uniform("Texture", 0)); - stateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(eyeNum))); - stateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(eyeNum))); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(eye))); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(eye))); // Uniforms needed for time warp if (m_useTimeWarp) { - osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(eyeNum)); - osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(eyeNum)); + osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(eye)); + osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(eye)); stateSet->addUniform(eyeRotationStart); stateSet->addUniform(eyeRotationEnd); - eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, eyeNum)); - eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, eyeNum)); + eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, eye)); + eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, eye)); } } @@ -143,8 +143,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const textureRight->setTextureSize( textureWidth, textureHeight ); textureRight->setInternalFormat( GL_RGBA ); // Create RTT cameras and attach textures - osg::ref_ptr cameraRTTLeft = createRTTCamera(textureLeft, gc); - osg::ref_ptr cameraRTTRight = createRTTCamera(textureRight, gc); + osg::ref_ptr cameraRTTLeft = createRTTCamera(textureLeft, gc, OculusDevice::Eye::LEFT); + osg::ref_ptr cameraRTTRight = createRTTCamera(textureRight, gc, OculusDevice::Eye::RIGHT); cameraRTTLeft->setName("LeftRTT"); cameraRTTRight->setName("RightRTT"); cameraRTTLeft->setCullMask(m_sceneNodeMask); @@ -171,10 +171,10 @@ void OculusViewConfig::configure(osgViewer::View& view) const program->addShader(fragmentShader); // Create distortionMesh for each camera - osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(0, program, 0, 0, textureWidth, textureHeight); + osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(leftDistortionMesh); - osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(1, program, textureWidth, 0, textureWidth, textureHeight); + osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::RIGHT, program, textureWidth, 0, textureWidth, textureHeight); cameraWarp->addChild(rightDistortionMesh); // Add pre draw camera to handle time warp @@ -184,8 +184,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); - applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), 0); - applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), 1); + applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::Eye::LEFT); + applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::Eye::RIGHT); // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, @@ -249,9 +249,9 @@ void OculusViewConfigOrientationCallback::operator() (osg::Node* node, osg::Node void EyeRotationCallback::operator() (osg::Uniform* uniform, osg::NodeVisitor*) { if (m_mode == START) { - uniform->set(m_device->eyeRotationStart(m_eyeNum)); + uniform->set(m_device->eyeRotationStart(m_eye)); } else if (m_mode == END) { - uniform->set(m_device->eyeRotationEnd(m_eyeNum)); + uniform->set(m_device->eyeRotationEnd(m_eye)); } } diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index cc201e7..ceb44ca 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -38,9 +38,9 @@ class OculusViewConfig : public osgViewer::ViewConfig { protected: ~OculusViewConfig() {}; - osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc) const; + osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; - void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, int eyeNum) const; + void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; bool m_configured; bool m_useOrientations; @@ -95,12 +95,12 @@ class EyeRotationCallback : public osg::Uniform::Callback START, END }; - EyeRotationCallback(Mode mode, osg::ref_ptr device, int eyeNum) : m_mode(mode), m_device(device), m_eyeNum(eyeNum) {} + EyeRotationCallback(Mode mode, osg::ref_ptr device, OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv); protected: Mode m_mode; osg::observer_ptr m_device; - unsigned int m_eyeNum; + OculusDevice::Eye m_eye; }; #endif /* _OSG_OCULUSVIEWCONFIG_H_ */ \ No newline at end of file From 6dc663168176c68580930610be0a05680b8bd5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 9 Aug 2014 02:43:29 +0200 Subject: [PATCH 22/51] Reset frame timing when using an emulated device. --- src/oculusdevice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index ed98e69..6a28152 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -27,6 +27,7 @@ OculusDevice::OculusDevice() : m_hmdDevice(0), if (!m_hmdDevice) { osg::notify(osg::WARN) << "Warning: No device could be found. Creating emulated device " << std::endl; m_hmdDevice = ovrHmd_CreateDebug(ovrHmd_DK1); + ovrHmd_ResetFrameTiming(m_hmdDevice, 0); } if (m_hmdDevice) { From 1ea384e5aba8b0184953c26c24175683f8f50a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 14 Aug 2014 10:38:13 +0200 Subject: [PATCH 23/51] Changed enum to support pre-C++11 compilers. --- src/oculusviewconfig.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 5cfbd01..ff5ebd1 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -143,8 +143,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const textureRight->setTextureSize( textureWidth, textureHeight ); textureRight->setInternalFormat( GL_RGBA ); // Create RTT cameras and attach textures - osg::ref_ptr cameraRTTLeft = createRTTCamera(textureLeft, gc, OculusDevice::Eye::LEFT); - osg::ref_ptr cameraRTTRight = createRTTCamera(textureRight, gc, OculusDevice::Eye::RIGHT); + osg::ref_ptr cameraRTTLeft = createRTTCamera(textureLeft, gc, OculusDevice::LEFT); + osg::ref_ptr cameraRTTRight = createRTTCamera(textureRight, gc, OculusDevice::RIGHT); cameraRTTLeft->setName("LeftRTT"); cameraRTTRight->setName("RightRTT"); cameraRTTLeft->setCullMask(m_sceneNodeMask); @@ -171,10 +171,10 @@ void OculusViewConfig::configure(osgViewer::View& view) const program->addShader(fragmentShader); // Create distortionMesh for each camera - osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); + osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::LEFT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(leftDistortionMesh); - osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::RIGHT, program, textureWidth, 0, textureWidth, textureHeight); + osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::RIGHT, program, textureWidth, 0, textureWidth, textureHeight); cameraWarp->addChild(rightDistortionMesh); // Add pre draw camera to handle time warp @@ -184,8 +184,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); - applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::Eye::LEFT); - applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::Eye::RIGHT); + applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT); + applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT); // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, From a19752af758a3afff9246bcaf1896a00b3d53510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 14 Aug 2014 10:44:56 +0200 Subject: [PATCH 24/51] Use absolute paths as default when doing out of source builds. --- CMakeLists.txt | 14 ++++++++++++-- src/CMakeLists.txt | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c63feca..45269bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,18 @@ PROJECT(OsgOculusViewer) SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -# Show relative paths options -OPTION(CMAKE_USE_RELATIVE_PATHS "If true, cmake will use relative paths in makefiles and projects." ON) +# Check if we are doing out of source builds +STRING(COMPARE NOTEQUAL ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} CMAKE_OUT_OF_SOURCE_BUILD) + +# Relative paths can be trouble when doing out of source builds +IF(CMAKE_OUT_OF_SOURCE_BUILD) + SET(DEFAULT_RELATIVE_PATHS OFF) +ELSE() + SET(DEFAULT_RELATIVE_PATHS ON) +ENDIF() + +# Show relative paths options +OPTION(CMAKE_USE_RELATIVE_PATHS "If true, cmake will use relative paths in makefiles and projects." ${DEFAULT_RELATIVE_PATHS}) MARK_AS_ADVANCED(CMAKE_USE_RELATIVE_PATHS) # Build example viewer diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e1adf9b..a076be3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -104,7 +104,7 @@ ENDIF() #################################################################### # Copy shaders if we are doing out of source builds ##################################################################### -STRING(COMPARE NOTEQUAL ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} CMAKE_OUT_OF_SOURCE_BUILD) + IF (CMAKE_OUT_OF_SOURCE_BUILD) CONFIGURE_FILE(warp_mesh.vert warp_mesh.vert COPYONLY) CONFIGURE_FILE(warp_mesh_with_timewarp.vert warp_mesh_with_timewarp.vert COPYONLY) From 7a10a6062deec29dbdeb1d9d84843d5415288e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sjo=CC=88lie?= Date: Thu, 14 Aug 2014 10:41:31 +0200 Subject: [PATCH 25/51] Changes to make OsgOculus compile on MacOSX. --- CMakeLists.txt | 14 ++++++++++++++ cmake/FindOculusSDK.cmake | 5 ++++- src/CMakeLists.txt | 12 +++++++++++- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 45269bc..679e823 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,6 +65,13 @@ FIND_PACKAGE( OpenGL REQUIRED ) FIND_PACKAGE( OpenSceneGraph REQUIRED osgViewer osgDB osgGA) FIND_PACKAGE( OculusSDK REQUIRED ) +# Oculus SDK dependencies for Mac OSX: +IF (APPLE) + FIND_LIBRARY (CORE_FOUNDATION CoreFoundation) + FIND_LIBRARY (CORE_GRAPHICS CoreGraphics) + FIND_LIBRARY (IOKIT IOKit) +ENDIF (APPLE) + INCLUDE_DIRECTORIES(BEFORE ${OPENGL_INCLUDE_DIR} ${OPENSCENEGRAPH_INCLUDE_DIR} @@ -133,6 +140,13 @@ IF(UNIX) ADD_DEFINITIONS(-Werror) ENDIF(WARNINGS_AS_ERRORS) ENDIF(CMAKE_COMPILER_IS_GNUCC) + IF (APPLE) + # set standard lib, clang defaults to c++0x + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++98") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -stdlib=libstdc++ -Wno-overloaded-virtual -Wno-conversion") + set(WARNING_CFLAGS "") + ENDIF() ENDIF(UNIX) ############################################################################### diff --git a/cmake/FindOculusSDK.cmake b/cmake/FindOculusSDK.cmake index b7fd801..00c3493 100644 --- a/cmake/FindOculusSDK.cmake +++ b/cmake/FindOculusSDK.cmake @@ -62,13 +62,16 @@ MARK_AS_ADVANCED(OCULUS_MSVC_DIR) # Look for the library. FIND_LIBRARY(OCULUS_SDK_LIBRARY NAMES libovr libovr64 ovr HINTS ${OCULUS_SDK_ROOT_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Mac/Release ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} ) # This will find release lib on Linux if no debug is available - on Linux this is no problem and avoids # having to compile in debug when not needed -FIND_LIBRARY(OCULUS_SDK_LIBRARY_DEBUG NAMES libovr${CMAKE_DEBUG_POSTFIX} libovr64${CMAKE_DEBUG_POSTFIX} ovr${CMAKE_DEBUG_POSTFIX} ovr HINTS +FIND_LIBRARY(OCULUS_SDK_LIBRARY_DEBUG NAMES libovr${CMAKE_DEBUG_POSTFIX} libovr64${CMAKE_DEBUG_POSTFIX} ovr${CMAKE_DEBUG_POSTFIX} ovr libovr HINTS ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Mac/Debug + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Mac/Release ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Debug/${OCULUS_SDK_LIB_ARCH} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a076be3..dcae04b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -55,7 +55,17 @@ IF(USE_VIEW_CONFIG) # Link to libraries needed for Oculus on Linux IF(UNIX) - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} pthread udev X11 Xinerama) + # Oculus SDK dependencies for Mac OSX: + IF (APPLE) + TARGET_LINK_LIBRARIES ( + ${TARGET_LIBRARYNAME} + ${CORE_FOUNDATION} + ${CORE_GRAPHICS} + ${IOKIT} + ) + ELSE(APPLE) + TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} pthread udev X11 Xinerama) + ENDIF(APPLE) ENDIF(UNIX) ##################################################################### From 733de2ab6c6c2f62d3c89a59123298a61f997f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 14 Aug 2014 17:25:41 +0200 Subject: [PATCH 26/51] Better calculation of center projection matrix and a corresponding correction of distortion mesh. --- src/oculusdevice.cpp | 26 ++++++++++++++------------ src/oculusviewconfig.cpp | 6 +++--- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 6a28152..2c57d73 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -42,8 +42,8 @@ OculusDevice::OculusDevice() : m_hmdDevice(0), // Get more details about the HMD. m_resolution = m_hmdDevice->Resolution; - // Compute recommended rendertexture size - float pixelsPerDisplayPixel = 1.0f; // Decrease this value to scale the size on render texture on lower performance hardware. Values above 1.0 is unnessesary. + // Compute recommended render texture size + float pixelsPerDisplayPixel = 1.0f; // Decrease this value to scale the size on render texture on lower performance hardware. Values above 1.0 is unnecessary. ovrSizei recommenedLeftTextureSize = ovrHmd_GetFovTextureSize(m_hmdDevice, ovrEye_Left, m_hmdDevice->DefaultEyeFov[0], pixelsPerDisplayPixel); ovrSizei recommenedRightTextureSize = ovrHmd_GetFovTextureSize(m_hmdDevice, ovrEye_Right, m_hmdDevice->DefaultEyeFov[1], pixelsPerDisplayPixel); @@ -71,7 +71,7 @@ OculusDevice::OculusDevice() : m_hmdDevice(0), leftEyeProjectionMatrix.M[0][3], leftEyeProjectionMatrix.M[1][3], leftEyeProjectionMatrix.M[2][3], leftEyeProjectionMatrix.M[3][3]); ovrMatrix4f rightEyeProjectionMatrix = ovrMatrix4f_Projection(m_eyeRenderDesc[1].Fov, m_nearClip, m_farClip, isRightHanded); - // Transpose matrix + // Transpose matrix m_rightEyeProjectionMatrix.set(rightEyeProjectionMatrix.M[0][0], rightEyeProjectionMatrix.M[1][0], rightEyeProjectionMatrix.M[2][0], rightEyeProjectionMatrix.M[3][0], rightEyeProjectionMatrix.M[0][1], rightEyeProjectionMatrix.M[1][1], rightEyeProjectionMatrix.M[2][1], rightEyeProjectionMatrix.M[3][1], rightEyeProjectionMatrix.M[0][2], rightEyeProjectionMatrix.M[1][2], rightEyeProjectionMatrix.M[2][2], rightEyeProjectionMatrix.M[3][2], @@ -126,9 +126,8 @@ unsigned int OculusDevice::vRenderTargetSize() const osg::Matrix OculusDevice::projectionMatrixCenter() const { osg::Matrix projectionMatrixCenter; - projectionMatrixCenter = m_leftEyeProjectionMatrix; - projectionMatrixCenter(2, 0) = 0; // Ugly hack to make left projection matrix into a center projection matrix - return projectionMatrixCenter * osg::Matrix::scale(osg::Vec3(0.5, 1.0, 1.0)); // Scale for correct aspect ratio + projectionMatrixCenter = m_leftEyeProjectionMatrix.operator*(0.5)+m_rightEyeProjectionMatrix.operator*(0.5); + return projectionMatrixCenter; } osg::Matrix OculusDevice::projectionMatrixLeft() const @@ -144,19 +143,19 @@ osg::Matrix OculusDevice::projectionMatrixRight() const osg::Matrix OculusDevice::projectionOffsetMatrixLeft() const { osg::Matrix projectionOffsetMatrix; - float offset = m_leftEyeProjectionMatrix(2, 0) * aspectRatio(LEFT); // Ugly hack to extract projection offset - projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0));// - + float offset = m_leftEyeProjectionMatrix(2, 0); + projectionOffsetMatrix.makeTranslate(osg::Vec3(-offset, 0.0, 0.0)); return projectionOffsetMatrix; } osg::Matrix OculusDevice::projectionOffsetMatrixRight() const { osg::Matrix projectionOffsetMatrix; - float offset = m_rightEyeProjectionMatrix(2, 0) * aspectRatio(RIGHT); // Ugly hack to extract projection offset - projectionOffsetMatrix.makeTranslate(osg::Vec3(offset, 0.0, 0.0)); + float offset = m_rightEyeProjectionMatrix(2, 0); + projectionOffsetMatrix.makeTranslate(osg::Vec3(-offset, 0.0, 0.0)); return projectionOffsetMatrix; } + osg::Matrix OculusDevice::viewMatrixLeft() const { osg::Matrix viewMatrix; @@ -279,7 +278,10 @@ osg::Geode* OculusDevice::distortionMesh(Eye eye, osg::Program* program, int x, eyeRenderViewport.Pos.y = y; eyeRenderViewport.Size.w = w; eyeRenderViewport.Size.h = h; - ovrHmd_GetRenderScaleAndOffset(m_eyeRenderDesc[eye].Fov, m_renderTargetSize, eyeRenderViewport, m_UVScaleOffset[eye]); + ovrSizei renderTargetSize; + renderTargetSize.w = m_renderTargetSize.w / 2; + renderTargetSize.h = m_renderTargetSize.h; + ovrHmd_GetRenderScaleAndOffset(m_eyeRenderDesc[eye].Fov, renderTargetSize, eyeRenderViewport, m_UVScaleOffset[eye]); geode->addDrawable(geometry); return geode.release(); } diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index ff5ebd1..f176d02 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -174,15 +174,15 @@ void OculusViewConfig::configure(osgViewer::View& view) const osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::LEFT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(leftDistortionMesh); - osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::RIGHT, program, textureWidth, 0, textureWidth, textureHeight); + osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::RIGHT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(rightDistortionMesh); // Add pre draw camera to handle time warp cameraWarp->setPreDrawCallback(new WarpCameraPreDrawCallback(m_device)); // Attach shaders to each distortion mesh - osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); - osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); + osg::ref_ptr leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); + osg::ref_ptr rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT); applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT); From 431adff7a44544041b619d5bd7ba4efde70a71a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 14 Aug 2014 18:07:01 +0200 Subject: [PATCH 27/51] Fixed erranous positional tracking. This closes #16 --- src/oculusdevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 2c57d73..d2abe21 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -180,7 +180,7 @@ void OculusDevice::updatePose(unsigned int frameIndex) if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { ovrPoseStatef headpose = ts.HeadPose; ovrPosef pose = headpose.ThePose; - m_position.set(pose.Position.x, pose.Position.y, pose.Position.z); + m_position.set(-pose.Position.x, -pose.Position.y, -pose.Position.z); m_orientation.set(pose.Orientation.x, pose.Orientation.y, pose.Orientation.z, -pose.Orientation.w); // Get head pose for both eyes (used for time warp From aad0f2f9309d4e9ef6e80988c5aa3d991eb2d3a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 8 Aug 2014 23:21:06 +0200 Subject: [PATCH 28/51] Renamed the examples and added a compositeviewer example. --- CMakeLists.txt | 12 +- src/CMakeLists.txt | 154 +++++------ src/compositeviewerexample.cpp | 244 ++++++++++++++++++ ...oculusviewer.cpp => viewconfigexample.cpp} | 0 ...iewer_deprecated.cpp => viewerexample.cpp} | 0 5 files changed, 311 insertions(+), 99 deletions(-) create mode 100644 src/compositeviewerexample.cpp rename src/{osgoculusviewer.cpp => viewconfigexample.cpp} (100%) rename src/{osgoculusviewer_deprecated.cpp => viewerexample.cpp} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 679e823..c35b8af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ OPTION(CMAKE_USE_RELATIVE_PATHS "If true, cmake will use relative paths in makef MARK_AS_ADVANCED(CMAKE_USE_RELATIVE_PATHS) # Build example viewer -OPTION(BUILD_EXAMPLE "Enable to build viewer example" ON) +OPTION(BUILD_EXAMPLES "Enable to build viewer examples" ON) IF (WIN32) @@ -87,15 +87,9 @@ ENDIF(VISUAL_STUDIO_EXPRESS) # osgViewer::ViewConfig concept requires osg 3.2 or later IF(NOT OPENSCENEGRAPH_VERSION VERSION_EQUAL 3.2.0 AND NOT OPENSCENEGRAPH_VERSION VERSION_GREATER 3.2.0) - #SET (USE_VIEW_CONFIG OFF) - #SET (BUILD_DEPRECATED ON) - MESSAGE(FATAL_ERROR "Error: Currently only supporting OpenSceneGraph 3.2.0 or later.") + SET (USE_VIEW_CONFIG OFF) ELSE() SET (USE_VIEW_CONFIG ON) - OPTION(BUILD_DEPRECATED "Enable to build deprecated version as well" OFF) - IF (BUILD_DEPRECATED) - MESSAGE(FATAL_ERROR "Error: Only supports Viewer Config.") - ENDIF() ENDIF() ############################################################################### @@ -137,7 +131,7 @@ IF(UNIX) IF(CMAKE_COMPILER_IS_GNUCC) ADD_DEFINITIONS(-Wall -ansi -pedantic -Wextra) IF (WARNINGS_AS_ERRORS) - ADD_DEFINITIONS(-Werror) + ADD_DEFINITIONS(-Werror) ENDIF(WARNINGS_AS_ERRORS) ENDIF(CMAKE_COMPILER_IS_GNUCC) IF (APPLE) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dcae04b..a400644 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,115 +1,90 @@ # Target name SET(TARGET_LIBRARYNAME OsgOculus) -SET(TARGET_LIBRARYNAME_DEPRECATED OsgOculus_deprecated) -SET(TARGET_TARGETNAME OsgOculusViewer) -SET(TARGET_TARGETNAME_DEPRECATED OsgOculusViewer_deprecated) +SET(TARGET_TARGETNAME_VIEW_CONFIG OculusViewConfigExample) +SET(TARGET_TARGETNAME_VIEWER OculusViewerExample) +SET(TARGET_TARGETNAME_COMPOSITE_VIEWER OculusCompositeViewerExample) -# Target source files +# Source files for library SET(TARGET_SRC oculusdevice.cpp oculuseventhandler.cpp oculusviewconfig.cpp ) -# Target header files +# Header files for library SET(TARGET_H oculusdevice.h oculuseventhandler.h oculusviewconfig.h ) -# Target source files -SET(TARGET_DEPRECATED_SRC - oculusdevice.cpp - hmdcamera.cpp -) -# Target header files -SET(TARGET_DEPRECATED_H - oculusdevice.cpp - hmdcamera.h -) +# Add view config if available +IF (USE_VIEW_CONFIG) + SET(TARGET_SRC ${TARGET_SRC} + oculusviewconfig.cpp + ) + + SET(TARGET_H ${TARGET_H} + oculusviewconfig.h + ) +ENDIF() ##################################################################### # Create library ##################################################################### -IF(USE_VIEW_CONFIG) - ADD_LIBRARY(${TARGET_LIBRARYNAME} ${TARGET_SRC} ${TARGET_H}) - - ##################################################################### - # Linker options - ##################################################################### - - # Link to open gl libs - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} ${OPENGL_LIBRARIES} ) - - # Link to OpenSceneGraph libs - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} ${OPENSCENEGRAPH_LIBRARIES} ) - - # Link to Oculus libs - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} ${OCULUS_SDK_LIBRARIES} ) - - # Link to libraries needed for Oculus on Visual Studio - IF(MSVC) - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} winmm.lib ws2_32.lib) - ENDIF(MSVC) - - # Link to libraries needed for Oculus on Linux - IF(UNIX) - # Oculus SDK dependencies for Mac OSX: - IF (APPLE) - TARGET_LINK_LIBRARIES ( - ${TARGET_LIBRARYNAME} - ${CORE_FOUNDATION} - ${CORE_GRAPHICS} - ${IOKIT} - ) - ELSE(APPLE) - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} pthread udev X11 Xinerama) - ENDIF(APPLE) - ENDIF(UNIX) +ADD_LIBRARY(${TARGET_LIBRARYNAME} ${TARGET_SRC} ${TARGET_H}) - ##################################################################### - # Create executable - ##################################################################### - IF(BUILD_EXAMPLE) - ADD_EXECUTABLE(${TARGET_TARGETNAME} osgoculusviewer.cpp) - TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME} ${TARGET_LIBRARYNAME}) - ENDIF(BUILD_EXAMPLE) -ENDIF() +##################################################################### +# Linker options +##################################################################### -IF (BUILD_DEPRECATED) - ADD_LIBRARY(${TARGET_LIBRARYNAME_DEPRECATED} ${TARGET_DEPRECATED_SRC} ${TARGET_DEPRECATED_H}) - ##################################################################### - # Linker options - ##################################################################### +# Link to open gl libs +TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} ${OPENGL_LIBRARIES} ) - # Link to open gl libs - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME_DEPRECATED} ${OPENGL_LIBRARIES} ) +# Link to OpenSceneGraph libs +TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} ${OPENSCENEGRAPH_LIBRARIES} ) - # Link to OpenSceneGraph libs - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME_DEPRECATED} ${OPENSCENEGRAPH_LIBRARIES} ) +# Link to Oculus libs +TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} ${OCULUS_SDK_LIBRARIES} ) - # Link to Oculus libs - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME_DEPRECATED} ${OCULUS_SDK_LIBRARIES} ) +# Link to libraries needed for Oculus on Visual Studio +IF(MSVC) + TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} winmm.lib ws2_32.lib) +ENDIF(MSVC) + +# Link to libraries needed for Oculus on Linux and Mac +IF(UNIX) + # Oculus SDK dependencies for Mac OSX + IF (APPLE) + TARGET_LINK_LIBRARIES ( + ${TARGET_LIBRARYNAME} + ${CORE_FOUNDATION} + ${CORE_GRAPHICS} + ${IOKIT} + ) + ELSE(APPLE) + # Oculus SDK dependencies for Linux + TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME} pthread udev X11 Xinerama) + ENDIF(APPLE) +ENDIF(UNIX) + +##################################################################### +# Create executable +##################################################################### +IF(BUILD_EXAMPLES) + ADD_EXECUTABLE(${TARGET_TARGETNAME_VIEWER} viewerexample.cpp) + TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME_VIEWER} ${TARGET_LIBRARYNAME}) - # Link to libraries needed for Oculus on Windows - IF(WIN32) - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME_DEPRECATED} winmm.lib ) - ENDIF(WIN32) + ADD_EXECUTABLE(${TARGET_TARGETNAME_COMPOSITE_VIEWER} compositeviewerexample.cpp) + TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME_COMPOSITE_VIEWER} ${TARGET_LIBRARYNAME}) - # Link to libraries needed for Oculus on Linux - IF(UNIX) - TARGET_LINK_LIBRARIES(${TARGET_LIBRARYNAME_DEPRECATED} pthread udev X11 Xinerama) - ENDIF(UNIX) + IF (USE_VIEW_CONFIG) + ADD_EXECUTABLE(${TARGET_TARGETNAME_VIEW_CONFIG} viewconfigexample.cpp) + TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME_VIEW_CONFIG} ${TARGET_LIBRARYNAME}) + ENDIF() - ##################################################################### - # Create executable - ##################################################################### - IF(BUILD_EXAMPLE) - ADD_EXECUTABLE(${TARGET_TARGETNAME_DEPRECATED} osgoculusviewer_deprecated.cpp) - TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME_DEPRECATED} ${TARGET_LIBRARYNAME_DEPRECATED}) - ENDIF(BUILD_EXAMPLE) -ENDIF() +ENDIF(BUILD_EXAMPLES) + #################################################################### # Copy shaders if we are doing out of source builds @@ -149,13 +124,12 @@ IF(MSVC) # For visual studio 2010 (MSVC10), 2012 (MSVC11) and 2013 (MSVC12) IF(MSVC10 OR MSVC11 OR MSVC12) + CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_VIEWER}.vcxproj.user @ONLY) + CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_COMPOSITE_VIEWER}.vcxproj.user @ONLY) IF (USE_VIEW_CONFIG) - CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME}.vcxproj.user @ONLY) - ENDIF() - IF (BUILD_DEPRECATED) - CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_DEPRECATED}.vcxproj.user @ONLY) + CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_VIEW_CONFIG}.vcxproj.user @ONLY) ENDIF() + ENDIF() - ENDIF (OPENSCENEGRAPH_FOUND) ENDIF(MSVC) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp new file mode 100644 index 0000000..93363bf --- /dev/null +++ b/src/compositeviewerexample.cpp @@ -0,0 +1,244 @@ +/* +* compositeviewerexample.cpp +* +* Created on: Jul 03, 2013 +* Author: Bjorn Blissing +*/ + +#include "oculusdevice.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +osg::Geode* createScreenQuad( float width, float height, float scale=1.0f ) +{ + osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(), + osg::Vec3(width,0.0f,0.0f), + osg::Vec3(0.0f,height,0.0f), + 0.0f, + 0.0f, + width*scale, + height*scale); + osg::ref_ptr quad = new osg::Geode; + quad->addDrawable( geom ); + int values = osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED; + quad->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), values ); + quad->getOrCreateStateSet()->setMode( GL_LIGHTING, values ); + return quad.release(); +} + +osg::Camera* createRTTCamera( osg::Camera::BufferComponent buffer, osg::Texture* tex ) +{ + osg::ref_ptr camera = new osg::Camera; + camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); + camera->setClearColor( osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f) ); + camera->setClearMask( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); + camera->setRenderOrder( osg::Camera::PRE_RENDER); + + if ( tex ) { + tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR ); + tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR ); + camera->setViewport( 0, 0, tex->getTextureWidth(), tex->getTextureHeight() ); + camera->attach( buffer, tex, 0, 0, false, 4, 4); + } + + return camera.release(); +} + +osg::Camera* createHUDCamera( double left, double right, double bottom, double top ) +{ + osg::ref_ptr camera = new osg::Camera; + camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); + camera->setClearMask( GL_DEPTH_BUFFER_BIT ); + camera->setRenderOrder( osg::Camera::POST_RENDER); + camera->setAllowEventFocus( false ); + camera->setProjectionMatrix( osg::Matrix::ortho2D(left, right, bottom, top) ); + camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + camera->setViewMatrix(osg::Matrix::identity()); + return camera.release(); +} + +int main( int argc, char** argv ) +{ + OculusDevice* oculusDevice = new OculusDevice; + // use an ArgumentParser object to manage the program arguments. + osg::ArgumentParser arguments(&argc,argv); + // read the scene from the list of file specified command line arguments. + osg::ref_ptr loadedModel = osgDB::readNodeFiles(arguments); + + // if not loaded assume no arguments passed in, try use default cow model instead. + if (!loadedModel) loadedModel = osgDB::readNodeFile("cow.osgt"); + + // Still no loaded model, then exit + if (!loadedModel) return 0; + + // Set the scaleing of the texture, using the recommend 25% from the SDK + oculusDevice->setCustomScaleFactor(1.25f); + // Calculate the texture size + const int textureWidth = oculusDevice->scaleFactor() * oculusDevice->hScreenResolution()/2; + const int textureHeight = oculusDevice->scaleFactor() * oculusDevice->vScreenResolution(); + // Setup textures for the RTT cameras + osg::ref_ptr leftEyeTex2D = new osg::Texture2D; + leftEyeTex2D->setTextureSize( textureWidth, textureHeight ); + leftEyeTex2D->setInternalFormat( GL_RGBA ); + osg::ref_ptr rightEyeTex2D = new osg::Texture2D; + rightEyeTex2D->setTextureSize( textureWidth, textureHeight ); + rightEyeTex2D->setInternalFormat( GL_RGBA ); + // Initialize RTT cameras for each eye + osg::ref_ptr leftEyeRTTCamera = createRTTCamera(osg::Camera::COLOR_BUFFER, leftEyeTex2D); + leftEyeRTTCamera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); + leftEyeRTTCamera->addChild( loadedModel ); + osg::ref_ptr rightEyeRTTCamera = createRTTCamera(osg::Camera::COLOR_BUFFER, rightEyeTex2D); + rightEyeRTTCamera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); + rightEyeRTTCamera->addChild( loadedModel ); + // Create HUD cameras for each eye + osg::ref_ptr leftEyeHUDCamera = createHUDCamera(0.0, 1.0, 0.0, 1.0); + osg::ref_ptr rightEyeHUDCamera = createHUDCamera(0.0, 1.0, 0.0, 1.0); + // Create quads on each camera + osg::ref_ptr leftQuad = createScreenQuad(1.0f, 1.0f); + leftEyeHUDCamera->addChild( leftQuad ); + osg::ref_ptr rightQuad = createScreenQuad(1.0f, 1.0f); + rightEyeHUDCamera->addChild( rightQuad ); + // Set up shaders from the Oculus SDK documentation + osg::ref_ptr program = new osg::Program; + osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp.vert")); + osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); + // Fragment shader with or without correction for chromatic aberration + bool useChromaticAberrationCorrection = true; + + if (useChromaticAberrationCorrection) { + fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithChromeAb.frag")); + } else { + fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithoutChromeAb.frag")); + } + + program->addShader( vertexShader ); + program->addShader( fragmentShader ); + // Configure state sets for both eyes + osg::StateSet* leftEyeStateSet = leftQuad->getOrCreateStateSet(); + leftEyeStateSet->setTextureAttributeAndModes(0, leftEyeTex2D, osg::StateAttribute::ON); + leftEyeStateSet->setAttributeAndModes( program, osg::StateAttribute::ON ); + leftEyeStateSet->addUniform( new osg::Uniform("WarpTexture", 0) ); + leftEyeStateSet->addUniform( new osg::Uniform("LensCenter", oculusDevice->lensCenter(OculusDevice::LEFT_EYE))); + leftEyeStateSet->addUniform( new osg::Uniform("ScreenCenter", oculusDevice->screenCenter())); + leftEyeStateSet->addUniform( new osg::Uniform("Scale", oculusDevice->scale())); + leftEyeStateSet->addUniform( new osg::Uniform("ScaleIn", oculusDevice->scaleIn())); + leftEyeStateSet->addUniform( new osg::Uniform("HmdWarpParam", oculusDevice->warpParameters())); + leftEyeStateSet->addUniform( new osg::Uniform("ChromAbParam", oculusDevice->chromAbParameters())); + osg::StateSet* rightEyeStateSet = rightQuad->getOrCreateStateSet(); + rightEyeStateSet->setTextureAttributeAndModes(0, rightEyeTex2D, osg::StateAttribute::ON); + rightEyeStateSet->setAttributeAndModes( program, osg::StateAttribute::ON ); + rightEyeStateSet->addUniform( new osg::Uniform("WarpTexture", 0) ); + rightEyeStateSet->addUniform( new osg::Uniform("LensCenter", oculusDevice->lensCenter(OculusDevice::RIGHT_EYE))); + rightEyeStateSet->addUniform( new osg::Uniform("ScreenCenter", oculusDevice->screenCenter())); + rightEyeStateSet->addUniform( new osg::Uniform("Scale", oculusDevice->scale())); + rightEyeStateSet->addUniform( new osg::Uniform("ScaleIn", oculusDevice->scaleIn())); + rightEyeStateSet->addUniform( new osg::Uniform("HmdWarpParam", oculusDevice->warpParameters())); + rightEyeStateSet->addUniform( new osg::Uniform("ChromAbParam", oculusDevice->chromAbParameters())); + // Add cameras to groups + osg::ref_ptr leftRoot = new osg::Group; + osg::ref_ptr rightRoot = new osg::Group; + leftRoot->addChild(leftEyeRTTCamera); + leftRoot->addChild(leftEyeHUDCamera); + rightRoot->addChild(rightEyeRTTCamera); + rightRoot->addChild(rightEyeHUDCamera); + osgViewer::CompositeViewer viewer(arguments); + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + + if (!wsi) { + osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->windowDecoration = false; + traits->x = 0; + traits->y = 0; + traits->width = oculusDevice->hScreenResolution(); + traits->height = oculusDevice->vScreenResolution(); + traits->doubleBuffer = true; + traits->sharedContext = 0; + traits->sampleBuffers = true; + traits->samples = 4; + traits->vsync = true; + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits); + + if (gc.valid()) { + gc->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); + gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } + + // Create Trackball manipulator + osg::ref_ptr cameraManipulator = new osgGA::TrackballManipulator; + const osg::BoundingSphere& bs = loadedModel->getBound(); + + if (bs.valid()) { + // Adjust view to object view + cameraManipulator->setHomePosition(osg::Vec3(0, bs.radius()*1.5, 0), osg::Vec3(0, 0, 0), osg::Vec3(0, 0, 1)); + } + + // Create views and attach camera groups to them + osg::ref_ptr leftView = new osgViewer::View; + leftView->setName("LeftEyeView"); + viewer.addView(leftView); + leftView->setSceneData( leftRoot ); + leftView->getCamera()->setName("LeftEyeCamera"); + leftView->getCamera()->setViewport(new osg::Viewport(0, 0, oculusDevice->hScreenResolution() / 2, oculusDevice->vScreenResolution())); + leftView->getCamera()->setGraphicsContext(gc); + leftView->addEventHandler( new osgViewer::StatsHandler ); + leftView->setCameraManipulator(cameraManipulator); + osg::ref_ptr rightView = new osgViewer::View; + rightView->setName("RightEyeView"); + viewer.addView(rightView); + rightView->setSceneData( rightRoot ); + rightView->getCamera()->setName("RightEyeCamera"); + rightView->getCamera()->setViewport(new osg::Viewport(oculusDevice->hScreenResolution() / 2, 0, oculusDevice->hScreenResolution() / 2, oculusDevice->vScreenResolution())); + rightView->getCamera()->setGraphicsContext(gc); + rightView->setCameraManipulator(cameraManipulator); + + // Realize viewer + if (!viewer.isRealized()) { + viewer.realize(); + } + + // Create matrix for camera position and orientation (from HMD) + osg::Matrix cameraManipulatorViewMatrix; + osg::Matrix orientationMatrix; + // Get the view matrix for each eye for later use + osg::Matrix leftEyeViewMatrix = oculusDevice->viewMatrix(OculusDevice::LEFT_EYE); + osg::Matrix rightEyeViewMatrix = oculusDevice->viewMatrix(OculusDevice::RIGHT_EYE); + // Set the projection matrix for each eye + leftEyeRTTCamera->setProjectionMatrix(oculusDevice->projectionMatrix(OculusDevice::LEFT_EYE)); + rightEyeRTTCamera->setProjectionMatrix(oculusDevice->projectionMatrix(OculusDevice::RIGHT_EYE)); + + // Start Viewer + while (!viewer.done()) { + // Get orientation from oculus sensor + orientationMatrix.makeRotate(oculusDevice->getOrientation()); + // Get camera matrix from manipulator + cameraManipulatorViewMatrix = cameraManipulator->getInverseMatrix(); + leftEyeRTTCamera->setViewMatrix(leftEyeViewMatrix*cameraManipulatorViewMatrix*orientationMatrix); + rightEyeRTTCamera->setViewMatrix(rightEyeViewMatrix*cameraManipulatorViewMatrix*orientationMatrix); + viewer.frame(); + } + + return 0; +} \ No newline at end of file diff --git a/src/osgoculusviewer.cpp b/src/viewconfigexample.cpp similarity index 100% rename from src/osgoculusviewer.cpp rename to src/viewconfigexample.cpp diff --git a/src/osgoculusviewer_deprecated.cpp b/src/viewerexample.cpp similarity index 100% rename from src/osgoculusviewer_deprecated.cpp rename to src/viewerexample.cpp From 49816af34b6323e0977ea45245112afbaed26167 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 9 Aug 2014 00:46:42 +0200 Subject: [PATCH 29/51] Updated the classic viewer example to SDK0.4. --- src/CMakeLists.txt | 2 + src/hmdcamera.cpp | 199 +++++++++++++++++++++------------------ src/hmdcamera.h | 17 ++-- src/oculusdevice.cpp | 24 +++++ src/oculusdevice.h | 35 +++++++ src/oculusviewconfig.cpp | 23 ----- src/oculusviewconfig.h | 35 ------- src/viewerexample.cpp | 6 +- 8 files changed, 181 insertions(+), 160 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a400644..37232c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,12 +6,14 @@ SET(TARGET_TARGETNAME_COMPOSITE_VIEWER OculusCompositeViewerExample) # Source files for library SET(TARGET_SRC + hmdcamera.cpp oculusdevice.cpp oculuseventhandler.cpp oculusviewconfig.cpp ) # Header files for library SET(TARGET_H + hmdcamera.h oculusdevice.h oculuseventhandler.h oculusviewconfig.h diff --git a/src/hmdcamera.cpp b/src/hmdcamera.cpp index fb83193..52a5b1d 100644 --- a/src/hmdcamera.cpp +++ b/src/hmdcamera.cpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -23,6 +22,11 @@ HMDCamera::HMDCamera(osgViewer::View* view, osg::ref_ptr dev) : osg::Group(), m_configured(false), m_useChromaticAberrationCorrection(false), + m_useTimeWarp(true), + m_useCustomScaleFactor(false), + m_customScaleFactor(1.0f), + m_nearClip(0.01f), + m_farClip(10000.0f), m_view(view), m_device(dev) { @@ -39,29 +43,38 @@ void HMDCamera::traverse(osg::NodeVisitor& nv) configure(); } - // Get orientation from oculus sensor - osg::Quat orient = m_device->getOrientation(); - // Nasty hack to update the view offset for each of the slave cameras - // There doesn't seem to be an accessor for this, fortunately the offsets are public - m_view->findSlaveForCamera(m_cameraRTTLeft.get())->_viewOffset.setRotate(orient); - m_view->findSlaveForCamera(m_cameraRTTRight.get())->_viewOffset.setRotate(orient); + if (m_configured) { + m_device.get()->updatePose(m_swapCallback->frameIndex()); + osg::Vec3 position = m_device.get()->position(); + osg::Quat orientation = m_device.get()->orientation(); + osg::Matrix viewOffsetLeft = m_device.get()->viewMatrixLeft(); + osg::Matrix viewOffsetRight = m_device.get()->viewMatrixRight(); + viewOffsetLeft.preMultTranslate(position); + viewOffsetRight.preMultTranslate(position); + viewOffsetLeft.postMultRotate(orientation); + viewOffsetRight.postMultRotate(orientation); + // Nasty hack to update the view offset for each of the slave cameras + // There doesn't seem to be an accessor for this, fortunately the offsets are public + m_view->findSlaveForCamera(m_cameraRTTLeft.get())->_viewOffset = viewOffsetLeft; + m_view->findSlaveForCamera(m_cameraRTTRight.get())->_viewOffset = viewOffsetRight; + } osg::Group::traverse(nv); } -osg::Camera* HMDCamera::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc) const +osg::Camera* HMDCamera::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const { osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); - camera->setClearMask( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); + camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camera->setDrawBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT); - camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); - camera->setRenderOrder(osg::Camera::PRE_RENDER); + camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); + camera->setRenderOrder(osg::Camera::PRE_RENDER, (int)m_device->renderOrder(eye)); camera->setAllowEventFocus(false); camera->setGraphicsContext(gc); camera->setReferenceFrame(osg::Camera::RELATIVE_RF); - if ( texture ) { + if (texture) { texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); camera->setViewport(0, 0, texture->getTextureWidth(), texture->getTextureHeight()); @@ -71,122 +84,124 @@ osg::Camera* HMDCamera::createRTTCamera(osg::Texture* texture, osg::GraphicsCont return camera.release(); } -osg::Camera* HMDCamera::createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const +osg::Camera* HMDCamera::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const { osg::ref_ptr camera = new osg::Camera; - camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); - camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); - camera->setClearMask( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setAllowEventFocus(false); camera->setGraphicsContext(gc); camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top)); - camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); return camera.release(); } -osg::Geode* HMDCamera::createHUDQuad( float width, float height, float scale ) const -{ - osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(), - osg::Vec3(width, 0.0f, 0.0f), - osg::Vec3(0.0f, height, 0.0f), - 0.0f, 0.0f, width*scale, height*scale ); - osg::ref_ptr quad = new osg::Geode; - quad->addDrawable( geom ); - int values = osg::StateAttribute::OFF | osg::StateAttribute::PROTECTED; - quad->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), values ); - quad->getOrCreateStateSet()->setMode( GL_LIGHTING, values ); - return quad.release(); -} - -void HMDCamera::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, - osg::Texture2D* texture, OculusDevice::EyeSide eye) const { - stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); - stateSet->setAttributeAndModes( program, osg::StateAttribute::ON ); - stateSet->addUniform( new osg::Uniform("WarpTexture", 0) ); - stateSet->addUniform( new osg::Uniform("LensCenter", m_device->lensCenter(eye))); - stateSet->addUniform( new osg::Uniform("ScreenCenter", m_device->screenCenter())); - stateSet->addUniform( new osg::Uniform("Scale", m_device->scale())); - stateSet->addUniform( new osg::Uniform("ScaleIn", m_device->scaleIn())); - stateSet->addUniform( new osg::Uniform("HmdWarpParam", m_device->warpParameters())); - stateSet->addUniform( new osg::Uniform("ChromAbParam", m_device->chromAbParameters())); +void HMDCamera::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { + stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); + stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); + stateSet->addUniform(new osg::Uniform("Texture", 0)); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(eye))); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(eye))); + + // Uniforms needed for time warp + if (m_useTimeWarp) { + osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(eye)); + osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(eye)); + stateSet->addUniform(eyeRotationStart); + stateSet->addUniform(eyeRotationEnd); + eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, eye)); + eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, eye)); + } } void HMDCamera::configure() { - const int textureWidth = m_device->scaleFactor() * m_device->hScreenResolution()/2; - const int textureHeight = m_device->scaleFactor() * m_device->vScreenResolution(); + m_device->setNearClip(m_nearClip); + m_device->setFarClip(m_farClip); + + osg::ref_ptr gc = m_view->getCamera()->getGraphicsContext(); - // master projection matrix - m_view->getCamera()->setProjectionMatrix(m_device->projectionCenterMatrix()); - m_view->setName("Oculus"); - osg::ref_ptr mainCamera = m_view->getCamera(); - mainCamera->setName("Main"); + // Attach a callback to detect swap + m_swapCallback = new OculusSwapCallback(m_device); + gc->setSwapCallback(m_swapCallback); + + osg::ref_ptr camera = m_view->getCamera(); + camera->setName("Main"); + // Disable scene rendering for main camera - mainCamera->setCullMask(~m_sceneNodeMask); + camera->setCullMask(~m_sceneNodeMask); + const int textureWidth = m_device->hRenderTargetSize()/2; + const int textureHeight = m_device->vRenderTargetSize(); + // master projection matrix + camera->setProjectionMatrix(m_device->projectionMatrixCenter()); + // Create textures for RTT cameras osg::ref_ptr textureLeft = new osg::Texture2D; - textureLeft->setTextureSize( textureWidth, textureHeight ); - textureLeft->setInternalFormat( GL_RGBA ); + textureLeft->setTextureSize(textureWidth, textureHeight); + textureLeft->setInternalFormat(GL_RGBA); osg::ref_ptr textureRight = new osg::Texture2D; - textureRight->setTextureSize( textureWidth, textureHeight ); - textureRight->setInternalFormat( GL_RGBA ); - - osg::ref_ptr gc = mainCamera->getGraphicsContext(); - // Create render to texture cameras - m_cameraRTTLeft = createRTTCamera(textureLeft, gc.get()); - m_cameraRTTRight = createRTTCamera(textureRight, gc.get()); + textureRight->setTextureSize(textureWidth, textureHeight); + textureRight->setInternalFormat(GL_RGBA); + // Create RTT cameras and attach textures + m_cameraRTTLeft = createRTTCamera(textureLeft, gc, OculusDevice::Eye::LEFT); + m_cameraRTTRight = createRTTCamera(textureRight, gc, OculusDevice::Eye::RIGHT); m_cameraRTTLeft->setName("LeftRTT"); m_cameraRTTRight->setName("RightRTT"); m_cameraRTTLeft->setCullMask(m_sceneNodeMask); m_cameraRTTRight->setCullMask(m_sceneNodeMask); - - // Create HUD cameras for each eye - osg::ref_ptr cameraHUDLeft = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc.get()); - cameraHUDLeft->setName("LeftHUD"); - cameraHUDLeft->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution() / 2.0f, m_device->vScreenResolution())); - osg::ref_ptr cameraHUDRight = createHUDCamera(0.0, 1.0, 0.0, 1.0, gc.get()); - cameraHUDRight->setName("RightHUD"); - cameraHUDRight->setViewport(new osg::Viewport(m_device->hScreenResolution() / 2.0f, 0, - m_device->hScreenResolution() / 2.0f, m_device->vScreenResolution())); - // Create quads on each camera - osg::ref_ptr leftQuad = createHUDQuad(1.0f, 1.0f); - cameraHUDLeft->addChild(leftQuad); - osg::ref_ptr rightQuad = createHUDQuad(1.0f, 1.0f); - cameraHUDRight->addChild(rightQuad); - + // Create warp ortho camera + osg::ref_ptr cameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); + cameraWarp->setName("WarpOrtho"); + cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); + // Set up shaders from the Oculus SDK documentation osg::ref_ptr program = new osg::Program; osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp.vert")); - osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); - // Fragment shader with or without correction for chromatic aberration - if (m_useChromaticAberrationCorrection) { - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithChromeAb.frag")); + if (m_useTimeWarp) { + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); } else { - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithoutChromeAb.frag")); + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); } + osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); + fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); program->addShader(vertexShader); program->addShader(fragmentShader); - // Attach shaders to each HUD - osg::StateSet* leftEyeStateSet = leftQuad->getOrCreateStateSet(); - osg::StateSet* rightEyeStateSet = rightQuad->getOrCreateStateSet(); - applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT_EYE); - applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT_EYE); + // Create distortionMesh for each camera + osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); + cameraWarp->addChild(leftDistortionMesh); + + osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::RIGHT, program, textureWidth, 0, textureWidth, textureHeight); + cameraWarp->addChild(rightDistortionMesh); - // Add cameras as slaves, specifying offsets for the projection - m_view->addSlave(m_cameraRTTLeft.get(), m_device->projectionOffsetMatrix(OculusDevice::LEFT_EYE), - m_device->viewMatrix(OculusDevice::LEFT_EYE), + // Add pre draw camera to handle time warp + cameraWarp->setPreDrawCallback(new WarpCameraPreDrawCallback(m_device)); + + // Attach shaders to each distortion mesh + osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); + osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); + + applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::Eye::LEFT); + applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::Eye::RIGHT); + + // Add RTT cameras as slaves, specifying offsets for the projection + m_view->addSlave(m_cameraRTTLeft.get(), + m_device->projectionOffsetMatrixLeft(), + m_device->viewMatrixLeft(), true); - m_view->addSlave(m_cameraRTTRight.get(), m_device->projectionOffsetMatrix(OculusDevice::RIGHT_EYE), - m_device->viewMatrix(OculusDevice::RIGHT_EYE), + m_view->addSlave(m_cameraRTTRight.get(), + m_device->projectionOffsetMatrixRight(), + m_device->viewMatrixRight(), true); - m_view->addSlave(cameraHUDLeft, false); - m_view->addSlave(cameraHUDRight, false); + + // Add warp camera as slave + m_view->addSlave(cameraWarp, false); + m_view->setName("Oculus"); + m_configured = true; } diff --git a/src/hmdcamera.h b/src/hmdcamera.h index a0773c8..a5c5262 100644 --- a/src/hmdcamera.h +++ b/src/hmdcamera.h @@ -21,22 +21,27 @@ class HMDCamera: public osg::Group { public: HMDCamera(osgViewer::View* view, osg::ref_ptr dev); virtual void traverse(osg::NodeVisitor& nv); - void setChromaticAberrationCorrection(bool correctionEnabled) { m_useChromaticAberrationCorrection = correctionEnabled; } void setSceneNodeMask(osg::Node::NodeMask nodeMask) { m_sceneNodeMask = nodeMask; } protected: ~HMDCamera(); virtual void configure(); - osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc) const; - osg::Camera* createHUDCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; - osg::Geode* createHUDQuad(float width, float height, float scale = 1.0f) const; - void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, - osg::Texture2D* texture, OculusDevice::EyeSide eye) const; + osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; + osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; + void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; + bool m_configured; bool m_useChromaticAberrationCorrection; + bool m_useTimeWarp; + bool m_useCustomScaleFactor; + float m_customScaleFactor; + float m_nearClip; + float m_farClip; + osg::observer_ptr m_view; osg::observer_ptr m_cameraRTTLeft, m_cameraRTTRight; osg::observer_ptr m_device; + osg::ref_ptr m_swapCallback; osg::Node::NodeMask m_sceneNodeMask; }; diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index d2abe21..70fc79e 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -341,4 +341,28 @@ void OculusDevice::waitTillTime() { for (int eyeIndex = 0; eyeIndex < ovrEye_Count; ++eyeIndex) { ovrHmd_GetEyeTimewarpMatrices(m_hmdDevice, (ovrEyeType)eyeIndex, m_headPose[eyeIndex], m_timeWarpMatrices[eyeIndex]); } +} + +void WarpCameraPreDrawCallback::operator()(osg::RenderInfo&) const +{ + // Wait till time - warp point to reduce latency. + m_device->waitTillTime(); +} + +void OculusSwapCallback::swapBuffersImplementation(osg::GraphicsContext *gc) { + // Run the default system swapBufferImplementation + gc->swapBuffersImplementation(); + // End frame timing when swap buffer is done + m_device->endFrameTiming(); + // Start a new frame with incremented frame index + m_device->beginFrameTiming(++m_frameIndex); +} + +void EyeRotationCallback::operator() (osg::Uniform* uniform, osg::NodeVisitor*) { + if (m_mode == START) { + uniform->set(m_device->eyeRotationStart(m_eye)); + } + else if (m_mode == END) { + uniform->set(m_device->eyeRotationEnd(m_eye)); + } } \ No newline at end of file diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 29e41a7..8187b4d 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -92,4 +92,39 @@ class OculusDevice : public osg::Referenced { OculusDevice(const OculusDevice&); // Do not allow copy }; +class WarpCameraPreDrawCallback : public osg::Camera::DrawCallback +{ +public: + WarpCameraPreDrawCallback(osg::ref_ptr device) : m_device(device) {} + virtual void operator()(osg::RenderInfo& renderInfo) const; +protected: + osg::observer_ptr m_device; +}; + +class OculusSwapCallback : public osg::GraphicsContext::SwapCallback { +public: + OculusSwapCallback(osg::ref_ptr device) : m_device(device), m_frameIndex(0) {} + void swapBuffersImplementation(osg::GraphicsContext *gc); + int frameIndex() const { return m_frameIndex; } +private: + osg::observer_ptr m_device; + int m_frameIndex; +}; + +class EyeRotationCallback : public osg::Uniform::Callback +{ +public: + enum Mode + { + START, + END + }; + EyeRotationCallback(Mode mode, osg::observer_ptr device, OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} + virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv); +protected: + Mode m_mode; + osg::observer_ptr m_device; + OculusDevice::Eye m_eye; +}; + #endif /* _OSG_OCULUSDEVICE_H_ */ diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index f176d02..1aef6ae 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -208,21 +208,6 @@ void OculusViewConfig::configure(osgViewer::View& view) const } } -void WarpCameraPreDrawCallback::operator()(osg::RenderInfo&) const -{ - // Wait till time - warp point to reduce latency. - m_device->waitTillTime(); -} - -void OculusSwapCallback::swapBuffersImplementation(osg::GraphicsContext *gc) { - // Run the default system swapBufferImplementation - gc->swapBuffersImplementation(); - // End frame timing when swap buffer is done - m_device->endFrameTiming(); - // Start a new frame with incremented frame index - m_device->beginFrameTiming(++m_frameIndex); -} - void OculusViewConfigOrientationCallback::operator() (osg::Node* node, osg::NodeVisitor* nv) { osg::Camera* mainCamera = static_cast(node); @@ -247,11 +232,3 @@ void OculusViewConfigOrientationCallback::operator() (osg::Node* node, osg::Node traverse(node, nv); } -void EyeRotationCallback::operator() (osg::Uniform* uniform, osg::NodeVisitor*) { - if (m_mode == START) { - uniform->set(m_device->eyeRotationStart(m_eye)); - } - else if (m_mode == END) { - uniform->set(m_device->eyeRotationEnd(m_eye)); - } -} diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index ceb44ca..a2fb96a 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -55,25 +55,6 @@ class OculusViewConfig : public osgViewer::ViewConfig { osg::ref_ptr m_device; }; -class WarpCameraPreDrawCallback : public osg::Camera::DrawCallback -{ -public: - WarpCameraPreDrawCallback(osg::ref_ptr device) : m_device(device) {} - virtual void operator()(osg::RenderInfo& renderInfo) const; -protected: - osg::observer_ptr m_device; -}; - -class OculusSwapCallback : public osg::GraphicsContext::SwapCallback { -public: - OculusSwapCallback(osg::ref_ptr device) : m_device(device), m_frameIndex(0) {} - void swapBuffersImplementation(osg::GraphicsContext *gc); - int frameIndex() const { return m_frameIndex; } -private: - osg::observer_ptr m_device; - int m_frameIndex; -}; - class OculusViewConfigOrientationCallback : public osg::NodeCallback { public: OculusViewConfigOrientationCallback(osg::ref_ptr rttLeft, @@ -87,20 +68,4 @@ class OculusViewConfigOrientationCallback : public osg::NodeCallback { osg::observer_ptr m_swapCallback; }; -class EyeRotationCallback : public osg::Uniform::Callback -{ -public: - enum Mode - { - START, - END - }; - EyeRotationCallback(Mode mode, osg::ref_ptr device, OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} - virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv); -protected: - Mode m_mode; - osg::observer_ptr m_device; - OculusDevice::Eye m_eye; -}; - #endif /* _OSG_OCULUSVIEWCONFIG_H_ */ \ No newline at end of file diff --git a/src/viewerexample.cpp b/src/viewerexample.cpp index b0d38f5..1d448d1 100644 --- a/src/viewerexample.cpp +++ b/src/viewerexample.cpp @@ -49,7 +49,6 @@ int main( int argc, char** argv ) // Open the HMD osg::ref_ptr oculusDevice = new OculusDevice(); - oculusDevice->setCustomScaleFactor(1.25f); // Create screen with match the Oculus Rift resolution osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); @@ -77,8 +76,8 @@ int main( int argc, char** argv ) traits->screenNum = si.screenNum; traits->displayNum = si.displayNum; traits->windowDecoration = false; - traits->x = 0; - traits->y = 0; + traits->x = oculusDevice->windowPos().x(); + traits->y = oculusDevice->windowPos().y(); traits->width = oculusDevice->hScreenResolution(); traits->height = oculusDevice->vScreenResolution(); traits->doubleBuffer = true; @@ -111,7 +110,6 @@ int main( int argc, char** argv ) loadedModel->setNodeMask(sceneNodeMask); osg::ref_ptr hmd_camera = new HMDCamera(&viewer, oculusDevice); - hmd_camera->setChromaticAberrationCorrection(true); hmd_camera->setSceneNodeMask(sceneNodeMask); hmd_camera->addChild(loadedModel); viewer.setSceneData(hmd_camera); From a372a1b21b2aeaf00de99a26242da118ec080f89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 9 Aug 2014 00:53:02 +0200 Subject: [PATCH 30/51] Renamed class HMDCamera to OculusViewer --- src/CMakeLists.txt | 4 ++-- src/hmdcamera.cpp | 21 ++++++++------------- src/hmdcamera.h | 14 +++++++------- src/viewerexample.cpp | 4 ++-- 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 37232c8..fa5db6f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,14 +6,14 @@ SET(TARGET_TARGETNAME_COMPOSITE_VIEWER OculusCompositeViewerExample) # Source files for library SET(TARGET_SRC - hmdcamera.cpp + oculusviewer.cpp oculusdevice.cpp oculuseventhandler.cpp oculusviewconfig.cpp ) # Header files for library SET(TARGET_H - hmdcamera.h + oculusviewer.h oculusdevice.h oculuseventhandler.h oculusviewconfig.h diff --git a/src/hmdcamera.cpp b/src/hmdcamera.cpp index 52a5b1d..580cf37 100644 --- a/src/hmdcamera.cpp +++ b/src/hmdcamera.cpp @@ -1,5 +1,5 @@ /* - * HMDCamera.cpp + * oculusviewer.cpp * * Created on: Jun 30, 2013 * Author: Jan Ciger @@ -15,11 +15,11 @@ #include -#include "hmdcamera.h" +#include "oculusviewer.h" #include "oculusdevice.h" -HMDCamera::HMDCamera(osgViewer::View* view, osg::ref_ptr dev) : osg::Group(), +OculusViewer::OculusViewer(osgViewer::View* view, osg::ref_ptr dev) : osg::Group(), m_configured(false), m_useChromaticAberrationCorrection(false), m_useTimeWarp(true), @@ -32,12 +32,7 @@ HMDCamera::HMDCamera(osgViewer::View* view, osg::ref_ptr dev) : os { } - -HMDCamera::~HMDCamera() -{ -} - -void HMDCamera::traverse(osg::NodeVisitor& nv) +void OculusViewer::traverse(osg::NodeVisitor& nv) { if (!m_configured) { configure(); @@ -61,7 +56,7 @@ void HMDCamera::traverse(osg::NodeVisitor& nv) osg::Group::traverse(nv); } -osg::Camera* HMDCamera::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const +osg::Camera* OculusViewer::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const { osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); @@ -84,7 +79,7 @@ osg::Camera* HMDCamera::createRTTCamera(osg::Texture* texture, osg::GraphicsCont return camera.release(); } -osg::Camera* HMDCamera::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const +osg::Camera* OculusViewer::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const { osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); @@ -98,7 +93,7 @@ osg::Camera* HMDCamera::createWarpOrthoCamera(double left, double right, double return camera.release(); } -void HMDCamera::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { +void OculusViewer::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); stateSet->addUniform(new osg::Uniform("Texture", 0)); @@ -116,7 +111,7 @@ void HMDCamera::applyShaderParameters(osg::StateSet* stateSet, osg::Program* pro } } -void HMDCamera::configure() +void OculusViewer::configure() { m_device->setNearClip(m_nearClip); m_device->setFarClip(m_farClip); diff --git a/src/hmdcamera.h b/src/hmdcamera.h index a5c5262..41d9a23 100644 --- a/src/hmdcamera.h +++ b/src/hmdcamera.h @@ -1,12 +1,12 @@ /* - * HMDCamera.h + * oculusviewer.h * * Created on: Jun 30, 2013 * Author: Jan Ciger */ -#ifndef _OSG_HMDCAMERA_H_ -#define _OSG_HMDCAMERA_H_ +#ifndef _OSG_OCULUSVIEWER_H_ +#define _OSG_OCULUSVIEWER_H_ #include @@ -17,13 +17,13 @@ namespace osgViewer { class NodeVisitor; } -class HMDCamera: public osg::Group { +class OculusViewer : public osg::Group { public: - HMDCamera(osgViewer::View* view, osg::ref_ptr dev); + OculusViewer(osgViewer::View* view, osg::ref_ptr dev); virtual void traverse(osg::NodeVisitor& nv); void setSceneNodeMask(osg::Node::NodeMask nodeMask) { m_sceneNodeMask = nodeMask; } protected: - ~HMDCamera(); + ~OculusViewer() {}; virtual void configure(); osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; @@ -45,4 +45,4 @@ class HMDCamera: public osg::Group { osg::Node::NodeMask m_sceneNodeMask; }; -#endif /* _OSG_HMDCAMERA_H_ */ +#endif /* _OSG_OCULUSVIEWER_H_ */ diff --git a/src/viewerexample.cpp b/src/viewerexample.cpp index 1d448d1..297f477 100644 --- a/src/viewerexample.cpp +++ b/src/viewerexample.cpp @@ -23,7 +23,7 @@ #include #include "oculusdevice.h" -#include "hmdcamera.h" +#include "oculusviewer.h" int main( int argc, char** argv ) { @@ -109,7 +109,7 @@ int main( int argc, char** argv ) osg::Node::NodeMask sceneNodeMask = loadedModel->getNodeMask() & ~0x1; loadedModel->setNodeMask(sceneNodeMask); - osg::ref_ptr hmd_camera = new HMDCamera(&viewer, oculusDevice); + osg::ref_ptr hmd_camera = new OculusViewer(&viewer, oculusDevice); hmd_camera->setSceneNodeMask(sceneNodeMask); hmd_camera->addChild(loadedModel); viewer.setSceneData(hmd_camera); From e247f7e448baad64ef891b089313c735a83fbfe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 9 Aug 2014 01:01:00 +0200 Subject: [PATCH 31/51] Renamed files HMDCamera to OculusViewer --- src/{hmdcamera.cpp => oculusviewer.cpp} | 0 src/{hmdcamera.h => oculusviewer.h} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/{hmdcamera.cpp => oculusviewer.cpp} (100%) rename src/{hmdcamera.h => oculusviewer.h} (100%) diff --git a/src/hmdcamera.cpp b/src/oculusviewer.cpp similarity index 100% rename from src/hmdcamera.cpp rename to src/oculusviewer.cpp diff --git a/src/hmdcamera.h b/src/oculusviewer.h similarity index 100% rename from src/hmdcamera.h rename to src/oculusviewer.h From 1b915e9f6e72ce349c049c80f7e1416578e42625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 14 Aug 2014 23:35:47 +0200 Subject: [PATCH 32/51] Added three separate examples: * Standard Viewer * Standard Viewer with ViewConfig * CompositeViewer Moved duplicated code into the oculus device class --- src/compositeviewerexample.cpp | 246 +++++++++++++-------------------- src/oculusdevice.cpp | 198 ++++++++++++++++++++++++++ src/oculusdevice.h | 15 +- src/oculuseventhandler.cpp | 2 +- src/oculuseventhandler.h | 6 +- src/oculusviewconfig.cpp | 106 ++------------ src/oculusviewconfig.h | 4 - src/oculusviewer.cpp | 76 +--------- src/oculusviewer.h | 4 - src/viewconfigexample.cpp | 4 +- src/viewerexample.cpp | 51 ++----- 11 files changed, 342 insertions(+), 370 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index 93363bf..cf92f3e 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -4,78 +4,36 @@ * Created on: Jul 03, 2013 * Author: Bjorn Blissing */ - #include "oculusdevice.h" - -#include -#include -#include -#include -#include -#include -#include - -#include +#include "oculuseventhandler.h" #include -#include #include + #include #include -#include - -osg::Geode* createScreenQuad( float width, float height, float scale=1.0f ) -{ - osg::Geometry* geom = osg::createTexturedQuadGeometry(osg::Vec3(), - osg::Vec3(width,0.0f,0.0f), - osg::Vec3(0.0f,height,0.0f), - 0.0f, - 0.0f, - width*scale, - height*scale); - osg::ref_ptr quad = new osg::Geode; - quad->addDrawable( geom ); - int values = osg::StateAttribute::OFF|osg::StateAttribute::PROTECTED; - quad->getOrCreateStateSet()->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), values ); - quad->getOrCreateStateSet()->setMode( GL_LIGHTING, values ); - return quad.release(); -} - -osg::Camera* createRTTCamera( osg::Camera::BufferComponent buffer, osg::Texture* tex ) -{ - osg::ref_ptr camera = new osg::Camera; - camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); - camera->setClearColor( osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f) ); - camera->setClearMask( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); - camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); - camera->setRenderOrder( osg::Camera::PRE_RENDER); - - if ( tex ) { - tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR ); - tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR ); - camera->setViewport( 0, 0, tex->getTextureWidth(), tex->getTextureHeight() ); - camera->attach( buffer, tex, 0, 0, false, 4, 4); - } - return camera.release(); -} +#include -osg::Camera* createHUDCamera( double left, double right, double bottom, double top ) +osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top) { osg::ref_ptr camera = new osg::Camera; - camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF ); - camera->setClearMask( GL_DEPTH_BUFFER_BIT ); - camera->setRenderOrder( osg::Camera::POST_RENDER); - camera->setAllowEventFocus( false ); - camera->setProjectionMatrix( osg::Matrix::ortho2D(left, right, bottom, top) ); - camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); + camera->setClearMask(GL_DEPTH_BUFFER_BIT); + camera->setRenderOrder(osg::Camera::POST_RENDER); + camera->setAllowEventFocus(false); + camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top)); + camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); camera->setViewMatrix(osg::Matrix::identity()); return camera.release(); } + int main( int argc, char** argv ) { - OculusDevice* oculusDevice = new OculusDevice; + bool useTimeWarp = false; + osg::ref_ptr oculusDevice = new OculusDevice(); // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // read the scene from the list of file specified command line arguments. @@ -87,104 +45,59 @@ int main( int argc, char** argv ) // Still no loaded model, then exit if (!loadedModel) return 0; - // Set the scaleing of the texture, using the recommend 25% from the SDK - oculusDevice->setCustomScaleFactor(1.25f); // Calculate the texture size - const int textureWidth = oculusDevice->scaleFactor() * oculusDevice->hScreenResolution()/2; - const int textureHeight = oculusDevice->scaleFactor() * oculusDevice->vScreenResolution(); + const int textureWidth = oculusDevice->hRenderTargetSize()/2; + const int textureHeight = oculusDevice->vRenderTargetSize(); // Setup textures for the RTT cameras - osg::ref_ptr leftEyeTex2D = new osg::Texture2D; - leftEyeTex2D->setTextureSize( textureWidth, textureHeight ); - leftEyeTex2D->setInternalFormat( GL_RGBA ); - osg::ref_ptr rightEyeTex2D = new osg::Texture2D; - rightEyeTex2D->setTextureSize( textureWidth, textureHeight ); - rightEyeTex2D->setInternalFormat( GL_RGBA ); + osg::ref_ptr textureLeft = new osg::Texture2D; + textureLeft->setTextureSize(textureWidth, textureHeight); + textureLeft->setInternalFormat(GL_RGBA); + osg::ref_ptr textureRight = new osg::Texture2D; + textureRight->setTextureSize(textureWidth, textureHeight); + textureRight->setInternalFormat(GL_RGBA); // Initialize RTT cameras for each eye - osg::ref_ptr leftEyeRTTCamera = createRTTCamera(osg::Camera::COLOR_BUFFER, leftEyeTex2D); + osg::ref_ptr leftEyeRTTCamera = oculusDevice->createRTTCamera(textureLeft, OculusDevice::LEFT); leftEyeRTTCamera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); leftEyeRTTCamera->addChild( loadedModel ); - osg::ref_ptr rightEyeRTTCamera = createRTTCamera(osg::Camera::COLOR_BUFFER, rightEyeTex2D); + osg::ref_ptr rightEyeRTTCamera = oculusDevice->createRTTCamera(textureRight, OculusDevice::RIGHT); rightEyeRTTCamera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); rightEyeRTTCamera->addChild( loadedModel ); // Create HUD cameras for each eye - osg::ref_ptr leftEyeHUDCamera = createHUDCamera(0.0, 1.0, 0.0, 1.0); - osg::ref_ptr rightEyeHUDCamera = createHUDCamera(0.0, 1.0, 0.0, 1.0); - // Create quads on each camera - osg::ref_ptr leftQuad = createScreenQuad(1.0f, 1.0f); - leftEyeHUDCamera->addChild( leftQuad ); - osg::ref_ptr rightQuad = createScreenQuad(1.0f, 1.0f); - rightEyeHUDCamera->addChild( rightQuad ); + osg::ref_ptr leftCameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); + osg::ref_ptr rightCameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); + // Set up shaders from the Oculus SDK documentation osg::ref_ptr program = new osg::Program; osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp.vert")); - osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); - // Fragment shader with or without correction for chromatic aberration - bool useChromaticAberrationCorrection = true; - if (useChromaticAberrationCorrection) { - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithChromeAb.frag")); - } else { - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warpWithoutChromeAb.frag")); + if (useTimeWarp) { + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); + } + else { + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); } - program->addShader( vertexShader ); - program->addShader( fragmentShader ); - // Configure state sets for both eyes - osg::StateSet* leftEyeStateSet = leftQuad->getOrCreateStateSet(); - leftEyeStateSet->setTextureAttributeAndModes(0, leftEyeTex2D, osg::StateAttribute::ON); - leftEyeStateSet->setAttributeAndModes( program, osg::StateAttribute::ON ); - leftEyeStateSet->addUniform( new osg::Uniform("WarpTexture", 0) ); - leftEyeStateSet->addUniform( new osg::Uniform("LensCenter", oculusDevice->lensCenter(OculusDevice::LEFT_EYE))); - leftEyeStateSet->addUniform( new osg::Uniform("ScreenCenter", oculusDevice->screenCenter())); - leftEyeStateSet->addUniform( new osg::Uniform("Scale", oculusDevice->scale())); - leftEyeStateSet->addUniform( new osg::Uniform("ScaleIn", oculusDevice->scaleIn())); - leftEyeStateSet->addUniform( new osg::Uniform("HmdWarpParam", oculusDevice->warpParameters())); - leftEyeStateSet->addUniform( new osg::Uniform("ChromAbParam", oculusDevice->chromAbParameters())); - osg::StateSet* rightEyeStateSet = rightQuad->getOrCreateStateSet(); - rightEyeStateSet->setTextureAttributeAndModes(0, rightEyeTex2D, osg::StateAttribute::ON); - rightEyeStateSet->setAttributeAndModes( program, osg::StateAttribute::ON ); - rightEyeStateSet->addUniform( new osg::Uniform("WarpTexture", 0) ); - rightEyeStateSet->addUniform( new osg::Uniform("LensCenter", oculusDevice->lensCenter(OculusDevice::RIGHT_EYE))); - rightEyeStateSet->addUniform( new osg::Uniform("ScreenCenter", oculusDevice->screenCenter())); - rightEyeStateSet->addUniform( new osg::Uniform("Scale", oculusDevice->scale())); - rightEyeStateSet->addUniform( new osg::Uniform("ScaleIn", oculusDevice->scaleIn())); - rightEyeStateSet->addUniform( new osg::Uniform("HmdWarpParam", oculusDevice->warpParameters())); - rightEyeStateSet->addUniform( new osg::Uniform("ChromAbParam", oculusDevice->chromAbParameters())); - // Add cameras to groups - osg::ref_ptr leftRoot = new osg::Group; - osg::ref_ptr rightRoot = new osg::Group; - leftRoot->addChild(leftEyeRTTCamera); - leftRoot->addChild(leftEyeHUDCamera); - rightRoot->addChild(rightEyeRTTCamera); - rightRoot->addChild(rightEyeHUDCamera); - osgViewer::CompositeViewer viewer(arguments); - osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); + fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); + program->addShader(vertexShader); + program->addShader(fragmentShader); - if (!wsi) { - osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."< leftDistortionMesh = oculusDevice->distortionMeshComposite(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); + leftCameraWarp->addChild(leftDistortionMesh); + osg::ref_ptr rightDistortionMesh = oculusDevice->distortionMeshComposite(OculusDevice::Eye::RIGHT, program, 0, 0, textureWidth, textureHeight); + rightCameraWarp->addChild(rightDistortionMesh); - unsigned int width, height; - wsi->getScreenResolution(osg::GraphicsContext::ScreenIdentifier(0), width, height); - osg::ref_ptr traits = new osg::GraphicsContext::Traits; - traits->windowDecoration = false; - traits->x = 0; - traits->y = 0; - traits->width = oculusDevice->hScreenResolution(); - traits->height = oculusDevice->vScreenResolution(); - traits->doubleBuffer = true; - traits->sharedContext = 0; - traits->sampleBuffers = true; - traits->samples = 4; - traits->vsync = true; - osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits); + // Add pre draw camera to handle time warp + leftCameraWarp->setPreDrawCallback(new WarpCameraPreDrawCallback(oculusDevice)); + rightCameraWarp->setPreDrawCallback(new WarpCameraPreDrawCallback(oculusDevice)); - if (gc.valid()) { - gc->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); - gc->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } + // Attach shaders to each distortion mesh + osg::ref_ptr leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); + osg::ref_ptr rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); + + oculusDevice->applyShaderParameters(leftEyeStateSet, program, textureLeft, OculusDevice::Eye::LEFT); + oculusDevice->applyShaderParameters(rightEyeStateSet, program, textureRight, OculusDevice::Eye::RIGHT); // Create Trackball manipulator osg::ref_ptr cameraManipulator = new osgGA::TrackballManipulator; @@ -195,20 +108,43 @@ int main( int argc, char** argv ) cameraManipulator->setHomePosition(osg::Vec3(0, bs.radius()*1.5, 0), osg::Vec3(0, 0, 0), osg::Vec3(0, 0, 1)); } + // Add cameras to groups + osg::ref_ptr leftRoot = new osg::Group; + osg::ref_ptr rightRoot = new osg::Group; + leftRoot->addChild(leftEyeRTTCamera); + leftRoot->addChild(leftCameraWarp); + rightRoot->addChild(rightEyeRTTCamera); + rightRoot->addChild(rightCameraWarp); + + osg::ref_ptr traits = oculusDevice->graphicsContextTraits(); + osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits); + + // Attach a callback to detect swap + osg::ref_ptr swapCallback = new OculusSwapCallback(oculusDevice); + gc->setSwapCallback(swapCallback); + + // Create a composite viewer + osgViewer::CompositeViewer viewer(arguments); + // Create views and attach camera groups to them osg::ref_ptr leftView = new osgViewer::View; leftView->setName("LeftEyeView"); viewer.addView(leftView); - leftView->setSceneData( leftRoot ); + leftView->setSceneData(leftRoot); leftView->getCamera()->setName("LeftEyeCamera"); + leftView->getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); leftView->getCamera()->setViewport(new osg::Viewport(0, 0, oculusDevice->hScreenResolution() / 2, oculusDevice->vScreenResolution())); leftView->getCamera()->setGraphicsContext(gc); - leftView->addEventHandler( new osgViewer::StatsHandler ); + // Add statistics view to only one view + leftView->addEventHandler(new osgViewer::StatsHandler); + // Add Oculus Keyboard Handler to only one view + leftView->addEventHandler(new OculusEventHandler(oculusDevice)); leftView->setCameraManipulator(cameraManipulator); osg::ref_ptr rightView = new osgViewer::View; rightView->setName("RightEyeView"); viewer.addView(rightView); - rightView->setSceneData( rightRoot ); + rightView->setSceneData(rightRoot); + rightView->getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); rightView->getCamera()->setName("RightEyeCamera"); rightView->getCamera()->setViewport(new osg::Viewport(oculusDevice->hScreenResolution() / 2, 0, oculusDevice->hScreenResolution() / 2, oculusDevice->vScreenResolution())); rightView->getCamera()->setGraphicsContext(gc); @@ -219,24 +155,34 @@ int main( int argc, char** argv ) viewer.realize(); } - // Create matrix for camera position and orientation (from HMD) + // Create matrix for camera position and orientation & position (from HMD) osg::Matrix cameraManipulatorViewMatrix; - osg::Matrix orientationMatrix; + osg::Matrix hmdMatrix; // Get the view matrix for each eye for later use - osg::Matrix leftEyeViewMatrix = oculusDevice->viewMatrix(OculusDevice::LEFT_EYE); - osg::Matrix rightEyeViewMatrix = oculusDevice->viewMatrix(OculusDevice::RIGHT_EYE); + osg::Matrix leftEyeViewMatrix = oculusDevice->viewMatrixLeft(); + osg::Matrix rightEyeViewMatrix = oculusDevice->viewMatrixRight(); // Set the projection matrix for each eye - leftEyeRTTCamera->setProjectionMatrix(oculusDevice->projectionMatrix(OculusDevice::LEFT_EYE)); - rightEyeRTTCamera->setProjectionMatrix(oculusDevice->projectionMatrix(OculusDevice::RIGHT_EYE)); + leftEyeRTTCamera->setProjectionMatrix(oculusDevice->projectionMatrixLeft()); + rightEyeRTTCamera->setProjectionMatrix(oculusDevice->projectionMatrixRight()); // Start Viewer while (!viewer.done()) { - // Get orientation from oculus sensor - orientationMatrix.makeRotate(oculusDevice->getOrientation()); + // Update the pose + oculusDevice->updatePose(swapCallback->frameIndex()); + + osg::Vec3 position = oculusDevice->position(); + osg::Quat orientation = oculusDevice->orientation(); + + hmdMatrix.makeRotate(orientation); + hmdMatrix.preMultTranslate(position); + + leftEyeViewMatrix = oculusDevice->viewMatrixLeft(); + rightEyeViewMatrix = oculusDevice->viewMatrixRight(); // Get camera matrix from manipulator cameraManipulatorViewMatrix = cameraManipulator->getInverseMatrix(); - leftEyeRTTCamera->setViewMatrix(leftEyeViewMatrix*cameraManipulatorViewMatrix*orientationMatrix); - rightEyeRTTCamera->setViewMatrix(rightEyeViewMatrix*cameraManipulatorViewMatrix*orientationMatrix); + leftEyeRTTCamera->setViewMatrix(leftEyeViewMatrix*cameraManipulatorViewMatrix*hmdMatrix); + rightEyeRTTCamera->setViewMatrix(rightEyeViewMatrix*cameraManipulatorViewMatrix*hmdMatrix); + viewer.frame(); } diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 70fc79e..28f5de8 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -286,6 +286,88 @@ osg::Geode* OculusDevice::distortionMesh(Eye eye, osg::Program* program, int x, return geode.release(); } +osg::Geode* OculusDevice::distortionMeshComposite(Eye eye, osg::Program* program, int x, int y, int w, int h) { + osg::ref_ptr geode = new osg::Geode; + // Allocate & generate distortion mesh vertices. + ovrDistortionMesh meshData; + ovrHmd_CreateDistortionMesh(m_hmdDevice, m_eyeRenderDesc[eye].Eye, m_eyeRenderDesc[eye].Fov, ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp, &meshData); + + // Now parse the vertex data and create a render ready vertex buffer from it + ovrDistortionVertex* ov = meshData.pVertexData; + osg::Vec2Array* positionArray = new osg::Vec2Array; + osg::Vec4Array* colorArray = new osg::Vec4Array; + osg::Vec2Array* textureRArray = new osg::Vec2Array; + osg::Vec2Array* textureGArray = new osg::Vec2Array; + osg::Vec2Array* textureBArray = new osg::Vec2Array; + + for (unsigned vertNum = 0; vertNum < meshData.VertexCount; ++vertNum) + { + if (eye == LEFT) { + positionArray->push_back(osg::Vec2f(2 * ov[vertNum].ScreenPosNDC.x+1.0, ov[vertNum].ScreenPosNDC.y)); + } else if (eye == RIGHT) { + positionArray->push_back(osg::Vec2f(2 * ov[vertNum].ScreenPosNDC.x-1.0, ov[vertNum].ScreenPosNDC.y)); + } + colorArray->push_back(osg::Vec4f(ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].TimeWarpFactor)); + textureRArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesR.x, ov[vertNum].TanEyeAnglesR.y)); + textureGArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesG.x, ov[vertNum].TanEyeAnglesG.y)); + textureBArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesB.x, ov[vertNum].TanEyeAnglesB.y)); + } + + // Get triangle indicies + osg::UShortArray* indexArray = new osg::UShortArray; + unsigned short* index = meshData.pIndexData; + for (unsigned indexNum = 0; indexNum < meshData.IndexCount; ++indexNum) { + indexArray->push_back(index[indexNum]); + } + + // Deallocate the mesh data + ovrHmd_DestroyDistortionMesh(&meshData); + + osg::ref_ptr geometry = new osg::Geometry; + osg::ref_ptr drawElement = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, indexArray->size(), (GLushort*)indexArray->getDataPointer()); + geometry->addPrimitiveSet(drawElement); + + GLuint positionLoc = 0; + GLuint colorLoc = 1; + GLuint texCoord0Loc = 2; + GLuint texCoord1Loc = 3; + GLuint texCoord2Loc = 4; + + program->addBindAttribLocation("Position", positionLoc); + geometry->setVertexAttribArray(positionLoc, positionArray); + geometry->setVertexAttribBinding(positionLoc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("Color", colorLoc); + geometry->setVertexAttribArray(colorLoc, colorArray); + geometry->setVertexAttribBinding(colorLoc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("TexCoord0", texCoord0Loc); + geometry->setVertexAttribArray(texCoord0Loc, textureRArray); + geometry->setVertexAttribBinding(texCoord0Loc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("TexCoord1", texCoord1Loc); + geometry->setVertexAttribArray(texCoord1Loc, textureGArray); + geometry->setVertexAttribBinding(texCoord1Loc, osg::Geometry::BIND_PER_VERTEX); + + program->addBindAttribLocation("TexCoord2", texCoord2Loc); + geometry->setVertexAttribArray(texCoord2Loc, textureBArray); + geometry->setVertexAttribBinding(texCoord2Loc, osg::Geometry::BIND_PER_VERTEX); + + + // Compute UV scale and offset + ovrRecti eyeRenderViewport; + eyeRenderViewport.Pos.x = x; + eyeRenderViewport.Pos.y = y; + eyeRenderViewport.Size.w = w; + eyeRenderViewport.Size.h = h; + ovrSizei renderTargetSize; + renderTargetSize.w = m_renderTargetSize.w / 2; + renderTargetSize.h = m_renderTargetSize.h; + ovrHmd_GetRenderScaleAndOffset(m_eyeRenderDesc[eye].Fov, renderTargetSize, eyeRenderViewport, m_UVScaleOffset[eye]); + geode->addDrawable(geometry); + return geode.release(); +} + osg::Vec2f OculusDevice::eyeToSourceUVScale(Eye eye) const { osg::Vec2f uvScale(m_UVScaleOffset[eye][0].x, m_UVScaleOffset[eye][0].y); return uvScale; @@ -343,6 +425,122 @@ void OculusDevice::waitTillTime() { } } +osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const +{ + osg::ref_ptr camera = new osg::Camera; + camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); + camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + camera->setDrawBuffer(GL_FRONT); + camera->setReadBuffer(GL_FRONT); + camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); + camera->setRenderOrder(osg::Camera::PRE_RENDER, renderOrder(eye)); + camera->setAllowEventFocus(false); + camera->setGraphicsContext(gc); + camera->setReferenceFrame(osg::Camera::RELATIVE_RF); + + if (texture) { + texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); + texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); + camera->setViewport(0, 0, texture->getTextureWidth(), texture->getTextureHeight()); + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0, false, 4, 4); + } + + return camera.release(); +} + +osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye) const +{ + osg::ref_ptr camera = new osg::Camera; + camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); + camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + camera->setDrawBuffer(GL_FRONT); + camera->setReadBuffer(GL_FRONT); + camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); + camera->setRenderOrder(osg::Camera::PRE_RENDER, renderOrder(eye)); + camera->setAllowEventFocus(false); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + + if (texture) { + texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); + texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); + camera->setViewport(0, 0, texture->getTextureWidth(), texture->getTextureHeight()); + camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0, false, 4, 4); + } + + return camera.release(); +} + + +osg::Camera* OculusDevice::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const +{ + osg::ref_ptr camera = new osg::Camera; + camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + camera->setRenderOrder(osg::Camera::POST_RENDER); + camera->setAllowEventFocus(false); + camera->setGraphicsContext(gc); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top)); + camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + return camera.release(); +} + +void OculusDevice::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { + stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); + stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); + stateSet->addUniform(new osg::Uniform("Texture", 0)); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", eyeToSourceUVScale(eye))); + stateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", eyeToSourceUVOffset(eye))); + + // Uniforms needed for time warp + if (m_useTimeWarp) { + osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", this->eyeRotationStart(eye)); + osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", this->eyeRotationEnd(eye)); + stateSet->addUniform(eyeRotationStart); + stateSet->addUniform(eyeRotationEnd); + eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, this, eye)); + eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, this, eye)); + } +} + +osg::GraphicsContext::Traits* OculusDevice::graphicsContextTraits() const { + // Create screen with match the Oculus Rift resolution + osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); + + if (!wsi) { + osg::notify(osg::NOTICE) << "Error, no WindowSystemInterface available, cannot create windows." << std::endl; + return 0; + } + + // Get the screen identifiers set in environment variable DISPLAY + osg::GraphicsContext::ScreenIdentifier si; + si.readDISPLAY(); + + // If displayNum has not been set, reset it to 0. + if (si.displayNum < 0) si.displayNum = 0; + + // If screenNum has not been set, reset it to 0. + if (si.screenNum < 0) si.screenNum = 0; + + unsigned int width, height; + wsi->getScreenResolution(si, width, height); + + osg::ref_ptr traits = new osg::GraphicsContext::Traits; + traits->hostName = si.hostName; + traits->screenNum = si.screenNum; + traits->displayNum = si.displayNum; + traits->windowDecoration = false; + traits->x = windowPos().x(); + traits->y = windowPos().y(); + traits->width = hScreenResolution(); + traits->height = vScreenResolution(); + traits->doubleBuffer = true; + traits->sharedContext = 0; + traits->vsync = true; // VSync should always be enabled for Oculus Rift applications + + return traits.release(); +} + void WarpCameraPreDrawCallback::operator()(osg::RenderInfo&) const { // Wait till time - warp point to reduce latency. diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 8187b4d..8f265f2 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -10,10 +10,12 @@ // Include the OculusVR SDK #include "OVR.h" + #include #include #include #include +#include class OculusDevice : public osg::Referenced { @@ -57,6 +59,7 @@ class OculusDevice : public osg::Referenced { int renderOrder(Eye eye) const; osg::Geode* distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h); + osg::Geode* distortionMeshComposite(Eye eye, osg::Program* program, int x, int y, int w, int h); osg::Vec2f eyeToSourceUVScale(Eye eye) const; osg::Vec2f eyeToSourceUVOffset(Eye eye) const; osg::Matrixf eyeRotationStart(Eye eye) const; @@ -65,6 +68,13 @@ class OculusDevice : public osg::Referenced { void beginFrameTiming(unsigned int frameIndex=0); void endFrameTiming() const; void waitTillTime(); + + osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; + osg::Camera* createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye) const; + osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; + void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; + osg::GraphicsContext::Traits* graphicsContextTraits() const; + protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected float aspectRatio(Eye eye) const; @@ -86,6 +96,7 @@ class OculusDevice : public osg::Referenced { osg::Vec3 m_position; osg::Quat m_orientation; + bool m_useTimeWarp; float m_nearClip; float m_farClip; private: @@ -119,11 +130,11 @@ class EyeRotationCallback : public osg::Uniform::Callback START, END }; - EyeRotationCallback(Mode mode, osg::observer_ptr device, OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} + EyeRotationCallback(Mode mode, const OculusDevice* device, OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv); protected: Mode m_mode; - osg::observer_ptr m_device; + const OculusDevice* m_device; OculusDevice::Eye m_eye; }; diff --git a/src/oculuseventhandler.cpp b/src/oculuseventhandler.cpp index d7a3154..2e10893 100644 --- a/src/oculuseventhandler.cpp +++ b/src/oculuseventhandler.cpp @@ -16,7 +16,7 @@ bool OculusEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActio switch(ea.getKey()) { case osgGA::GUIEventAdapter::KEY_R: - m_oculusViewConfig->resetSensorOrientation(); + m_oculusDevice->resetSensorOrientation(); return osgGA::GUIEventHandler::handle(ea, ad); break; default: diff --git a/src/oculuseventhandler.h b/src/oculuseventhandler.h index ce6c6fa..cf22435 100644 --- a/src/oculuseventhandler.h +++ b/src/oculuseventhandler.h @@ -10,15 +10,15 @@ #include -#include "oculusviewconfig.h" +#include "oculusdevice.h" class OculusEventHandler : public osgGA::GUIEventHandler { public: - OculusEventHandler(osg::ref_ptr viewConfig) : m_oculusViewConfig(viewConfig) {} + OculusEventHandler(osg::ref_ptr device) : m_oculusDevice(device) {} virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&); protected: - osg::ref_ptr m_oculusViewConfig; + osg::ref_ptr m_oculusDevice; }; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 1aef6ae..fd842b5 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -4,6 +4,8 @@ * Created on: Sept 26, 2013 * Author: Bjorn Blissing & Jan Ciger */ +#include "oculusviewconfig.h" + #include #include #include @@ -14,104 +16,16 @@ #include -#include "oculusviewconfig.h" #include "oculusdevice.h" - -osg::Camera* OculusViewConfig::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const -{ - osg::ref_ptr camera = new osg::Camera; - camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); - camera->setClearMask( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ); - camera->setDrawBuffer(GL_FRONT); - camera->setReadBuffer(GL_FRONT); - camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); - camera->setRenderOrder(osg::Camera::PRE_RENDER, (int) m_device->renderOrder(eye)); - camera->setAllowEventFocus(false); - camera->setGraphicsContext(gc); - camera->setReferenceFrame(osg::Camera::RELATIVE_RF); - - if ( texture ) { - texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); - texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); - camera->setViewport(0, 0, texture->getTextureWidth(), texture->getTextureHeight()); - camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0, false, 4, 4); - } - - return camera.release(); -} - -osg::Camera* OculusViewConfig::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const -{ - osg::ref_ptr camera = new osg::Camera; - camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); - camera->setClearMask( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - camera->setRenderOrder(osg::Camera::POST_RENDER); - camera->setAllowEventFocus(false); - camera->setGraphicsContext(gc); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top)); - camera->getOrCreateStateSet()->setMode( GL_LIGHTING, osg::StateAttribute::OFF ); - return camera.release(); -} - -void OculusViewConfig::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { - stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); - stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); - stateSet->addUniform(new osg::Uniform("Texture", 0)); - stateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(eye))); - stateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(eye))); - - // Uniforms needed for time warp - if (m_useTimeWarp) { - osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(eye)); - osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(eye)); - stateSet->addUniform(eyeRotationStart); - stateSet->addUniform(eyeRotationEnd); - eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, eye)); - eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, eye)); - } -} +#include "oculuseventhandler.h" void OculusViewConfig::configure(osgViewer::View& view) const { m_device->setNearClip(m_nearClip); m_device->setFarClip(m_farClip); - // Create screen with match the Oculus Rift resolution - osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); - - if (!wsi) { - osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(si, width, height); - - osg::ref_ptr traits = new osg::GraphicsContext::Traits; - traits->hostName = si.hostName; - traits->screenNum = si.screenNum; - traits->displayNum = si.displayNum; - traits->windowDecoration = false; - traits->x = m_device->windowPos().x(); - traits->y = m_device->windowPos().y(); - traits->width = m_device->hScreenResolution(); - traits->height = m_device->vScreenResolution(); - traits->doubleBuffer = true; - traits->sharedContext = 0; - traits->vsync = true; // VSync should always be enabled for Oculus Rift applications - // Create a graphic context based on our desired traits + osg::ref_ptr traits = m_device->graphicsContextTraits(); osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits); if (!gc) { osg::notify(osg::NOTICE) << "Error, GraphicsWindow has not been created successfully" << std::endl; @@ -143,15 +57,15 @@ void OculusViewConfig::configure(osgViewer::View& view) const textureRight->setTextureSize( textureWidth, textureHeight ); textureRight->setInternalFormat( GL_RGBA ); // Create RTT cameras and attach textures - osg::ref_ptr cameraRTTLeft = createRTTCamera(textureLeft, gc, OculusDevice::LEFT); - osg::ref_ptr cameraRTTRight = createRTTCamera(textureRight, gc, OculusDevice::RIGHT); + osg::ref_ptr cameraRTTLeft = m_device->createRTTCamera(textureLeft, gc, OculusDevice::LEFT); + osg::ref_ptr cameraRTTRight = m_device->createRTTCamera(textureRight, gc, OculusDevice::RIGHT); cameraRTTLeft->setName("LeftRTT"); cameraRTTRight->setName("RightRTT"); cameraRTTLeft->setCullMask(m_sceneNodeMask); cameraRTTRight->setCullMask(m_sceneNodeMask); // Create warp ortho camera - osg::ref_ptr cameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); + osg::ref_ptr cameraWarp = m_device->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); cameraWarp->setName("WarpOrtho"); cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); @@ -184,8 +98,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const osg::ref_ptr leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); osg::ref_ptr rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); - applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT); - applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT); + m_device->applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT); + m_device->applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT); // Add RTT cameras as slaves, specifying offsets for the projection view.addSlave(cameraRTTLeft, @@ -206,6 +120,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const camera->setDataVariance(osg::Object::DYNAMIC); camera->setUpdateCallback(new OculusViewConfigOrientationCallback(cameraRTTLeft, cameraRTTRight, m_device, swapCallback)); } + // Add Oculus keyboard handler + view.addEventHandler(new OculusEventHandler(m_device)); } void OculusViewConfigOrientationCallback::operator() (osg::Node* node, osg::NodeVisitor* nv) diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index a2fb96a..cd2104e 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -38,10 +38,6 @@ class OculusViewConfig : public osgViewer::ViewConfig { protected: ~OculusViewConfig() {}; - osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; - osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; - void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; - bool m_configured; bool m_useOrientations; bool m_useChromaticAberrationCorrection; diff --git a/src/oculusviewer.cpp b/src/oculusviewer.cpp index 580cf37..5e87786 100644 --- a/src/oculusviewer.cpp +++ b/src/oculusviewer.cpp @@ -5,20 +5,13 @@ * Author: Jan Ciger */ -#include -#include -#include -#include +#include "oculusviewer.h" #include #include #include -#include "oculusviewer.h" -#include "oculusdevice.h" - - OculusViewer::OculusViewer(osgViewer::View* view, osg::ref_ptr dev) : osg::Group(), m_configured(false), m_useChromaticAberrationCorrection(false), @@ -56,61 +49,6 @@ void OculusViewer::traverse(osg::NodeVisitor& nv) osg::Group::traverse(nv); } -osg::Camera* OculusViewer::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const -{ - osg::ref_ptr camera = new osg::Camera; - camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); - camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - camera->setDrawBuffer(GL_FRONT); - camera->setReadBuffer(GL_FRONT); - camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); - camera->setRenderOrder(osg::Camera::PRE_RENDER, (int)m_device->renderOrder(eye)); - camera->setAllowEventFocus(false); - camera->setGraphicsContext(gc); - camera->setReferenceFrame(osg::Camera::RELATIVE_RF); - - if (texture) { - texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); - texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); - camera->setViewport(0, 0, texture->getTextureWidth(), texture->getTextureHeight()); - camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0, false, 4, 4); - } - - return camera.release(); -} - -osg::Camera* OculusViewer::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const -{ - osg::ref_ptr camera = new osg::Camera; - camera->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); - camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - camera->setRenderOrder(osg::Camera::POST_RENDER); - camera->setAllowEventFocus(false); - camera->setGraphicsContext(gc); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top)); - camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - return camera.release(); -} - -void OculusViewer::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { - stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); - stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); - stateSet->addUniform(new osg::Uniform("Texture", 0)); - stateSet->addUniform(new osg::Uniform("EyeToSourceUVScale", m_device->eyeToSourceUVScale(eye))); - stateSet->addUniform(new osg::Uniform("EyeToSourceUVOffset", m_device->eyeToSourceUVOffset(eye))); - - // Uniforms needed for time warp - if (m_useTimeWarp) { - osg::ref_ptr eyeRotationStart = new osg::Uniform("EyeRotationStart", m_device->eyeRotationStart(eye)); - osg::ref_ptr eyeRotationEnd = new osg::Uniform("EyeRotationEnd", m_device->eyeRotationEnd(eye)); - stateSet->addUniform(eyeRotationStart); - stateSet->addUniform(eyeRotationEnd); - eyeRotationStart->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::START, m_device, eye)); - eyeRotationEnd->setUpdateCallback(new EyeRotationCallback(EyeRotationCallback::END, m_device, eye)); - } -} - void OculusViewer::configure() { m_device->setNearClip(m_nearClip); @@ -140,15 +78,15 @@ void OculusViewer::configure() textureRight->setTextureSize(textureWidth, textureHeight); textureRight->setInternalFormat(GL_RGBA); // Create RTT cameras and attach textures - m_cameraRTTLeft = createRTTCamera(textureLeft, gc, OculusDevice::Eye::LEFT); - m_cameraRTTRight = createRTTCamera(textureRight, gc, OculusDevice::Eye::RIGHT); + m_cameraRTTLeft = m_device->createRTTCamera(textureLeft, gc, OculusDevice::Eye::LEFT); + m_cameraRTTRight = m_device->createRTTCamera(textureRight, gc, OculusDevice::Eye::RIGHT); m_cameraRTTLeft->setName("LeftRTT"); m_cameraRTTRight->setName("RightRTT"); m_cameraRTTLeft->setCullMask(m_sceneNodeMask); m_cameraRTTRight->setCullMask(m_sceneNodeMask); // Create warp ortho camera - osg::ref_ptr cameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); + osg::ref_ptr cameraWarp = m_device->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); cameraWarp->setName("WarpOrtho"); cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); @@ -171,7 +109,7 @@ void OculusViewer::configure() osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(leftDistortionMesh); - osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::RIGHT, program, textureWidth, 0, textureWidth, textureHeight); + osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::RIGHT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(rightDistortionMesh); // Add pre draw camera to handle time warp @@ -181,8 +119,8 @@ void OculusViewer::configure() osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); - applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::Eye::LEFT); - applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::Eye::RIGHT); + m_device->applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::Eye::LEFT); + m_device->applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::Eye::RIGHT); // Add RTT cameras as slaves, specifying offsets for the projection m_view->addSlave(m_cameraRTTLeft.get(), diff --git a/src/oculusviewer.h b/src/oculusviewer.h index 41d9a23..9138c33 100644 --- a/src/oculusviewer.h +++ b/src/oculusviewer.h @@ -26,10 +26,6 @@ class OculusViewer : public osg::Group { ~OculusViewer() {}; virtual void configure(); - osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; - osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; - void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; - bool m_configured; bool m_useChromaticAberrationCorrection; bool m_useTimeWarp; diff --git a/src/viewconfigexample.cpp b/src/viewconfigexample.cpp index ca0f79a..25917c2 100644 --- a/src/viewconfigexample.cpp +++ b/src/viewconfigexample.cpp @@ -1,5 +1,5 @@ /* - * main.cpp + * viewconfigexample.cpp * * Created on: Jul 03, 2013 * Author: Bjorn Blissing @@ -38,8 +38,6 @@ int main( int argc, char** argv ) osgViewer::Viewer viewer(arguments); // Add statistics handler viewer.addEventHandler(new osgViewer::StatsHandler); - // Add Oculus keyboard handler - viewer.addEventHandler(new OculusEventHandler(oculusViewConfig)); // Apply view config viewer.apply(oculusViewConfig); // Add loaded model to viewer diff --git a/src/viewerexample.cpp b/src/viewerexample.cpp index 297f477..660a449 100644 --- a/src/viewerexample.cpp +++ b/src/viewerexample.cpp @@ -1,5 +1,5 @@ /* - * main.cpp + * viewerexample.cpp * * Created on: Jul 03, 2013 * Author: Bjorn Blissing @@ -22,8 +22,10 @@ #include #include -#include "oculusdevice.h" #include "oculusviewer.h" +#include "oculusdevice.h" +#include "oculuseventhandler.h" + int main( int argc, char** argv ) { @@ -50,39 +52,8 @@ int main( int argc, char** argv ) // Open the HMD osg::ref_ptr oculusDevice = new OculusDevice(); - // Create screen with match the Oculus Rift resolution - osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface(); - - if (!wsi) { - osg::notify(osg::NOTICE)<<"Error, no WindowSystemInterface available, cannot create windows."<getScreenResolution(si, width, height); - - osg::ref_ptr traits = new osg::GraphicsContext::Traits; - traits->hostName = si.hostName; - traits->screenNum = si.screenNum; - traits->displayNum = si.displayNum; - traits->windowDecoration = false; - traits->x = oculusDevice->windowPos().x(); - traits->y = oculusDevice->windowPos().y(); - traits->width = oculusDevice->hScreenResolution(); - traits->height = oculusDevice->vScreenResolution(); - traits->doubleBuffer = true; - traits->sharedContext = 0; - traits->vsync = true; // VSync should always be enabled for Oculus Rift applications + // Get the suggested context traits + osg::ref_ptr traits = oculusDevice->graphicsContextTraits(); // Create a graphic context based on our desired traits osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits); @@ -109,12 +80,14 @@ int main( int argc, char** argv ) osg::Node::NodeMask sceneNodeMask = loadedModel->getNodeMask() & ~0x1; loadedModel->setNodeMask(sceneNodeMask); - osg::ref_ptr hmd_camera = new OculusViewer(&viewer, oculusDevice); - hmd_camera->setSceneNodeMask(sceneNodeMask); - hmd_camera->addChild(loadedModel); - viewer.setSceneData(hmd_camera); + osg::ref_ptr oculusViewer = new OculusViewer(&viewer, oculusDevice); + oculusViewer->setSceneNodeMask(sceneNodeMask); + oculusViewer->addChild(loadedModel); + viewer.setSceneData(oculusViewer); // Add statistics handler viewer.addEventHandler(new osgViewer::StatsHandler); + // Add Oculus Keyboard Handler to only one view + viewer.addEventHandler(new OculusEventHandler(oculusDevice)); // Start Viewer viewer.run(); return 0; From fad4c4e6f3ee412b7338e43641b45c409b7833eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Thu, 14 Aug 2014 23:38:21 +0200 Subject: [PATCH 33/51] Updated the readme. --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d71c5c5..8128a59 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,7 @@ OsgOculusViewer An OsgViewer with support for the Oculus Rift -**NOTE! This is work in progress and is NOT intended for production.** -**Currently only supporting OpenSceneGraph 3.2.0 or later.** - -Last tested against Oculus SDK 0.4.0 Beta +Last tested against Oculus SDK 0.4.1 Beta To be able to use the osgViewer::ViewConfig version you will need to use OpenSceneGraph 3.2.0 or later. @@ -24,3 +21,5 @@ Björn Blissing Jan Ciger Nico Kruithof + +Daniel Sjölie From fd1a10a81bcf64891b3887fc4964306bd7a14d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Fri, 15 Aug 2014 00:23:13 +0200 Subject: [PATCH 34/51] Updated license year. --- license.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/license.txt b/license.txt index a183c9d..d46e7b5 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -Copyright (c) 2013, Swedish National Road and Transport Research Institute +Copyright (c) 2013-2014, Swedish National Road and Transport Research Institute All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: From d6d6a25000bee4b7f6a4227b855eaf8d7111723e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 00:44:08 +0200 Subject: [PATCH 35/51] Removed a lot of code duplication and redundant #includes. --- src/compositeviewerexample.cpp | 10 +-- src/oculusdevice.cpp | 150 ++++++--------------------------- src/oculusdevice.h | 21 ++--- src/oculuseventhandler.cpp | 1 + src/oculuseventhandler.h | 3 +- src/oculusviewconfig.cpp | 24 ++---- src/oculusviewconfig.h | 22 +---- src/oculusviewer.cpp | 24 +----- src/oculusviewer.h | 18 ++-- src/viewconfigexample.cpp | 2 - src/viewerexample.cpp | 17 +--- 11 files changed, 65 insertions(+), 227 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index cf92f3e..de7bbda 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -8,7 +8,6 @@ #include "oculuseventhandler.h" #include -#include #include #include @@ -32,8 +31,7 @@ osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, dou int main( int argc, char** argv ) { - bool useTimeWarp = false; - osg::ref_ptr oculusDevice = new OculusDevice(); + osg::ref_ptr oculusDevice = new OculusDevice(0.01f, 10000.0, true); // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // read the scene from the list of file specified command line arguments. @@ -70,7 +68,7 @@ int main( int argc, char** argv ) osg::ref_ptr program = new osg::Program; osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - if (useTimeWarp) { + if (oculusDevice->useTimewarp()) { vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); } else { @@ -83,9 +81,9 @@ int main( int argc, char** argv ) program->addShader(fragmentShader); // Create distortionMesh for each camera - osg::ref_ptr leftDistortionMesh = oculusDevice->distortionMeshComposite(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); + osg::ref_ptr leftDistortionMesh = oculusDevice->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight, true); leftCameraWarp->addChild(leftDistortionMesh); - osg::ref_ptr rightDistortionMesh = oculusDevice->distortionMeshComposite(OculusDevice::Eye::RIGHT, program, 0, 0, textureWidth, textureHeight); + osg::ref_ptr rightDistortionMesh = oculusDevice->distortionMesh(OculusDevice::Eye::RIGHT, program, 0, 0, textureWidth, textureHeight, true); rightCameraWarp->addChild(rightDistortionMesh); // Add pre draw camera to handle time warp diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 28f5de8..f81969f 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -10,8 +10,9 @@ #include -OculusDevice::OculusDevice() : m_hmdDevice(0), - m_nearClip(0.01f), m_farClip(10000.0f), +OculusDevice::OculusDevice(float nearClip, float farClip, bool useTimewarp) : m_hmdDevice(0), + m_nearClip(nearClip), m_farClip(farClip), + m_useTimeWarp(useTimewarp), m_position(osg::Vec3(0.0f, 0.0f, 0.0f)), m_orientation(osg::Quat(0.0f, 0.0f, 0.0f, 1.0f)) { @@ -94,22 +95,12 @@ OculusDevice::~OculusDevice() unsigned int OculusDevice::hScreenResolution() const { - if (m_hmdDevice) { - return m_hmdDevice->Resolution.w; - } - - // Default value from dev kit 1 - return 1280; + return m_hmdDevice->Resolution.w; } unsigned int OculusDevice::vScreenResolution() const { - if (m_hmdDevice) { - return m_hmdDevice->Resolution.h; - } - - // Default value from dev kit 1 - return 800; + return m_hmdDevice->Resolution.h; } @@ -208,7 +199,7 @@ int OculusDevice::renderOrder(Eye eye) const { return 0; } -osg::Geode* OculusDevice::distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h) { +osg::Geode* OculusDevice::distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h, bool splitViewport) { osg::ref_ptr geode = new osg::Geode; // Allocate & generate distortion mesh vertices. ovrDistortionMesh meshData; @@ -224,7 +215,19 @@ osg::Geode* OculusDevice::distortionMesh(Eye eye, osg::Program* program, int x, for (unsigned vertNum = 0; vertNum < meshData.VertexCount; ++vertNum) { - positionArray->push_back(osg::Vec2f(ov[vertNum].ScreenPosNDC.x, ov[vertNum].ScreenPosNDC.y)); + if (splitViewport) { + // Positions need to be scaled and translated if we are using one viewport per eye + if (eye == LEFT) { + positionArray->push_back(osg::Vec2f(2 * ov[vertNum].ScreenPosNDC.x + 1.0, ov[vertNum].ScreenPosNDC.y)); + } + else if (eye == RIGHT) { + positionArray->push_back(osg::Vec2f(2 * ov[vertNum].ScreenPosNDC.x - 1.0, ov[vertNum].ScreenPosNDC.y)); + } + } + else { + positionArray->push_back(osg::Vec2f(ov[vertNum].ScreenPosNDC.x, ov[vertNum].ScreenPosNDC.y)); + } + colorArray->push_back(osg::Vec4f(ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].TimeWarpFactor)); textureRArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesR.x, ov[vertNum].TanEyeAnglesR.y)); textureGArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesG.x, ov[vertNum].TanEyeAnglesG.y)); @@ -271,89 +274,6 @@ osg::Geode* OculusDevice::distortionMesh(Eye eye, osg::Program* program, int x, geometry->setVertexAttribArray(texCoord2Loc, textureBArray); geometry->setVertexAttribBinding(texCoord2Loc, osg::Geometry::BIND_PER_VERTEX); - - // Compute UV scale and offset - ovrRecti eyeRenderViewport; - eyeRenderViewport.Pos.x = x; - eyeRenderViewport.Pos.y = y; - eyeRenderViewport.Size.w = w; - eyeRenderViewport.Size.h = h; - ovrSizei renderTargetSize; - renderTargetSize.w = m_renderTargetSize.w / 2; - renderTargetSize.h = m_renderTargetSize.h; - ovrHmd_GetRenderScaleAndOffset(m_eyeRenderDesc[eye].Fov, renderTargetSize, eyeRenderViewport, m_UVScaleOffset[eye]); - geode->addDrawable(geometry); - return geode.release(); -} - -osg::Geode* OculusDevice::distortionMeshComposite(Eye eye, osg::Program* program, int x, int y, int w, int h) { - osg::ref_ptr geode = new osg::Geode; - // Allocate & generate distortion mesh vertices. - ovrDistortionMesh meshData; - ovrHmd_CreateDistortionMesh(m_hmdDevice, m_eyeRenderDesc[eye].Eye, m_eyeRenderDesc[eye].Fov, ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp, &meshData); - - // Now parse the vertex data and create a render ready vertex buffer from it - ovrDistortionVertex* ov = meshData.pVertexData; - osg::Vec2Array* positionArray = new osg::Vec2Array; - osg::Vec4Array* colorArray = new osg::Vec4Array; - osg::Vec2Array* textureRArray = new osg::Vec2Array; - osg::Vec2Array* textureGArray = new osg::Vec2Array; - osg::Vec2Array* textureBArray = new osg::Vec2Array; - - for (unsigned vertNum = 0; vertNum < meshData.VertexCount; ++vertNum) - { - if (eye == LEFT) { - positionArray->push_back(osg::Vec2f(2 * ov[vertNum].ScreenPosNDC.x+1.0, ov[vertNum].ScreenPosNDC.y)); - } else if (eye == RIGHT) { - positionArray->push_back(osg::Vec2f(2 * ov[vertNum].ScreenPosNDC.x-1.0, ov[vertNum].ScreenPosNDC.y)); - } - colorArray->push_back(osg::Vec4f(ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].VignetteFactor, ov[vertNum].TimeWarpFactor)); - textureRArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesR.x, ov[vertNum].TanEyeAnglesR.y)); - textureGArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesG.x, ov[vertNum].TanEyeAnglesG.y)); - textureBArray->push_back(osg::Vec2f(ov[vertNum].TanEyeAnglesB.x, ov[vertNum].TanEyeAnglesB.y)); - } - - // Get triangle indicies - osg::UShortArray* indexArray = new osg::UShortArray; - unsigned short* index = meshData.pIndexData; - for (unsigned indexNum = 0; indexNum < meshData.IndexCount; ++indexNum) { - indexArray->push_back(index[indexNum]); - } - - // Deallocate the mesh data - ovrHmd_DestroyDistortionMesh(&meshData); - - osg::ref_ptr geometry = new osg::Geometry; - osg::ref_ptr drawElement = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, indexArray->size(), (GLushort*)indexArray->getDataPointer()); - geometry->addPrimitiveSet(drawElement); - - GLuint positionLoc = 0; - GLuint colorLoc = 1; - GLuint texCoord0Loc = 2; - GLuint texCoord1Loc = 3; - GLuint texCoord2Loc = 4; - - program->addBindAttribLocation("Position", positionLoc); - geometry->setVertexAttribArray(positionLoc, positionArray); - geometry->setVertexAttribBinding(positionLoc, osg::Geometry::BIND_PER_VERTEX); - - program->addBindAttribLocation("Color", colorLoc); - geometry->setVertexAttribArray(colorLoc, colorArray); - geometry->setVertexAttribBinding(colorLoc, osg::Geometry::BIND_PER_VERTEX); - - program->addBindAttribLocation("TexCoord0", texCoord0Loc); - geometry->setVertexAttribArray(texCoord0Loc, textureRArray); - geometry->setVertexAttribBinding(texCoord0Loc, osg::Geometry::BIND_PER_VERTEX); - - program->addBindAttribLocation("TexCoord1", texCoord1Loc); - geometry->setVertexAttribArray(texCoord1Loc, textureGArray); - geometry->setVertexAttribBinding(texCoord1Loc, osg::Geometry::BIND_PER_VERTEX); - - program->addBindAttribLocation("TexCoord2", texCoord2Loc); - geometry->setVertexAttribArray(texCoord2Loc, textureBArray); - geometry->setVertexAttribBinding(texCoord2Loc, osg::Geometry::BIND_PER_VERTEX); - - // Compute UV scale and offset ovrRecti eyeRenderViewport; eyeRenderViewport.Pos.x = x; @@ -403,10 +323,6 @@ osg::Matrixf OculusDevice::eyeRotationEnd(Eye eye) const { return rotationEnd; } -float OculusDevice::aspectRatio(Eye eye) const { - return float(m_eyeRenderDesc[eye].DistortedViewport.Size.w) / float(m_eyeRenderDesc[eye].DistortedViewport.Size.h); -} - void OculusDevice::beginFrameTiming(unsigned int frameIndex) { m_frameTiming = ovrHmd_BeginFrameTiming(m_hmdDevice, frameIndex); } @@ -425,30 +341,22 @@ void OculusDevice::waitTillTime() { } } -osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const +osg::Camera* OculusDevice::createRTTCameraForContext(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const { - osg::ref_ptr camera = new osg::Camera; - camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); - camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - camera->setDrawBuffer(GL_FRONT); - camera->setReadBuffer(GL_FRONT); - camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); - camera->setRenderOrder(osg::Camera::PRE_RENDER, renderOrder(eye)); - camera->setAllowEventFocus(false); + osg::ref_ptr camera = createRTTCameraImplementation(texture, eye);; camera->setGraphicsContext(gc); camera->setReferenceFrame(osg::Camera::RELATIVE_RF); - - if (texture) { - texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); - texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); - camera->setViewport(0, 0, texture->getTextureWidth(), texture->getTextureHeight()); - camera->attach(osg::Camera::COLOR_BUFFER, texture, 0, 0, false, 4, 4); - } - return camera.release(); } osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye) const +{ + osg::ref_ptr camera = createRTTCameraImplementation(texture, eye); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + return camera.release(); +} + +osg::Camera* OculusDevice::createRTTCameraImplementation(osg::Texture* texture, OculusDevice::Eye eye) const { osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); @@ -458,7 +366,6 @@ osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, OculusDevice:: camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); camera->setRenderOrder(osg::Camera::PRE_RENDER, renderOrder(eye)); camera->setAllowEventFocus(false); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); if (texture) { texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); @@ -470,7 +377,6 @@ osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, OculusDevice:: return camera.release(); } - osg::Camera* OculusDevice::createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const { osg::ref_ptr camera = new osg::Camera; diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 8f265f2..cbfb2d3 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -11,13 +11,9 @@ // Include the OculusVR SDK #include "OVR.h" -#include -#include #include -#include #include - class OculusDevice : public osg::Referenced { public: @@ -27,7 +23,7 @@ class OculusDevice : public osg::Referenced { RIGHT = 1, COUNT = 2 }; - OculusDevice(); + OculusDevice(float nearClip, float farClip, bool useTimewarp); unsigned int hScreenResolution() const; unsigned int vScreenResolution() const; @@ -48,8 +44,9 @@ class OculusDevice : public osg::Referenced { osg::Matrix viewMatrixLeft() const; osg::Matrix viewMatrixRight() const; - void setNearClip(float nearClip) { m_nearClip = nearClip; } - void setFarClip(float farclip) { m_farClip = farclip; } + float nearClip() const { return m_nearClip; } + float farClip() const { return m_farClip; } + bool useTimewarp() const { return m_useTimeWarp; } void resetSensorOrientation() const; void updatePose(unsigned int frameIndex = 0); @@ -58,8 +55,7 @@ class OculusDevice : public osg::Referenced { osg::Quat orientation() const { return m_orientation; } int renderOrder(Eye eye) const; - osg::Geode* distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h); - osg::Geode* distortionMeshComposite(Eye eye, osg::Program* program, int x, int y, int w, int h); + osg::Geode* distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h, bool splitViewport=false); osg::Vec2f eyeToSourceUVScale(Eye eye) const; osg::Vec2f eyeToSourceUVOffset(Eye eye) const; osg::Matrixf eyeRotationStart(Eye eye) const; @@ -69,7 +65,7 @@ class OculusDevice : public osg::Referenced { void endFrameTiming() const; void waitTillTime(); - osg::Camera* createRTTCamera(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; + osg::Camera* createRTTCameraForContext(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; osg::Camera* createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye) const; osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; @@ -77,7 +73,7 @@ class OculusDevice : public osg::Referenced { protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected - float aspectRatio(Eye eye) const; + osg::Camera* createRTTCameraImplementation(osg::Texture* texture, OculusDevice::Eye eye) const; ovrHmd m_hmdDevice; ovrSizei m_resolution; @@ -96,11 +92,12 @@ class OculusDevice : public osg::Referenced { osg::Vec3 m_position; osg::Quat m_orientation; - bool m_useTimeWarp; float m_nearClip; float m_farClip; + bool m_useTimeWarp; private: OculusDevice(const OculusDevice&); // Do not allow copy + OculusDevice& operator=(const OculusDevice&); // Do not allow assignment operator. }; class WarpCameraPreDrawCallback : public osg::Camera::DrawCallback diff --git a/src/oculuseventhandler.cpp b/src/oculuseventhandler.cpp index 2e10893..fb65c2d 100644 --- a/src/oculuseventhandler.cpp +++ b/src/oculuseventhandler.cpp @@ -6,6 +6,7 @@ */ #include "oculuseventhandler.h" +#include "oculusdevice.h" bool OculusEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& ad) { diff --git a/src/oculuseventhandler.h b/src/oculuseventhandler.h index cf22435..e8a2cc5 100644 --- a/src/oculuseventhandler.h +++ b/src/oculuseventhandler.h @@ -10,7 +10,8 @@ #include -#include "oculusdevice.h" +// Forward declaration +class OculusDevice; class OculusEventHandler : public osgGA::GUIEventHandler { diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index fd842b5..4514e34 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -6,24 +6,13 @@ */ #include "oculusviewconfig.h" -#include -#include -#include -#include - #include #include -#include - -#include "oculusdevice.h" #include "oculuseventhandler.h" void OculusViewConfig::configure(osgViewer::View& view) const { - m_device->setNearClip(m_nearClip); - m_device->setFarClip(m_farClip); - // Create a graphic context based on our desired traits osg::ref_ptr traits = m_device->graphicsContextTraits(); osg::ref_ptr gc = osg::GraphicsContext::createGraphicsContext(traits); @@ -57,8 +46,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const textureRight->setTextureSize( textureWidth, textureHeight ); textureRight->setInternalFormat( GL_RGBA ); // Create RTT cameras and attach textures - osg::ref_ptr cameraRTTLeft = m_device->createRTTCamera(textureLeft, gc, OculusDevice::LEFT); - osg::ref_ptr cameraRTTRight = m_device->createRTTCamera(textureRight, gc, OculusDevice::RIGHT); + osg::ref_ptr cameraRTTLeft = m_device->createRTTCameraForContext(textureLeft, gc, OculusDevice::LEFT); + osg::ref_ptr cameraRTTRight = m_device->createRTTCameraForContext(textureRight, gc, OculusDevice::RIGHT); cameraRTTLeft->setName("LeftRTT"); cameraRTTRight->setName("RightRTT"); cameraRTTLeft->setCullMask(m_sceneNodeMask); @@ -73,7 +62,7 @@ void OculusViewConfig::configure(osgViewer::View& view) const osg::ref_ptr program = new osg::Program; osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - if (m_useTimeWarp) { + if (m_device->useTimewarp()) { vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); } else { vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); @@ -116,10 +105,9 @@ void OculusViewConfig::configure(osgViewer::View& view) const view.setName("Oculus"); // Connect main camera to node callback that get HMD orientation - if (m_useOrientations) { - camera->setDataVariance(osg::Object::DYNAMIC); - camera->setUpdateCallback(new OculusViewConfigOrientationCallback(cameraRTTLeft, cameraRTTRight, m_device, swapCallback)); - } + camera->setDataVariance(osg::Object::DYNAMIC); + camera->setUpdateCallback(new OculusViewConfigOrientationCallback(cameraRTTLeft, cameraRTTRight, m_device, swapCallback)); + // Add Oculus keyboard handler view.addEventHandler(new OculusEventHandler(m_device)); } diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index cd2104e..2d4593b 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -15,37 +15,17 @@ class OculusViewConfig : public osgViewer::ViewConfig { public: OculusViewConfig() : osgViewer::ViewConfig(), m_configured(false), - m_useChromaticAberrationCorrection(true), - m_useOrientations(true), - m_useCustomScaleFactor(false), - m_useTimeWarp(true), - m_customScaleFactor(1.0f), - m_nearClip(0.01f), - m_farClip(10000.0f), m_sceneNodeMask(0x1), m_device(0) { - m_device = new OculusDevice; + m_device = new OculusDevice(0.01f, 10000.0f, true); } - void setEnableOrientationsFromHMD(bool useOrientations) { m_useOrientations = useOrientations; } - void setEnableChromaticAberrationCorrection(bool correctionEnabled) { m_useChromaticAberrationCorrection = correctionEnabled; } - void setNearClip(float nearClip) { m_nearClip = nearClip; } - void setFarClip(float farclip) { m_farClip = farclip; } void resetSensorOrientation() { if (m_device) m_device->resetSensorOrientation(); } - void setUseDefaultScaleFactor(bool useDefault) { m_useCustomScaleFactor = !useDefault; } - void setCustomScaleFactor(const float& customScaleFactor) { m_useCustomScaleFactor = true; m_customScaleFactor = customScaleFactor; } void setSceneNodeMask(osg::Node::NodeMask nodeMask) { m_sceneNodeMask = nodeMask; } virtual void configure(osgViewer::View& view) const; protected: ~OculusViewConfig() {}; bool m_configured; - bool m_useOrientations; - bool m_useChromaticAberrationCorrection; - bool m_useTimeWarp; - bool m_useCustomScaleFactor; - float m_customScaleFactor; - float m_nearClip; - float m_farClip; osg::Node::NodeMask m_sceneNodeMask; osg::ref_ptr m_device; diff --git a/src/oculusviewer.cpp b/src/oculusviewer.cpp index 5e87786..1270822 100644 --- a/src/oculusviewer.cpp +++ b/src/oculusviewer.cpp @@ -2,7 +2,7 @@ * oculusviewer.cpp * * Created on: Jun 30, 2013 - * Author: Jan Ciger + * Author: Jan Ciger & Björn Blissing */ #include "oculusviewer.h" @@ -12,19 +12,6 @@ #include -OculusViewer::OculusViewer(osgViewer::View* view, osg::ref_ptr dev) : osg::Group(), - m_configured(false), - m_useChromaticAberrationCorrection(false), - m_useTimeWarp(true), - m_useCustomScaleFactor(false), - m_customScaleFactor(1.0f), - m_nearClip(0.01f), - m_farClip(10000.0f), - m_view(view), - m_device(dev) -{ -} - void OculusViewer::traverse(osg::NodeVisitor& nv) { if (!m_configured) { @@ -51,9 +38,6 @@ void OculusViewer::traverse(osg::NodeVisitor& nv) void OculusViewer::configure() { - m_device->setNearClip(m_nearClip); - m_device->setFarClip(m_farClip); - osg::ref_ptr gc = m_view->getCamera()->getGraphicsContext(); // Attach a callback to detect swap @@ -78,8 +62,8 @@ void OculusViewer::configure() textureRight->setTextureSize(textureWidth, textureHeight); textureRight->setInternalFormat(GL_RGBA); // Create RTT cameras and attach textures - m_cameraRTTLeft = m_device->createRTTCamera(textureLeft, gc, OculusDevice::Eye::LEFT); - m_cameraRTTRight = m_device->createRTTCamera(textureRight, gc, OculusDevice::Eye::RIGHT); + m_cameraRTTLeft = m_device->createRTTCameraForContext(textureLeft, gc, OculusDevice::Eye::LEFT); + m_cameraRTTRight = m_device->createRTTCameraForContext(textureRight, gc, OculusDevice::Eye::RIGHT); m_cameraRTTLeft->setName("LeftRTT"); m_cameraRTTRight->setName("RightRTT"); m_cameraRTTLeft->setCullMask(m_sceneNodeMask); @@ -94,7 +78,7 @@ void OculusViewer::configure() osg::ref_ptr program = new osg::Program; osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - if (m_useTimeWarp) { + if (m_device->useTimewarp()) { vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); } else { vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); diff --git a/src/oculusviewer.h b/src/oculusviewer.h index 9138c33..86db60a 100644 --- a/src/oculusviewer.h +++ b/src/oculusviewer.h @@ -2,7 +2,7 @@ * oculusviewer.h * * Created on: Jun 30, 2013 - * Author: Jan Ciger + * Author: Jan Ciger & Björn Blissing */ #ifndef _OSG_OCULUSVIEWER_H_ @@ -12,14 +12,20 @@ #include "oculusdevice.h" +// Forward declaration namespace osgViewer { class View; - class NodeVisitor; } class OculusViewer : public osg::Group { public: - OculusViewer(osgViewer::View* view, osg::ref_ptr dev); + OculusViewer(osgViewer::View* view, osg::ref_ptr dev) : osg::Group(), + m_configured(false), + m_view(view), + m_cameraRTTLeft(0), m_cameraRTTRight(0), + m_device(dev), + m_swapCallback(0), + m_sceneNodeMask(0x1) {}; virtual void traverse(osg::NodeVisitor& nv); void setSceneNodeMask(osg::Node::NodeMask nodeMask) { m_sceneNodeMask = nodeMask; } protected: @@ -27,12 +33,6 @@ class OculusViewer : public osg::Group { virtual void configure(); bool m_configured; - bool m_useChromaticAberrationCorrection; - bool m_useTimeWarp; - bool m_useCustomScaleFactor; - float m_customScaleFactor; - float m_nearClip; - float m_farClip; osg::observer_ptr m_view; osg::observer_ptr m_cameraRTTLeft, m_cameraRTTRight; diff --git a/src/viewconfigexample.cpp b/src/viewconfigexample.cpp index 25917c2..e56bf6f 100644 --- a/src/viewconfigexample.cpp +++ b/src/viewconfigexample.cpp @@ -7,8 +7,6 @@ #include #include -#include -#include #include "oculuseventhandler.h" #include "oculusviewconfig.h" diff --git a/src/viewerexample.cpp b/src/viewerexample.cpp index 660a449..6ebf8e8 100644 --- a/src/viewerexample.cpp +++ b/src/viewerexample.cpp @@ -5,25 +5,10 @@ * Author: Bjorn Blissing */ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - #include #include -#include -#include #include "oculusviewer.h" -#include "oculusdevice.h" #include "oculuseventhandler.h" @@ -50,7 +35,7 @@ int main( int argc, char** argv ) } // Open the HMD - osg::ref_ptr oculusDevice = new OculusDevice(); + osg::ref_ptr oculusDevice = new OculusDevice(0.01f, 10000.0f, true); // Get the suggested context traits osg::ref_ptr traits = oculusDevice->graphicsContextTraits(); From 83a72874720dd7209089f8159959e869f3645ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 00:57:48 +0200 Subject: [PATCH 36/51] Correct enumeration of connected devices. --- src/oculusdevice.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index f81969f..62c69b5 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -19,7 +19,8 @@ OculusDevice::OculusDevice(float nearClip, float farClip, bool useTimewarp) : m_ ovr_Initialize(); // Enumerate HMD devices - int hmd_ovrHmd_Detect(); + int numberOfDevices = ovrHmd_Detect(); + osg::notify(osg::DEBUG_INFO) << "Number of connected devices: " << numberOfDevices << std::endl; // Get first available HMD m_hmdDevice = ovrHmd_Create(0); From 5421caa493e3a1db1a280f3433955ec66620a128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 01:21:27 +0200 Subject: [PATCH 37/51] Removed trailing semi-colon in shaders, since it caused shader compiling to fail on some platforms. --- src/warp_mesh.frag | 2 +- src/warp_mesh.vert | 2 +- src/warp_mesh_with_timewarp.vert | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/warp_mesh.frag b/src/warp_mesh.frag index bbac9cb..60c0496 100644 --- a/src/warp_mesh.frag +++ b/src/warp_mesh.frag @@ -13,4 +13,4 @@ void main() gl_FragColor.g = oColor.g * texture2D(Texture, oTexCoord1).g; gl_FragColor.b = oColor.b * texture2D(Texture, oTexCoord2).b; gl_FragColor.a = 1.0; -}; +} diff --git a/src/warp_mesh.vert b/src/warp_mesh.vert index 27bf26f..47746d5 100644 --- a/src/warp_mesh.vert +++ b/src/warp_mesh.vert @@ -29,4 +29,4 @@ void main() oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset; oTexCoord2.y = 1.0-oTexCoord2.y; oColor = Color; // Used for vignette fade. -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src/warp_mesh_with_timewarp.vert b/src/warp_mesh_with_timewarp.vert index bd38584..9a40d6f 100644 --- a/src/warp_mesh_with_timewarp.vert +++ b/src/warp_mesh_with_timewarp.vert @@ -57,4 +57,4 @@ void main() oTexCoord2 = SrcCoordB; oTexCoord2.y = 1.0-oTexCoord2.y; oColor = vec4(Color.r, Color.r, Color.r, Color.r); // Used for vignette fade. -}; \ No newline at end of file +} \ No newline at end of file From f794efe3df90c6a813bd9233794f6d240e438a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 14:48:29 +0200 Subject: [PATCH 38/51] Some code refactoring regarding the createRTTCamera function. --- src/compositeviewerexample.cpp | 4 ++-- src/oculusdevice.cpp | 22 ++++++---------------- src/oculusdevice.h | 5 ++--- src/oculusviewconfig.cpp | 4 ++-- src/oculusviewer.cpp | 4 ++-- 5 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index de7bbda..f058989 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -54,10 +54,10 @@ int main( int argc, char** argv ) textureRight->setTextureSize(textureWidth, textureHeight); textureRight->setInternalFormat(GL_RGBA); // Initialize RTT cameras for each eye - osg::ref_ptr leftEyeRTTCamera = oculusDevice->createRTTCamera(textureLeft, OculusDevice::LEFT); + osg::ref_ptr leftEyeRTTCamera = oculusDevice->createRTTCamera(textureLeft, OculusDevice::LEFT, osg::Camera::ABSOLUTE_RF); leftEyeRTTCamera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); leftEyeRTTCamera->addChild( loadedModel ); - osg::ref_ptr rightEyeRTTCamera = oculusDevice->createRTTCamera(textureRight, OculusDevice::RIGHT); + osg::ref_ptr rightEyeRTTCamera = oculusDevice->createRTTCamera(textureRight, OculusDevice::RIGHT, osg::Camera::ABSOLUTE_RF); rightEyeRTTCamera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); rightEyeRTTCamera->addChild( loadedModel ); // Create HUD cameras for each eye diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 62c69b5..8d7477e 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -342,22 +342,7 @@ void OculusDevice::waitTillTime() { } } -osg::Camera* OculusDevice::createRTTCameraForContext(osg::Texture* texture, osg::GraphicsContext* gc, OculusDevice::Eye eye) const -{ - osg::ref_ptr camera = createRTTCameraImplementation(texture, eye);; - camera->setGraphicsContext(gc); - camera->setReferenceFrame(osg::Camera::RELATIVE_RF); - return camera.release(); -} - -osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye) const -{ - osg::ref_ptr camera = createRTTCameraImplementation(texture, eye); - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - return camera.release(); -} - -osg::Camera* OculusDevice::createRTTCameraImplementation(osg::Texture* texture, OculusDevice::Eye eye) const +osg::Camera* OculusDevice::createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye, osg::Transform::ReferenceFrame referenceFrame, osg::GraphicsContext* gc) const { osg::ref_ptr camera = new osg::Camera; camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); @@ -367,6 +352,11 @@ osg::Camera* OculusDevice::createRTTCameraImplementation(osg::Texture* texture, camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); camera->setRenderOrder(osg::Camera::PRE_RENDER, renderOrder(eye)); camera->setAllowEventFocus(false); + camera->setReferenceFrame(referenceFrame); + + if (gc) { + camera->setGraphicsContext(gc); + } if (texture) { texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); diff --git a/src/oculusdevice.h b/src/oculusdevice.h index cbfb2d3..c7f7972 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -65,15 +65,14 @@ class OculusDevice : public osg::Referenced { void endFrameTiming() const; void waitTillTime(); - osg::Camera* createRTTCameraForContext(osg::Texture* tex, osg::GraphicsContext* gc, OculusDevice::Eye eye) const; - osg::Camera* createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye) const; + osg::Camera* createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye, osg::Transform::ReferenceFrame referenceFrame, osg::GraphicsContext* gc = 0) const; osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; osg::GraphicsContext::Traits* graphicsContextTraits() const; protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected - osg::Camera* createRTTCameraImplementation(osg::Texture* texture, OculusDevice::Eye eye) const; + ovrHmd m_hmdDevice; ovrSizei m_resolution; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 4514e34..35d5516 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -46,8 +46,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const textureRight->setTextureSize( textureWidth, textureHeight ); textureRight->setInternalFormat( GL_RGBA ); // Create RTT cameras and attach textures - osg::ref_ptr cameraRTTLeft = m_device->createRTTCameraForContext(textureLeft, gc, OculusDevice::LEFT); - osg::ref_ptr cameraRTTRight = m_device->createRTTCameraForContext(textureRight, gc, OculusDevice::RIGHT); + osg::ref_ptr cameraRTTLeft = m_device->createRTTCamera(textureLeft, OculusDevice::Eye::LEFT, osg::Camera::RELATIVE_RF, gc); + osg::ref_ptr cameraRTTRight = m_device->createRTTCamera(textureRight, OculusDevice::Eye::RIGHT, osg::Camera::RELATIVE_RF, gc); cameraRTTLeft->setName("LeftRTT"); cameraRTTRight->setName("RightRTT"); cameraRTTLeft->setCullMask(m_sceneNodeMask); diff --git a/src/oculusviewer.cpp b/src/oculusviewer.cpp index 1270822..44f0eea 100644 --- a/src/oculusviewer.cpp +++ b/src/oculusviewer.cpp @@ -62,8 +62,8 @@ void OculusViewer::configure() textureRight->setTextureSize(textureWidth, textureHeight); textureRight->setInternalFormat(GL_RGBA); // Create RTT cameras and attach textures - m_cameraRTTLeft = m_device->createRTTCameraForContext(textureLeft, gc, OculusDevice::Eye::LEFT); - m_cameraRTTRight = m_device->createRTTCameraForContext(textureRight, gc, OculusDevice::Eye::RIGHT); + m_cameraRTTLeft = m_device->createRTTCamera(textureLeft, OculusDevice::Eye::LEFT, osg::Camera::RELATIVE_RF, gc); + m_cameraRTTRight = m_device->createRTTCamera(textureRight, OculusDevice::Eye::RIGHT, osg::Camera::RELATIVE_RF, gc); m_cameraRTTLeft->setName("LeftRTT"); m_cameraRTTRight->setName("RightRTT"); m_cameraRTTLeft->setCullMask(m_sceneNodeMask); From aa3754a8a9733ab80c7ca12697e315a5cef8948d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 15:13:12 +0200 Subject: [PATCH 39/51] Renamed screen and render target properties. --- src/compositeviewerexample.cpp | 8 ++++---- src/oculusdevice.cpp | 16 ++++++++-------- src/oculusdevice.h | 11 ++++------- src/oculusviewconfig.cpp | 6 +++--- src/oculusviewer.cpp | 6 +++--- 5 files changed, 22 insertions(+), 25 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index f058989..07afc16 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -44,8 +44,8 @@ int main( int argc, char** argv ) if (!loadedModel) return 0; // Calculate the texture size - const int textureWidth = oculusDevice->hRenderTargetSize()/2; - const int textureHeight = oculusDevice->vRenderTargetSize(); + const int textureWidth = oculusDevice->renderTargetWidth()/2; + const int textureHeight = oculusDevice->renderTargetHeight(); // Setup textures for the RTT cameras osg::ref_ptr textureLeft = new osg::Texture2D; textureLeft->setTextureSize(textureWidth, textureHeight); @@ -131,7 +131,7 @@ int main( int argc, char** argv ) leftView->setSceneData(leftRoot); leftView->getCamera()->setName("LeftEyeCamera"); leftView->getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); - leftView->getCamera()->setViewport(new osg::Viewport(0, 0, oculusDevice->hScreenResolution() / 2, oculusDevice->vScreenResolution())); + leftView->getCamera()->setViewport(new osg::Viewport(0, 0, oculusDevice->screenResolutionWidth() / 2, oculusDevice->screenResolutionHeight())); leftView->getCamera()->setGraphicsContext(gc); // Add statistics view to only one view leftView->addEventHandler(new osgViewer::StatsHandler); @@ -144,7 +144,7 @@ int main( int argc, char** argv ) rightView->setSceneData(rightRoot); rightView->getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); rightView->getCamera()->setName("RightEyeCamera"); - rightView->getCamera()->setViewport(new osg::Viewport(oculusDevice->hScreenResolution() / 2, 0, oculusDevice->hScreenResolution() / 2, oculusDevice->vScreenResolution())); + rightView->getCamera()->setViewport(new osg::Viewport(oculusDevice->screenResolutionWidth() / 2, 0, oculusDevice->screenResolutionWidth() / 2, oculusDevice->screenResolutionHeight())); rightView->getCamera()->setGraphicsContext(gc); rightView->setCameraManipulator(cameraManipulator); diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 8d7477e..f6b86bb 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -94,23 +94,23 @@ OculusDevice::~OculusDevice() ovr_Shutdown(); } -unsigned int OculusDevice::hScreenResolution() const +unsigned int OculusDevice::screenResolutionWidth() const { return m_hmdDevice->Resolution.w; } -unsigned int OculusDevice::vScreenResolution() const +unsigned int OculusDevice::screenResolutionHeight() const { return m_hmdDevice->Resolution.h; } -unsigned int OculusDevice::hRenderTargetSize() const +unsigned int OculusDevice::renderTargetWidth() const { return m_renderTargetSize.w; } -unsigned int OculusDevice::vRenderTargetSize() const +unsigned int OculusDevice::renderTargetHeight() const { return m_renderTargetSize.h; } @@ -427,10 +427,10 @@ osg::GraphicsContext::Traits* OculusDevice::graphicsContextTraits() const { traits->screenNum = si.screenNum; traits->displayNum = si.displayNum; traits->windowDecoration = false; - traits->x = windowPos().x(); - traits->y = windowPos().y(); - traits->width = hScreenResolution(); - traits->height = vScreenResolution(); + traits->x = m_hmdDevice->WindowsPos.x; + traits->y = m_hmdDevice->WindowsPos.y; + traits->width = screenResolutionWidth(); + traits->height = screenResolutionHeight(); traits->doubleBuffer = true; traits->sharedContext = 0; traits->vsync = true; // VSync should always be enabled for Oculus Rift applications diff --git a/src/oculusdevice.h b/src/oculusdevice.h index c7f7972..86d4646 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -25,14 +25,11 @@ class OculusDevice : public osg::Referenced { }; OculusDevice(float nearClip, float farClip, bool useTimewarp); - unsigned int hScreenResolution() const; - unsigned int vScreenResolution() const; + unsigned int screenResolutionWidth() const; + unsigned int screenResolutionHeight() const; - unsigned int hRenderTargetSize() const; - unsigned int vRenderTargetSize() const; - - int displayId() const { return m_hmdDevice->DisplayId; } - osg::Vec2i windowPos() const { return osg::Vec2i(m_hmdDevice->WindowsPos.x, m_hmdDevice->WindowsPos.y); } + unsigned int renderTargetWidth() const; + unsigned int renderTargetHeight() const; osg::Matrix projectionMatrixCenter() const; osg::Matrix projectionMatrixLeft() const; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 35d5516..27c30d4 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -34,8 +34,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); // Disable automatic computation of near and far plane on main camera, will propagate to slave cameras camera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); - const int textureWidth = m_device->hRenderTargetSize()/2; - const int textureHeight = m_device->vRenderTargetSize(); + const int textureWidth = m_device->renderTargetWidth()/2; + const int textureHeight = m_device->renderTargetHeight(); // master projection matrix camera->setProjectionMatrix(m_device->projectionMatrixCenter()); // Create textures for RTT cameras @@ -56,7 +56,7 @@ void OculusViewConfig::configure(osgViewer::View& view) const // Create warp ortho camera osg::ref_ptr cameraWarp = m_device->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); cameraWarp->setName("WarpOrtho"); - cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); + cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->screenResolutionWidth(), m_device->screenResolutionHeight())); // Set up shaders from the Oculus SDK documentation osg::ref_ptr program = new osg::Program; diff --git a/src/oculusviewer.cpp b/src/oculusviewer.cpp index 44f0eea..bd5aa33 100644 --- a/src/oculusviewer.cpp +++ b/src/oculusviewer.cpp @@ -50,8 +50,8 @@ void OculusViewer::configure() // Disable scene rendering for main camera camera->setCullMask(~m_sceneNodeMask); - const int textureWidth = m_device->hRenderTargetSize()/2; - const int textureHeight = m_device->vRenderTargetSize(); + const int textureWidth = m_device->renderTargetWidth()/2; + const int textureHeight = m_device->renderTargetHeight(); // master projection matrix camera->setProjectionMatrix(m_device->projectionMatrixCenter()); // Create textures for RTT cameras @@ -72,7 +72,7 @@ void OculusViewer::configure() // Create warp ortho camera osg::ref_ptr cameraWarp = m_device->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0, gc); cameraWarp->setName("WarpOrtho"); - cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->hScreenResolution(), m_device->vScreenResolution())); + cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->screenResolutionWidth(), m_device->screenResolutionHeight())); // Set up shaders from the Oculus SDK documentation osg::ref_ptr program = new osg::Program; From 0df3edc9f6cdc9a08cac1844d86760d451374957 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 15:14:26 +0200 Subject: [PATCH 40/51] Reduced the number of public functions for OculusDevice class. --- src/oculusdevice.h | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 86d4646..f14624b 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -14,8 +14,16 @@ #include #include -class OculusDevice : public osg::Referenced { +// Forward declaration +class WarpCameraPreDrawCallback; +class OculusSwapCallback; +class EyeRotationCallback; +class OculusDevice : public osg::Referenced { + friend class WarpCameraPreDrawCallback; + friend class OculusSwapCallback; + friend class EyeRotationCallback; + public: enum Eye { @@ -51,17 +59,7 @@ class OculusDevice : public osg::Referenced { osg::Vec3 position() const { return m_position; } osg::Quat orientation() const { return m_orientation; } - int renderOrder(Eye eye) const; osg::Geode* distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h, bool splitViewport=false); - osg::Vec2f eyeToSourceUVScale(Eye eye) const; - osg::Vec2f eyeToSourceUVOffset(Eye eye) const; - osg::Matrixf eyeRotationStart(Eye eye) const; - osg::Matrixf eyeRotationEnd(Eye eye) const; - - void beginFrameTiming(unsigned int frameIndex=0); - void endFrameTiming() const; - void waitTillTime(); - osg::Camera* createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye, osg::Transform::ReferenceFrame referenceFrame, osg::GraphicsContext* gc = 0) const; osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; @@ -69,7 +67,16 @@ class OculusDevice : public osg::Referenced { protected: ~OculusDevice(); // Since we inherit from osg::Referenced we must make destructor protected - + + int renderOrder(Eye eye) const; + osg::Matrixf eyeRotationStart(Eye eye) const; + osg::Matrixf eyeRotationEnd(Eye eye) const; + osg::Vec2f eyeToSourceUVScale(Eye eye) const; + osg::Vec2f eyeToSourceUVOffset(Eye eye) const; + + void beginFrameTiming(unsigned int frameIndex = 0); + void endFrameTiming() const; + void waitTillTime(); ovrHmd m_hmdDevice; ovrSizei m_resolution; @@ -123,12 +130,12 @@ class EyeRotationCallback : public osg::Uniform::Callback START, END }; - EyeRotationCallback(Mode mode, const OculusDevice* device, OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} + EyeRotationCallback(const Mode mode, const OculusDevice* device, const OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv); protected: - Mode m_mode; + const Mode m_mode; const OculusDevice* m_device; - OculusDevice::Eye m_eye; + const OculusDevice::Eye m_eye; }; #endif /* _OSG_OCULUSDEVICE_H_ */ From 1e64cbd0a6dc1c2dedb0245f98deba69cd594824 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 15:17:52 +0200 Subject: [PATCH 41/51] Reduced the number of public functions for OculusViewConfig class. --- src/oculusviewconfig.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index 2d4593b..39b5890 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -19,7 +19,6 @@ class OculusViewConfig : public osgViewer::ViewConfig { m_device(0) { m_device = new OculusDevice(0.01f, 10000.0f, true); } - void resetSensorOrientation() { if (m_device) m_device->resetSensorOrientation(); } void setSceneNodeMask(osg::Node::NodeMask nodeMask) { m_sceneNodeMask = nodeMask; } virtual void configure(osgViewer::View& view) const; protected: From a81c2dfc775d4b61287e46e1cafab5d0276e01f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 16:32:07 +0200 Subject: [PATCH 42/51] Refactored createWarpOrthoCamera from CompositeViewerExample. --- src/compositeviewerexample.cpp | 18 ++---------------- src/oculusdevice.cpp | 6 +++++- src/oculusdevice.h | 2 +- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index 07afc16..53ec53e 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -14,20 +14,6 @@ #include -osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top) -{ - osg::ref_ptr camera = new osg::Camera; - camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); - camera->setClearColor(osg::Vec4(0.2f, 0.2f, 0.4f, 1.0f)); - camera->setClearMask(GL_DEPTH_BUFFER_BIT); - camera->setRenderOrder(osg::Camera::POST_RENDER); - camera->setAllowEventFocus(false); - camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top)); - camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - camera->setViewMatrix(osg::Matrix::identity()); - return camera.release(); -} - int main( int argc, char** argv ) { @@ -61,8 +47,8 @@ int main( int argc, char** argv ) rightEyeRTTCamera->setComputeNearFarMode( osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR ); rightEyeRTTCamera->addChild( loadedModel ); // Create HUD cameras for each eye - osg::ref_ptr leftCameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); - osg::ref_ptr rightCameraWarp = createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); + osg::ref_ptr leftCameraWarp = oculusDevice->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); + osg::ref_ptr rightCameraWarp = oculusDevice->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); // Set up shaders from the Oculus SDK documentation osg::ref_ptr program = new osg::Program; diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index f6b86bb..2d5f729 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -375,10 +375,14 @@ osg::Camera* OculusDevice::createWarpOrthoCamera(double left, double right, doub camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); camera->setRenderOrder(osg::Camera::POST_RENDER); camera->setAllowEventFocus(false); - camera->setGraphicsContext(gc); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); camera->setProjectionMatrix(osg::Matrix::ortho2D(left, right, bottom, top)); camera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + + if (gc) { + camera->setGraphicsContext(gc); + } return camera.release(); } diff --git a/src/oculusdevice.h b/src/oculusdevice.h index f14624b..1e48fec 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -61,7 +61,7 @@ class OculusDevice : public osg::Referenced { osg::Geode* distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h, bool splitViewport=false); osg::Camera* createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye, osg::Transform::ReferenceFrame referenceFrame, osg::GraphicsContext* gc = 0) const; - osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc) const; + osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc=0) const; void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; osg::GraphicsContext::Traits* graphicsContextTraits() const; From 79a8532a0bb6158bdbd8064be6f0494c698e88f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 16:35:33 +0200 Subject: [PATCH 43/51] Moved the shader loading and creation to OculusDevice class to reduce code duplication. --- src/compositeviewerexample.cpp | 19 ++----------------- src/oculusdevice.cpp | 20 ++++++++++++++++++++ src/oculusdevice.h | 1 + src/oculusviewconfig.cpp | 19 ++----------------- src/oculusviewer.cpp | 19 ++----------------- 5 files changed, 27 insertions(+), 51 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index 53ec53e..1ae5831 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -10,8 +10,6 @@ #include #include -#include - #include @@ -50,21 +48,8 @@ int main( int argc, char** argv ) osg::ref_ptr leftCameraWarp = oculusDevice->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); osg::ref_ptr rightCameraWarp = oculusDevice->createWarpOrthoCamera(0.0, 1.0, 0.0, 1.0); - // Set up shaders from the Oculus SDK documentation - osg::ref_ptr program = new osg::Program; - osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - - if (oculusDevice->useTimewarp()) { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); - } - else { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); - } - - osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); - program->addShader(vertexShader); - program->addShader(fragmentShader); + // Create shader program + osg::ref_ptr program = oculusDevice->createShaderProgram(); // Create distortionMesh for each camera osg::ref_ptr leftDistortionMesh = oculusDevice->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight, true); diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 2d5f729..7a3ccb9 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -8,6 +8,7 @@ #include "oculusdevice.h" #include +#include OculusDevice::OculusDevice(float nearClip, float farClip, bool useTimewarp) : m_hmdDevice(0), @@ -386,6 +387,25 @@ osg::Camera* OculusDevice::createWarpOrthoCamera(double left, double right, doub return camera.release(); } +osg::Program* OculusDevice::createShaderProgram() const { + // Set up shaders from the Oculus SDK documentation + osg::ref_ptr program = new osg::Program; + osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); + + if (m_useTimeWarp) { + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); + } + else { + vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); + } + + osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); + fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); + program->addShader(vertexShader); + program->addShader(fragmentShader); + return program.release(); +} + void OculusDevice::applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const { stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON); stateSet->setAttributeAndModes(program, osg::StateAttribute::ON); diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 1e48fec..639616e 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -62,6 +62,7 @@ class OculusDevice : public osg::Referenced { osg::Geode* distortionMesh(Eye eye, osg::Program* program, int x, int y, int w, int h, bool splitViewport=false); osg::Camera* createRTTCamera(osg::Texture* texture, OculusDevice::Eye eye, osg::Transform::ReferenceFrame referenceFrame, osg::GraphicsContext* gc = 0) const; osg::Camera* createWarpOrthoCamera(double left, double right, double bottom, double top, osg::GraphicsContext* gc=0) const; + osg::Program* createShaderProgram() const; void applyShaderParameters(osg::StateSet* stateSet, osg::Program* program, osg::Texture2D* texture, OculusDevice::Eye eye) const; osg::GraphicsContext::Traits* graphicsContextTraits() const; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 27c30d4..3d73c76 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -6,9 +6,6 @@ */ #include "oculusviewconfig.h" -#include -#include - #include "oculuseventhandler.h" void OculusViewConfig::configure(osgViewer::View& view) const @@ -58,20 +55,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const cameraWarp->setName("WarpOrtho"); cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->screenResolutionWidth(), m_device->screenResolutionHeight())); - // Set up shaders from the Oculus SDK documentation - osg::ref_ptr program = new osg::Program; - osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - - if (m_device->useTimewarp()) { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); - } else { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); - } - - osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); - program->addShader(vertexShader); - program->addShader(fragmentShader); + // Create shader program + osg::ref_ptr program = m_device->createShaderProgram(); // Create distortionMesh for each camera osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::LEFT, program, 0, 0, textureWidth, textureHeight); diff --git a/src/oculusviewer.cpp b/src/oculusviewer.cpp index bd5aa33..4df95ae 100644 --- a/src/oculusviewer.cpp +++ b/src/oculusviewer.cpp @@ -7,9 +7,6 @@ #include "oculusviewer.h" -#include -#include - #include void OculusViewer::traverse(osg::NodeVisitor& nv) @@ -74,20 +71,8 @@ void OculusViewer::configure() cameraWarp->setName("WarpOrtho"); cameraWarp->setViewport(new osg::Viewport(0, 0, m_device->screenResolutionWidth(), m_device->screenResolutionHeight())); - // Set up shaders from the Oculus SDK documentation - osg::ref_ptr program = new osg::Program; - osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); - - if (m_device->useTimewarp()) { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); - } else { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); - } - - osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); - program->addShader(vertexShader); - program->addShader(fragmentShader); + // Create shader program + osg::ref_ptr program = m_device->createShaderProgram(); // Create distortionMesh for each camera osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); From 49de90c71925bacf07cea21800361f772fe9c4e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 18:50:04 +0200 Subject: [PATCH 44/51] Move shaders to source instead of separate files. --- CMakeLists.txt | 21 ++---- src/CMakeLists.txt | 18 +---- src/oculusdevice.cpp | 123 ++++++++++++++++++++++++++++++- src/oculusdevice.h | 4 + src/warp_mesh.frag | 16 ---- src/warp_mesh.vert | 32 -------- src/warp_mesh_with_timewarp.vert | 60 --------------- 7 files changed, 135 insertions(+), 139 deletions(-) delete mode 100644 src/warp_mesh.frag delete mode 100644 src/warp_mesh.vert delete mode 100644 src/warp_mesh_with_timewarp.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index c35b8af..6f069c8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,19 +30,19 @@ IF (WIN32) IF(NOT OSG_DIR) MESSAGE(FATAL_ERROR "Error: OpenSceneGraph not found.") ENDIF(NOT OSG_DIR) - + # Where to find OpenSceneGraph third party dependencies SET(OSG_THIRD_PARTY_DIR $ENV{OSG_THIRD_PARTY_DIR} CACHE PATH "Path where to find the OpenSceneGraph third party dependencies") IF(NOT OSG_THIRD_PARTY_DIR) MESSAGE(FATAL_ERROR "Error: OpenSceneGraph 3rd Party Directory not found.") ENDIF(NOT OSG_THIRD_PARTY_DIR) - + # Where to find Oculus SDK SET(OCULUS_SDK_ROOT_DIR $ENV{OCULUS_SDK_ROOT_DIR} CACHE PATH "Path where to find the Oculus SDK") IF(NOT OCULUS_SDK_ROOT_DIR) MESSAGE(FATAL_ERROR "Error: Oculus SDK not found.") ENDIF(NOT OCULUS_SDK_ROOT_DIR) - + IF(MSVC) OPTION(VISUAL_STUDIO_EXPRESS "Building with Visual Studio Express" OFF) IF(VISUAL_STUDIO_EXPRESS) @@ -65,7 +65,7 @@ FIND_PACKAGE( OpenGL REQUIRED ) FIND_PACKAGE( OpenSceneGraph REQUIRED osgViewer osgDB osgGA) FIND_PACKAGE( OculusSDK REQUIRED ) -# Oculus SDK dependencies for Mac OSX: +# Oculus SDK dependencies for Mac OSX IF (APPLE) FIND_LIBRARY (CORE_FOUNDATION CoreFoundation) FIND_LIBRARY (CORE_GRAPHICS CoreGraphics) @@ -99,23 +99,18 @@ IF(MSVC) # Make sure we use minimal windows.h library without min max macros SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"WIN32_LEAN_AND_MEAN\"") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D \"NOMINMAX\"") - + # Use Link Time Code Generation SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG") - + # Add ATL libraries for Visual Studio Express builds IF(VISUAL_STUDIO_EXPRESS) SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LIBPATH:${ATL_LIBRARY_DIR}") ENDIF(VISUAL_STUDIO_EXPRESS) - IF(MSVC80) - # Detech 64-bit portability Issues - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wp64") - ENDIF(MSVC80) - OPTION(BUILD_MULTI_PROCESSOR_COMPILATION "Use multiple processors when compiling" ON) MARK_AS_ADVANCED(BUILD_MULTI_PROCESSOR_COMPILATION) - + IF(BUILD_MULTI_PROCESSOR_COMPILATION) # Set multi processor build SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") @@ -140,7 +135,7 @@ IF(UNIX) set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++98 -stdlib=libstdc++ -Wno-overloaded-virtual -Wno-conversion") set(WARNING_CFLAGS "") - ENDIF() + ENDIF() ENDIF(UNIX) ############################################################################### diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fa5db6f..220b5c6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -24,7 +24,7 @@ IF (USE_VIEW_CONFIG) SET(TARGET_SRC ${TARGET_SRC} oculusviewconfig.cpp ) - + SET(TARGET_H ${TARGET_H} oculusviewconfig.h ) @@ -35,7 +35,7 @@ ENDIF() ##################################################################### ADD_LIBRARY(${TARGET_LIBRARYNAME} ${TARGET_SRC} ${TARGET_H}) - + ##################################################################### # Linker options ##################################################################### @@ -84,19 +84,9 @@ IF(BUILD_EXAMPLES) ADD_EXECUTABLE(${TARGET_TARGETNAME_VIEW_CONFIG} viewconfigexample.cpp) TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME_VIEW_CONFIG} ${TARGET_LIBRARYNAME}) ENDIF() - -ENDIF(BUILD_EXAMPLES) +ENDIF(BUILD_EXAMPLES) -#################################################################### -# Copy shaders if we are doing out of source builds -##################################################################### - -IF (CMAKE_OUT_OF_SOURCE_BUILD) - CONFIGURE_FILE(warp_mesh.vert warp_mesh.vert COPYONLY) - CONFIGURE_FILE(warp_mesh_with_timewarp.vert warp_mesh_with_timewarp.vert COPYONLY) - CONFIGURE_FILE(warp_mesh.frag warp_mesh.frag COPYONLY) -ENDIF() #################################################################### # Create user file for correct environment string @@ -131,7 +121,7 @@ IF(MSVC) IF (USE_VIEW_CONFIG) CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_VIEW_CONFIG}.vcxproj.user @ONLY) ENDIF() - + ENDIF() ENDIF (OPENSCENEGRAPH_FOUND) ENDIF(MSVC) diff --git a/src/oculusdevice.cpp b/src/oculusdevice.cpp index 7a3ccb9..21818fb 100644 --- a/src/oculusdevice.cpp +++ b/src/oculusdevice.cpp @@ -8,8 +8,123 @@ #include "oculusdevice.h" #include -#include +const std::string OculusDevice::m_warpVertexShaderSource( + "#version 110\n" + + "uniform vec2 EyeToSourceUVScale;\n" + "uniform vec2 EyeToSourceUVOffset;\n" + + "attribute vec2 Position;\n" + "attribute vec4 Color;\n" + "attribute vec2 TexCoord0;\n" + "attribute vec2 TexCoord1;\n" + "attribute vec2 TexCoord2;\n" + + "varying vec4 oColor;\n" + "varying vec2 oTexCoord0;\n" + "varying vec2 oTexCoord1;\n" + "varying vec2 oTexCoord2;\n" + + "void main()\n" + "{\n" + " gl_Position.x = Position.x;\n" + " gl_Position.y = Position.y;\n" + " gl_Position.z = 0.5;\n" + " gl_Position.w = 1.0;\n" + " // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).\n" + " // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)\n" + " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0.y = 1.0-oTexCoord0.y;\n" + " oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord1.y = 1.0-oTexCoord1.y;\n" + " oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord2.y = 1.0-oTexCoord2.y;\n" + " oColor = Color; // Used for vignette fade.\n" + "}\n" +); + +const std::string OculusDevice::m_warpWithTimewarpVertexShaderSource( + "#version 110\n" + + "uniform vec2 EyeToSourceUVScale;\n" + "uniform vec2 EyeToSourceUVOffset;\n" + "uniform mat4 EyeRotationStart;\n" + "uniform mat4 EyeRotationEnd;\n" + + "attribute vec2 Position;\n" + "attribute vec4 Color;\n" + "attribute vec2 TexCoord0;\n" + "attribute vec2 TexCoord1;\n" + "attribute vec2 TexCoord2;\n" + + "varying vec4 oColor;\n" + "varying vec2 oTexCoord0;\n" + "varying vec2 oTexCoord1;\n" + "varying vec2 oTexCoord2;\n" + + "void main()\n" + "{\n" + " gl_Position.x = Position.x;\n" + " gl_Position.y = Position.y;\n" + " gl_Position.z = 0.0;\n" + " gl_Position.w = 1.0;\n" + + " // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion).\n" + " // These are now real world vectors in direction(x, y, 1) relative to the eye of the HMD.\n" + " vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" + " vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 );\n" + " vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 );\n" + + " mat3 EyeRotation;\n" + " EyeRotation[0] = mix ( EyeRotationStart[0], EyeRotationEnd[0], Color.a ).xyz;\n" + " EyeRotation[1] = mix ( EyeRotationStart[1], EyeRotationEnd[1], Color.a ).xyz;\n" + " EyeRotation[2] = mix ( EyeRotationStart[2], EyeRotationEnd[2], Color.a ).xyz;\n" + " vec3 TransformedR = EyeRotation * TanEyeAngleR;\n" + " vec3 TransformedG = EyeRotation * TanEyeAngleG;\n" + " vec3 TransformedB = EyeRotation * TanEyeAngleB;\n" + + " // Project them back onto the Z=1 plane of the rendered images.\n" + " float RecipZR = 1.0 / TransformedR.z;\n" + " float RecipZG = 1.0 / TransformedG.z;\n" + " float RecipZB = 1.0 / TransformedB.z;\n" + " vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR );\n" + " vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG );\n" + " vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB );\n" + + " // These are now still in TanEyeAngle space.\n" + " // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye)\n" + " vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset;\n" + " oTexCoord0 = SrcCoordR;\n" + " oTexCoord0.y = 1.0-oTexCoord0.y;\n" + " oTexCoord1 = SrcCoordG;\n" + " oTexCoord1.y = 1.0-oTexCoord1.y;\n" + " oTexCoord2 = SrcCoordB;\n" + " oTexCoord2.y = 1.0-oTexCoord2.y;\n" + " oColor = vec4(Color.r, Color.r, Color.r, Color.r); // Used for vignette fade.\n" + "}\n" +); + +const std::string OculusDevice::m_warpFragmentShaderSource( + "#version 110\n" + " \n" + "uniform sampler2D Texture;\n" + " \n" + "varying vec4 oColor;\n" + "varying vec2 oTexCoord0;\n" + "varying vec2 oTexCoord1;\n" + "varying vec2 oTexCoord2;\n" + " \n" + "void main()\n" + "{\n" + " gl_FragColor.r = oColor.r * texture2D(Texture, oTexCoord0).r;\n" + " gl_FragColor.g = oColor.g * texture2D(Texture, oTexCoord1).g;\n" + " gl_FragColor.b = oColor.b * texture2D(Texture, oTexCoord2).b;\n" + " gl_FragColor.a = 1.0;\n" + "}\n" +); OculusDevice::OculusDevice(float nearClip, float farClip, bool useTimewarp) : m_hmdDevice(0), m_nearClip(nearClip), m_farClip(farClip), @@ -393,14 +508,14 @@ osg::Program* OculusDevice::createShaderProgram() const { osg::ref_ptr vertexShader = new osg::Shader(osg::Shader::VERTEX); if (m_useTimeWarp) { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh_with_timewarp.vert")); + vertexShader->setShaderSource(m_warpWithTimewarpVertexShaderSource); } else { - vertexShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.vert")); + vertexShader->setShaderSource(m_warpVertexShaderSource); } osg::ref_ptr fragmentShader = new osg::Shader(osg::Shader::FRAGMENT); - fragmentShader->loadShaderSourceFromFile(osgDB::findDataFile("warp_mesh.frag")); + fragmentShader->setShaderSource(m_warpFragmentShaderSource); program->addShader(vertexShader); program->addShader(fragmentShader); return program.release(); diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 639616e..888be5a 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -78,6 +78,10 @@ class OculusDevice : public osg::Referenced { void beginFrameTiming(unsigned int frameIndex = 0); void endFrameTiming() const; void waitTillTime(); + + static const std::string m_warpVertexShaderSource; + static const std::string m_warpWithTimewarpVertexShaderSource; + static const std::string m_warpFragmentShaderSource; ovrHmd m_hmdDevice; ovrSizei m_resolution; diff --git a/src/warp_mesh.frag b/src/warp_mesh.frag deleted file mode 100644 index 60c0496..0000000 --- a/src/warp_mesh.frag +++ /dev/null @@ -1,16 +0,0 @@ -#version 110 - -uniform sampler2D Texture; - -varying vec4 oColor; -varying vec2 oTexCoord0; -varying vec2 oTexCoord1; -varying vec2 oTexCoord2; - -void main() -{ - gl_FragColor.r = oColor.r * texture2D(Texture, oTexCoord0).r; - gl_FragColor.g = oColor.g * texture2D(Texture, oTexCoord1).g; - gl_FragColor.b = oColor.b * texture2D(Texture, oTexCoord2).b; - gl_FragColor.a = 1.0; -} diff --git a/src/warp_mesh.vert b/src/warp_mesh.vert deleted file mode 100644 index 47746d5..0000000 --- a/src/warp_mesh.vert +++ /dev/null @@ -1,32 +0,0 @@ -#version 110 - -uniform vec2 EyeToSourceUVScale; -uniform vec2 EyeToSourceUVOffset; - -attribute vec2 Position; -attribute vec4 Color; -attribute vec2 TexCoord0; -attribute vec2 TexCoord1; -attribute vec2 TexCoord2; - -varying vec4 oColor; -varying vec2 oTexCoord0; -varying vec2 oTexCoord1; -varying vec2 oTexCoord2; - -void main() -{ - gl_Position.x = Position.x; - gl_Position.y = Position.y; - gl_Position.z = 0.5; - gl_Position.w = 1.0; - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset; - oTexCoord0.y = 1.0-oTexCoord0.y; - oTexCoord1 = TexCoord1 * EyeToSourceUVScale + EyeToSourceUVOffset; - oTexCoord1.y = 1.0-oTexCoord1.y; - oTexCoord2 = TexCoord2 * EyeToSourceUVScale + EyeToSourceUVOffset; - oTexCoord2.y = 1.0-oTexCoord2.y; - oColor = Color; // Used for vignette fade. -} \ No newline at end of file diff --git a/src/warp_mesh_with_timewarp.vert b/src/warp_mesh_with_timewarp.vert deleted file mode 100644 index 9a40d6f..0000000 --- a/src/warp_mesh_with_timewarp.vert +++ /dev/null @@ -1,60 +0,0 @@ -#version 110 - -uniform vec2 EyeToSourceUVScale; -uniform vec2 EyeToSourceUVOffset; -uniform mat4 EyeRotationStart; -uniform mat4 EyeRotationEnd; - -attribute vec2 Position; -attribute vec4 Color; -attribute vec2 TexCoord0; -attribute vec2 TexCoord1; -attribute vec2 TexCoord2; - -varying vec4 oColor; -varying vec2 oTexCoord0; -varying vec2 oTexCoord1; -varying vec2 oTexCoord2; - -void main() -{ - gl_Position.x = Position.x; - gl_Position.y = Position.y; - gl_Position.z = 0.0; - gl_Position.w = 1.0; - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are nowreal world" vectors in direction (x,y,1) relative to the eye of the HMD. - vec3 TanEyeAngleR = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 ); - vec3 TanEyeAngleG = vec3 ( TexCoord1.x, TexCoord1.y, 1.0 ); - vec3 TanEyeAngleB = vec3 ( TexCoord2.x, TexCoord2.y, 1.0 ); - - mat3 EyeRotation; - EyeRotation[0] = mix ( EyeRotationStart[0], EyeRotationEnd[0], Color.a ).xyz; - EyeRotation[1] = mix ( EyeRotationStart[1], EyeRotationEnd[1], Color.a ).xyz; - EyeRotation[2] = mix ( EyeRotationStart[2], EyeRotationEnd[2], Color.a ).xyz; - vec3 TransformedR = EyeRotation * TanEyeAngleR; - vec3 TransformedG = EyeRotation * TanEyeAngleG; - vec3 TransformedB = EyeRotation * TanEyeAngleB; - - // Project them back onto the Z=1 plane of the rendered images. - float RecipZR = 1.0 / TransformedR.z; - float RecipZG = 1.0 / TransformedG.z; - float RecipZB = 1.0 / TransformedB.z; - vec2 FlattenedR = vec2 ( TransformedR.x * RecipZR, TransformedR.y * RecipZR ); - vec2 FlattenedG = vec2 ( TransformedG.x * RecipZG, TransformedG.y * RecipZG ); - vec2 FlattenedB = vec2 ( TransformedB.x * RecipZB, TransformedB.y * RecipZB ); - - // These are now still in TanEyeAngle space. - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - vec2 SrcCoordR = FlattenedR * EyeToSourceUVScale + EyeToSourceUVOffset; - vec2 SrcCoordG = FlattenedG * EyeToSourceUVScale + EyeToSourceUVOffset; - vec2 SrcCoordB = FlattenedB * EyeToSourceUVScale + EyeToSourceUVOffset; - oTexCoord0 = SrcCoordR; - oTexCoord0.y = 1.0-oTexCoord0.y; - oTexCoord1 = SrcCoordG; - oTexCoord1.y = 1.0-oTexCoord1.y; - oTexCoord2 = SrcCoordB; - oTexCoord2.y = 1.0-oTexCoord2.y; - oColor = vec4(Color.r, Color.r, Color.r, Color.r); // Used for vignette fade. -} \ No newline at end of file From fd4b58b5ba3aa9f24e46f1f0f597c47c6d863d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 22:46:26 +0200 Subject: [PATCH 45/51] Find Oculus SDK version in CMake module. --- cmake/FindOculusSDK.cmake | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmake/FindOculusSDK.cmake b/cmake/FindOculusSDK.cmake index 00c3493..12d6fa3 100644 --- a/cmake/FindOculusSDK.cmake +++ b/cmake/FindOculusSDK.cmake @@ -4,6 +4,7 @@ # OCULUS_SDK_INCLUDE_DIRS - where to find OVR.h, etc. # OCULUS_SDK_LIBRARIES - List of libraries when using OculusSDK. # OCULUS_SDK_FOUND - True if OculusSDK found. +# OCULUS_SDK_VERSION - Version of the OculusSDK if found IF (DEFINED ENV{OCULUS_SDK_ROOT_DIR}) SET(OCULUS_SDK_ROOT_DIR "$ENV{OCULUS_SDK_ROOT_DIR}") @@ -59,6 +60,22 @@ IF (MSVC) ENDIF() MARK_AS_ADVANCED(OCULUS_MSVC_DIR) +# Try to ascertain the version of the SDK +IF(OCULUS_SDK_INCLUDE_DIRS) + SET(_OCULUS_VERSION_FILE "${OCULUS_SDK_INCLUDE_DIRS}/OVR_Version.h") + + IF(EXISTS "${_OCULUS_VERSION_FILE}") + FILE(STRINGS "${_OCULUS_VERSION_FILE}" _OCULUS_VERSION_FILE_CONTENTS REGEX "#define OVR_[A-Z]+_VERSION[ \t]+[0-9]+") + + STRING(REGEX REPLACE ".*#define OVR_MAJOR_VERSION[ \t]+([0-9]+).*" "\\1" OCULUS_SDK_VERSION_MAJOR ${_OCULUS_VERSION_FILE_CONTENTS}) + STRING(REGEX REPLACE ".*#define OVR_MINOR_VERSION[ \t]+([0-9]+).*" "\\1" OCULUS_SDK_VERSION_MINOR ${_OCULUS_VERSION_FILE_CONTENTS}) + STRING(REGEX REPLACE ".*#define OVR_BUILD_VERSION[ \t]+([0-9]+).*" "\\1" OCULUS_SDK_VERSION_BUILD ${_OCULUS_VERSION_FILE_CONTENTS}) + + SET(OCULUS_SDK_VERSION "${OCULUS_SDK_VERSION_MAJOR}.${OCULUS_SDK_VERSION_MINOR}.${OCULUS_SDK_VERSION_BUILD}" CACHE INTERNAL "The version of Oculus SDK which was detected") + ENDIF() +ENDIF() + + # Look for the library. FIND_LIBRARY(OCULUS_SDK_LIBRARY NAMES libovr libovr64 ovr HINTS ${OCULUS_SDK_ROOT_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} From 903a56464b56e2a899d8e9172564ff376dd5b0fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 23:27:21 +0200 Subject: [PATCH 46/51] Added install script and included CPack --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6f069c8..802ff4e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ ENDIF() OPTION(CMAKE_USE_RELATIVE_PATHS "If true, cmake will use relative paths in makefiles and projects." ${DEFAULT_RELATIVE_PATHS}) MARK_AS_ADVANCED(CMAKE_USE_RELATIVE_PATHS) -# Build example viewer +# Build example viewers OPTION(BUILD_EXAMPLES "Enable to build viewer examples" ON) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 220b5c6..2164a40 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -121,7 +121,39 @@ IF(MSVC) IF (USE_VIEW_CONFIG) CONFIGURE_FILE(osgoculusviewer.vcxproj.template ${TARGET_TARGETNAME_VIEW_CONFIG}.vcxproj.user @ONLY) ENDIF() - ENDIF() + ENDIF (OPENSCENEGRAPH_FOUND) ENDIF(MSVC) + +#################################################################### +# Install library +##################################################################### + +INSTALL(FILES ${TARGET_H} DESTINATION include) + +INSTALL(TARGETS ${TARGET_LIBRARYNAME} ${TARGET_TARGETNAME} + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib + RUNTIME DESTINATION bin +) + +INSTALL(FILES "${PROJECT_SOURCE_DIR}/license.txt" DESTINATION .) +INSTALL(FILES "${PROJECT_SOURCE_DIR}/README.md" DESTINATION . RENAME readme.txt) + +SET(CPACK_PACKAGE_NAME "${TARGET_LIBRARYNAME}-SDK-v") +SET(CPACK_PACKAGE_VERSION_MAJOR "${OCULUS_SDK_VERSION_MAJOR}") +SET(CPACK_PACKAGE_VERSION_MINOR "${OCULUS_SDK_VERSION_MINOR}") +SET(CPACK_PACKAGE_VERSION_PATCH "${OCULUS_SDK_VERSION_BUILD}") +SET(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README.md") +SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/license.txt") + + +IF(WIN32) + SET(CPACK_GENERATOR "ZIP") +ELSEIF(UNIX) + SET(CPACK_GENERATOR "TGZ;TBZ2;TZ") +ENDIF() + +# Pack files to package +INCLUDE(CPack) From af959ce9bdc2670ea5a3c0cd809f08336b81e7e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sat, 16 Aug 2014 23:46:14 +0200 Subject: [PATCH 47/51] Pass near clip, far clip and time warp properties from viewers. --- src/compositeviewerexample.cpp | 5 ++++- src/oculusviewconfig.h | 4 ++-- src/viewconfigexample.cpp | 5 ++++- src/viewerexample.cpp | 5 ++++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index 1ae5831..505b7da 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -15,7 +15,10 @@ int main( int argc, char** argv ) { - osg::ref_ptr oculusDevice = new OculusDevice(0.01f, 10000.0, true); + float nearClip = 0.01f; + float farClip = 10000.0f; + bool useTimewarp = true; + osg::ref_ptr oculusDevice = new OculusDevice(nearClip, farClip, useTimewarp); // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); // read the scene from the list of file specified command line arguments. diff --git a/src/oculusviewconfig.h b/src/oculusviewconfig.h index 39b5890..f265f82 100644 --- a/src/oculusviewconfig.h +++ b/src/oculusviewconfig.h @@ -13,11 +13,11 @@ class OculusViewConfig : public osgViewer::ViewConfig { public: - OculusViewConfig() : osgViewer::ViewConfig(), + OculusViewConfig(float nearClip=0.01f, float farClip=10000.0f, bool useTimewarp=true) : osgViewer::ViewConfig(), m_configured(false), m_sceneNodeMask(0x1), m_device(0) { - m_device = new OculusDevice(0.01f, 10000.0f, true); + m_device = new OculusDevice(nearClip, farClip, useTimewarp); } void setSceneNodeMask(osg::Node::NodeMask nodeMask) { m_sceneNodeMask = nodeMask; } virtual void configure(osgViewer::View& view) const; diff --git a/src/viewconfigexample.cpp b/src/viewconfigexample.cpp index e56bf6f..c8176f6 100644 --- a/src/viewconfigexample.cpp +++ b/src/viewconfigexample.cpp @@ -29,7 +29,10 @@ int main( int argc, char** argv ) loadedModel->setNodeMask(sceneNodeMask); // Create Oculus View Config - osg::ref_ptr oculusViewConfig = new OculusViewConfig; + float nearClip = 0.01f; + float farClip = 10000.0f; + bool useTimewarp = true; + osg::ref_ptr oculusViewConfig = new OculusViewConfig(nearClip, farClip, useTimewarp); // Set the node mask used for scene oculusViewConfig->setSceneNodeMask(sceneNodeMask); // Create viewer diff --git a/src/viewerexample.cpp b/src/viewerexample.cpp index 6ebf8e8..a4b4c4a 100644 --- a/src/viewerexample.cpp +++ b/src/viewerexample.cpp @@ -35,7 +35,10 @@ int main( int argc, char** argv ) } // Open the HMD - osg::ref_ptr oculusDevice = new OculusDevice(0.01f, 10000.0f, true); + float nearClip = 0.01f; + float farClip = 10000.0f; + bool useTimewarp = true; + osg::ref_ptr oculusDevice = new OculusDevice(nearClip, farClip, useTimewarp); // Get the suggested context traits osg::ref_ptr traits = oculusDevice->graphicsContextTraits(); From bcf634fe9e5dcc1348dfe415a3739cb704b64f6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Sun, 17 Aug 2014 01:12:23 +0200 Subject: [PATCH 48/51] License information added. --- README.md | 2 ++ cmake/FindOculusSDK.cmake | 32 ++++++++++++++++++-------------- src/CMakeLists.txt | 3 ++- 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8128a59..0165f4d 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ License Source code is licensed according to the 3-clause license BSD-license. See license.txt for complete licensing information. +**NOTE** By linking to the Oculus SDK libraries you must adhere to the terms of the Oculus SDK License Agreement. + Contributors ------------ diff --git a/cmake/FindOculusSDK.cmake b/cmake/FindOculusSDK.cmake index 12d6fa3..22d44b1 100644 --- a/cmake/FindOculusSDK.cmake +++ b/cmake/FindOculusSDK.cmake @@ -22,21 +22,21 @@ FIND_PATH(OCULUS_SDK_INCLUDE_DIRS NAMES OVR.h HINTS # Determine architecture IF(CMAKE_SIZEOF_VOID_P MATCHES "8") IF(UNIX) - SET(OCULUS_SDK_LIB_ARCH "x86_64" CACHE STRING "library location") + SET(_OCULUS_SDK_LIB_ARCH "x86_64") ENDIF() IF(MSVC) - SET(OCULUS_SDK_LIB_ARCH "x64" CACHE STRING "library location") + SET(_OCULUS_SDK_LIB_ARCH "x64") ENDIF() ELSE() IF(UNIX) - SET(OCULUS_SDK_LIB_ARCH "i386" CACHE STRING "library location") + SET(_OCULUS_SDK_LIB_ARCH "i386") ENDIF() IF(MSVC) - SET(OCULUS_SDK_LIB_ARCH "Win32" CACHE STRING "library location") + SET(_OCULUS_SDK_LIB_ARCH "Win32") ENDIF() ENDIF() -MARK_AS_ADVANCED(OCULUS_SDK_LIB_ARCH) +MARK_AS_ADVANCED(_OCULUS_SDK_LIB_ARCH) # Append "d" to debug libs on windows platform IF (WIN32) @@ -47,18 +47,17 @@ ENDIF() IF (MSVC) # Visual Studio 2010 IF(MSVC10) - SET(OCULUS_MSVC_DIR "VS2010" CACHE STRING "library location") + SET(_OCULUS_MSVC_DIR "VS2010") ENDIF() # Visual Studio 2012 IF(MSVC11) - SET(OCULUS_MSVC_DIR "VS2012" CACHE STRING "library location") + SET(_OCULUS_MSVC_DIR "VS2012") ENDIF() # Visual Studio 2013 IF(MSVC12) - SET(OCULUS_MSVC_DIR "VS2013" CACHE STRING "library location") + SET(_OCULUS_MSVC_DIR "VS2013") ENDIF() ENDIF() -MARK_AS_ADVANCED(OCULUS_MSVC_DIR) # Try to ascertain the version of the SDK IF(OCULUS_SDK_INCLUDE_DIRS) @@ -75,22 +74,27 @@ IF(OCULUS_SDK_INCLUDE_DIRS) ENDIF() ENDIF() +# Locate Oculus license file +SET(_OCULUS_SDK_LICENSE_FILE "${OCULUS_SDK_ROOT_DIR}/LICENSE.txt") +IF(EXISTS "${_OCULUS_SDK_LICENSE_FILE}") + SET(OCULUS_SDK_LICENSE_FILE "${_OCULUS_SDK_LICENSE_FILE}" CACHE INTERNAL "The location of the Oculus SDK license file") +ENDIF() # Look for the library. FIND_LIBRARY(OCULUS_SDK_LIBRARY NAMES libovr libovr64 ovr HINTS ${OCULUS_SDK_ROOT_DIR} - ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${_OCULUS_SDK_LIB_ARCH}/${_OCULUS_MSVC_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Mac/Release - ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${_OCULUS_SDK_LIB_ARCH} ) # This will find release lib on Linux if no debug is available - on Linux this is no problem and avoids # having to compile in debug when not needed FIND_LIBRARY(OCULUS_SDK_LIBRARY_DEBUG NAMES libovr${CMAKE_DEBUG_POSTFIX} libovr64${CMAKE_DEBUG_POSTFIX} ovr${CMAKE_DEBUG_POSTFIX} ovr libovr HINTS - ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${OCULUS_SDK_LIB_ARCH}/${OCULUS_MSVC_DIR} + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/${_OCULUS_SDK_LIB_ARCH}/${_OCULUS_MSVC_DIR} ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Mac/Debug ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Mac/Release - ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Debug/${OCULUS_SDK_LIB_ARCH} - ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${OCULUS_SDK_LIB_ARCH} + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Debug/${_OCULUS_SDK_LIB_ARCH} + ${OCULUS_SDK_ROOT_DIR}/LibOVR/Lib/Linux/Release/${_OCULUS_SDK_LIB_ARCH} ) MARK_AS_ADVANCED(OCULUS_SDK_LIBRARY) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2164a40..56d28f9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -138,8 +138,9 @@ INSTALL(TARGETS ${TARGET_LIBRARYNAME} ${TARGET_TARGETNAME} RUNTIME DESTINATION bin ) -INSTALL(FILES "${PROJECT_SOURCE_DIR}/license.txt" DESTINATION .) INSTALL(FILES "${PROJECT_SOURCE_DIR}/README.md" DESTINATION . RENAME readme.txt) +INSTALL(FILES "${PROJECT_SOURCE_DIR}/license.txt" DESTINATION . RENAME license_osgoculus.txt) +INSTALL(FILES ${OCULUS_SDK_LICENSE_FILE} DESTINATION . RENAME license_oculus.txt) SET(CPACK_PACKAGE_NAME "${TARGET_LIBRARYNAME}-SDK-v") SET(CPACK_PACKAGE_VERSION_MAJOR "${OCULUS_SDK_VERSION_MAJOR}") From a98c918d89140c43e3bd26b9f18b144089e3b0c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Sj=C3=B6lie?= Date: Mon, 18 Aug 2014 12:27:01 +0200 Subject: [PATCH 49/51] Install new example binaries. --- src/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 56d28f9..c94f371 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,9 +80,12 @@ IF(BUILD_EXAMPLES) ADD_EXECUTABLE(${TARGET_TARGETNAME_COMPOSITE_VIEWER} compositeviewerexample.cpp) TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME_COMPOSITE_VIEWER} ${TARGET_LIBRARYNAME}) + INSTALL(TARGETS ${TARGET_TARGETNAME_VIEWER} ${TARGET_TARGETNAME_COMPOSITE_VIEWER} RUNTIME DESTINATION bin) + IF (USE_VIEW_CONFIG) ADD_EXECUTABLE(${TARGET_TARGETNAME_VIEW_CONFIG} viewconfigexample.cpp) TARGET_LINK_LIBRARIES(${TARGET_TARGETNAME_VIEW_CONFIG} ${TARGET_LIBRARYNAME}) + INSTALL(TARGETS ${TARGET_TARGETNAME_VIEW_CONFIG} RUNTIME DESTINATION bin) ENDIF() ENDIF(BUILD_EXAMPLES) @@ -132,10 +135,9 @@ ENDIF(MSVC) INSTALL(FILES ${TARGET_H} DESTINATION include) -INSTALL(TARGETS ${TARGET_LIBRARYNAME} ${TARGET_TARGETNAME} +INSTALL(TARGETS ${TARGET_LIBRARYNAME} LIBRARY DESTINATION lib ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin ) INSTALL(FILES "${PROJECT_SOURCE_DIR}/README.md" DESTINATION . RENAME readme.txt) From b4a5bc6e60bfd4b245c8bbcc37fe8018b01486c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Mon, 18 Aug 2014 12:41:57 +0200 Subject: [PATCH 50/51] Changed enum to support pre-C++11 compilers. --- src/compositeviewerexample.cpp | 8 ++++---- src/oculusviewconfig.cpp | 4 ++-- src/oculusviewer.cpp | 12 ++++++------ 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/compositeviewerexample.cpp b/src/compositeviewerexample.cpp index 505b7da..c06f517 100644 --- a/src/compositeviewerexample.cpp +++ b/src/compositeviewerexample.cpp @@ -55,9 +55,9 @@ int main( int argc, char** argv ) osg::ref_ptr program = oculusDevice->createShaderProgram(); // Create distortionMesh for each camera - osg::ref_ptr leftDistortionMesh = oculusDevice->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight, true); + osg::ref_ptr leftDistortionMesh = oculusDevice->distortionMesh(OculusDevice::LEFT, program, 0, 0, textureWidth, textureHeight, true); leftCameraWarp->addChild(leftDistortionMesh); - osg::ref_ptr rightDistortionMesh = oculusDevice->distortionMesh(OculusDevice::Eye::RIGHT, program, 0, 0, textureWidth, textureHeight, true); + osg::ref_ptr rightDistortionMesh = oculusDevice->distortionMesh(OculusDevice::RIGHT, program, 0, 0, textureWidth, textureHeight, true); rightCameraWarp->addChild(rightDistortionMesh); // Add pre draw camera to handle time warp @@ -68,8 +68,8 @@ int main( int argc, char** argv ) osg::ref_ptr leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); osg::ref_ptr rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); - oculusDevice->applyShaderParameters(leftEyeStateSet, program, textureLeft, OculusDevice::Eye::LEFT); - oculusDevice->applyShaderParameters(rightEyeStateSet, program, textureRight, OculusDevice::Eye::RIGHT); + oculusDevice->applyShaderParameters(leftEyeStateSet, program, textureLeft, OculusDevice::LEFT); + oculusDevice->applyShaderParameters(rightEyeStateSet, program, textureRight, OculusDevice::RIGHT); // Create Trackball manipulator osg::ref_ptr cameraManipulator = new osgGA::TrackballManipulator; diff --git a/src/oculusviewconfig.cpp b/src/oculusviewconfig.cpp index 3d73c76..e2be9c3 100644 --- a/src/oculusviewconfig.cpp +++ b/src/oculusviewconfig.cpp @@ -43,8 +43,8 @@ void OculusViewConfig::configure(osgViewer::View& view) const textureRight->setTextureSize( textureWidth, textureHeight ); textureRight->setInternalFormat( GL_RGBA ); // Create RTT cameras and attach textures - osg::ref_ptr cameraRTTLeft = m_device->createRTTCamera(textureLeft, OculusDevice::Eye::LEFT, osg::Camera::RELATIVE_RF, gc); - osg::ref_ptr cameraRTTRight = m_device->createRTTCamera(textureRight, OculusDevice::Eye::RIGHT, osg::Camera::RELATIVE_RF, gc); + osg::ref_ptr cameraRTTLeft = m_device->createRTTCamera(textureLeft, OculusDevice::LEFT, osg::Camera::RELATIVE_RF, gc); + osg::ref_ptr cameraRTTRight = m_device->createRTTCamera(textureRight, OculusDevice::RIGHT, osg::Camera::RELATIVE_RF, gc); cameraRTTLeft->setName("LeftRTT"); cameraRTTRight->setName("RightRTT"); cameraRTTLeft->setCullMask(m_sceneNodeMask); diff --git a/src/oculusviewer.cpp b/src/oculusviewer.cpp index 4df95ae..cc85f1a 100644 --- a/src/oculusviewer.cpp +++ b/src/oculusviewer.cpp @@ -59,8 +59,8 @@ void OculusViewer::configure() textureRight->setTextureSize(textureWidth, textureHeight); textureRight->setInternalFormat(GL_RGBA); // Create RTT cameras and attach textures - m_cameraRTTLeft = m_device->createRTTCamera(textureLeft, OculusDevice::Eye::LEFT, osg::Camera::RELATIVE_RF, gc); - m_cameraRTTRight = m_device->createRTTCamera(textureRight, OculusDevice::Eye::RIGHT, osg::Camera::RELATIVE_RF, gc); + m_cameraRTTLeft = m_device->createRTTCamera(textureLeft, OculusDevice::LEFT, osg::Camera::RELATIVE_RF, gc); + m_cameraRTTRight = m_device->createRTTCamera(textureRight, OculusDevice::RIGHT, osg::Camera::RELATIVE_RF, gc); m_cameraRTTLeft->setName("LeftRTT"); m_cameraRTTRight->setName("RightRTT"); m_cameraRTTLeft->setCullMask(m_sceneNodeMask); @@ -75,10 +75,10 @@ void OculusViewer::configure() osg::ref_ptr program = m_device->createShaderProgram(); // Create distortionMesh for each camera - osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::LEFT, program, 0, 0, textureWidth, textureHeight); + osg::ref_ptr leftDistortionMesh = m_device->distortionMesh(OculusDevice::LEFT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(leftDistortionMesh); - osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::Eye::RIGHT, program, 0, 0, textureWidth, textureHeight); + osg::ref_ptr rightDistortionMesh = m_device->distortionMesh(OculusDevice::RIGHT, program, 0, 0, textureWidth, textureHeight); cameraWarp->addChild(rightDistortionMesh); // Add pre draw camera to handle time warp @@ -88,8 +88,8 @@ void OculusViewer::configure() osg::StateSet* leftEyeStateSet = leftDistortionMesh->getOrCreateStateSet(); osg::StateSet* rightEyeStateSet = rightDistortionMesh->getOrCreateStateSet(); - m_device->applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::Eye::LEFT); - m_device->applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::Eye::RIGHT); + m_device->applyShaderParameters(leftEyeStateSet, program.get(), textureLeft.get(), OculusDevice::LEFT); + m_device->applyShaderParameters(rightEyeStateSet, program.get(), textureRight.get(), OculusDevice::RIGHT); // Add RTT cameras as slaves, specifying offsets for the projection m_view->addSlave(m_cameraRTTLeft.get(), From f925a4e314e8333d9d996adfc3e32e4f97f6e697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Blissing?= Date: Mon, 18 Aug 2014 12:42:29 +0200 Subject: [PATCH 51/51] Use const reference instead of pass by value. --- src/oculusdevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/oculusdevice.h b/src/oculusdevice.h index 888be5a..178955e 100644 --- a/src/oculusdevice.h +++ b/src/oculusdevice.h @@ -135,7 +135,7 @@ class EyeRotationCallback : public osg::Uniform::Callback START, END }; - EyeRotationCallback(const Mode mode, const OculusDevice* device, const OculusDevice::Eye eye) : m_mode(mode), m_device(device), m_eye(eye) {} + EyeRotationCallback(const Mode mode, const OculusDevice* device, const OculusDevice::Eye& eye) : m_mode(mode), m_device(device), m_eye(eye) {} virtual void operator() (osg::Uniform* uniform, osg::NodeVisitor* nv); protected: const Mode m_mode;