From 0488b706b23010a5142f0cb2921a89cd22ae7d20 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 4 Aug 2014 18:30:25 +0200 Subject: [PATCH] Add placeholders for LibOVR 0.4.0 support --HG-- branch : multipass-stereo --- code/nel/include/nel/3d/stereo_ovr.h | 2 +- code/nel/include/nel/3d/stereo_ovr_04.h | 185 +++++ code/nel/src/3d/CMakeLists.txt | 8 + code/nel/src/3d/stereo_debugger.cpp | 2 +- code/nel/src/3d/stereo_display.cpp | 9 +- code/nel/src/3d/stereo_hmd.cpp | 2 +- code/nel/src/3d/stereo_libvr.cpp | 2 +- code/nel/src/3d/stereo_ovr.cpp | 5 +- code/nel/src/3d/stereo_ovr_04.cpp | 1015 +++++++++++++++++++++++ code/nel/src/3d/stereo_ovr_04_program.h | 249 ++++++ code/nel/src/3d/stereo_ovr_fp.cpp | 2 + 11 files changed, 1471 insertions(+), 10 deletions(-) create mode 100644 code/nel/include/nel/3d/stereo_ovr_04.h create mode 100644 code/nel/src/3d/stereo_ovr_04.cpp create mode 100644 code/nel/src/3d/stereo_ovr_04_program.h diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index a215ff8b6..750f32027 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -44,7 +44,7 @@ #ifndef NL3D_STEREO_OVR_H #define NL3D_STEREO_OVR_H -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 #include diff --git a/code/nel/include/nel/3d/stereo_ovr_04.h b/code/nel/include/nel/3d/stereo_ovr_04.h new file mode 100644 index 000000000..d58698066 --- /dev/null +++ b/code/nel/include/nel/3d/stereo_ovr_04.h @@ -0,0 +1,185 @@ +/** + * \file stereo_ovr.h + * \brief CStereoOVR + * \date 2014-08-04 16:21GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2014 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#ifndef NL3D_STEREO_OVR_H +#define NL3D_STEREO_OVR_H + +#ifdef HAVE_LIBOVR + +#include + +// STL includes + +// NeL includes +#include +#include + +// Project includes +#include +#include +#include +#include + +namespace NL3D { + +class ITexture; +class CTextureUser; +class CStereoOVRDevicePtr; +class CStereoOVRDeviceHandle; +/*class CPixelProgramOVR;*/ + +#define NL_STEREO_MAX_USER_CAMERAS 8 + +/** + * \brief CStereoOVR + * \date 2014-08-04 16:21GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ +class CStereoOVR : public IStereoHMD +{ +public: + CStereoOVR(const CStereoOVRDeviceHandle *handle); + virtual ~CStereoOVR(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver *driver); + + /// Gets the required screen resolution for this device + virtual bool getScreenResolution(uint &width, uint &height); + /// Set latest camera position etcetera + virtual void updateCamera(uint cid, const NL3D::UCamera *camera); + /// Get the frustum to use for clipping + virtual void getClippingFrustum(uint cid, NL3D::UCamera *camera) const; + /// Get the original frustum of the camera + virtual void getOriginalFrustum(uint cid, NL3D::UCamera *camera) const; + + /// Is there a next pass + virtual bool nextPass(); + /// Gets the current viewport + virtual const NL3D::CViewport &getCurrentViewport() const; + /// Gets the current camera frustum + virtual const NL3D::CFrustum &getCurrentFrustum(uint cid) const; + /// Gets the current camera frustum + virtual void getCurrentFrustum(uint cid, NL3D::UCamera *camera) const; + /// Gets the current camera matrix + virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; + + /// At the start of a new render target + virtual bool wantClear(); + /// The 3D scene + virtual bool wantScene(); + /// Interface within the 3D scene + virtual bool wantInterface3D(); + /// 2D Interface + virtual bool wantInterface2D(); + + /// Returns true if a new render target was set, always fase if not using render targets + virtual bool beginRenderTarget(); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(); + + + /// Get the HMD orientation + virtual NLMISC::CQuat getOrientation() const; + + /// Set the GUI reference + virtual void setInterfaceMatrix(const NL3D::CMatrix &matrix); + + /// Get GUI center (1 = width, 1 = height, 0 = center) + virtual void getInterface2DShift(uint cid, float &x, float &y, float distance) const; + + /// Set the head model, eye position relative to orientation point + virtual void setEyePosition(const NLMISC::CVector &v); + /// Get the head model, eye position relative to orientation point + virtual const NLMISC::CVector &getEyePosition() const; + + /// Set the scale of the game in units per meter + virtual void setScale(float s); + + /// Calculates internal camera information based on the reference camera + void initCamera(uint cid, const NL3D::UCamera *camera); + /// Render GUI + void renderGUI(); + + /// Checks if the device used by this class was actually created + bool isDeviceCreated(); + + static void listDevices(std::vector &devicesOut); + static bool isLibraryInUse(); + static void releaseLibrary(); + +private: + CStereoOVRDevicePtr *m_DevicePtr; + int m_Stage; + int m_SubStage; + CViewport m_RegularViewport; + CViewport m_LeftViewport; + CViewport m_RightViewport; + CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_LeftFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_RightFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CFrustum m_OriginalFrustum[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_CameraMatrix[NL_STEREO_MAX_USER_CAMERAS]; + CMatrix m_InterfaceCameraMatrix; + mutable bool m_OrientationCached; + mutable NLMISC::CQuat m_OrientationCache; + UDriver *m_Driver; + NL3D::CTextureUser *m_GUITexture; + /*NL3D::CTextureUser *m_SceneTexture; + NL3D::UMaterial m_BarrelMat; + NLMISC::CQuadUV m_BarrelQuadLeft; + NLMISC::CQuadUV m_BarrelQuadRight; + NLMISC::CRefPtr m_PixelProgram;*/ + NLMISC::CVector m_EyePosition; + float m_Scale; + +}; /* class CStereoOVR */ + +} /* namespace NL3D */ + +#endif /* HAVE_LIBOVR */ + +#endif /* #ifndef NL3D_STEREO_OVR_H */ + +/* end of file */ diff --git a/code/nel/src/3d/CMakeLists.txt b/code/nel/src/3d/CMakeLists.txt index fff343915..21184eb12 100644 --- a/code/nel/src/3d/CMakeLists.txt +++ b/code/nel/src/3d/CMakeLists.txt @@ -562,8 +562,13 @@ SOURCE_GROUP(Fx\\Particles\\lights FILES ps_light.cpp ../../include/nel/3d/ps_light.h) SOURCE_GROUP(Fx\\2d FILES + render_target_manager.cpp + ../../include/nel/3d/render_target_manager.h bloom_effect.cpp ../../include/nel/3d/bloom_effect.h + fxaa.cpp + fxaa_program.h + ../../include/nel/3d/fxaa.h deform_2d.cpp ../../include/nel/3d/deform_2d.h heat_haze.cpp @@ -700,6 +705,9 @@ SOURCE_GROUP(Stereo FILES stereo_ovr.cpp stereo_ovr_fp.cpp ../../include/nel/3d/stereo_ovr.h + stereo_ovr_04.cpp + stereo_ovr_04_program.h + ../../include/nel/3d/stereo_ovr_04.h stereo_libvr.cpp ../../include/nel/3d/stereo_libvr.h stereo_debugger.cpp diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 3a3144113..89ca605d0 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -26,7 +26,7 @@ */ #if !FINAL_VERSION -#include +#include "std3d.h" #include // STL includes diff --git a/code/nel/src/3d/stereo_display.cpp b/code/nel/src/3d/stereo_display.cpp index eace867fc..2ef8dca17 100644 --- a/code/nel/src/3d/stereo_display.cpp +++ b/code/nel/src/3d/stereo_display.cpp @@ -25,7 +25,7 @@ * . */ -#include +#include "std3d.h" #include // STL includes @@ -35,6 +35,7 @@ // Project includes #include +#include #include #include @@ -76,7 +77,7 @@ const char *IStereoDisplay::getLibraryName(CStereoDeviceInfo::TStereoDeviceLibra void IStereoDisplay::listDevices(std::vector &devicesOut) { -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 CStereoOVR::listDevices(devicesOut); #endif #ifdef HAVE_LIBVR @@ -94,7 +95,7 @@ IStereoDisplay *IStereoDisplay::createDevice(const CStereoDeviceInfo &deviceInfo void IStereoDisplay::releaseUnusedLibraries() { -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 if (!CStereoOVR::isLibraryInUse()) CStereoOVR::releaseLibrary(); #endif @@ -102,7 +103,7 @@ void IStereoDisplay::releaseUnusedLibraries() void IStereoDisplay::releaseAllLibraries() { -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 CStereoOVR::releaseLibrary(); #endif } diff --git a/code/nel/src/3d/stereo_hmd.cpp b/code/nel/src/3d/stereo_hmd.cpp index d28017482..25249e2b4 100644 --- a/code/nel/src/3d/stereo_hmd.cpp +++ b/code/nel/src/3d/stereo_hmd.cpp @@ -25,7 +25,7 @@ * . */ -#include +#include "std3d.h" #include // STL includes diff --git a/code/nel/src/3d/stereo_libvr.cpp b/code/nel/src/3d/stereo_libvr.cpp index 44a5a0a5a..c655f959c 100644 --- a/code/nel/src/3d/stereo_libvr.cpp +++ b/code/nel/src/3d/stereo_libvr.cpp @@ -27,7 +27,7 @@ #ifdef HAVE_LIBVR -#include +#include "std3d.h" #include #include diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 8b8f8a90a..073490dc0 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -41,15 +41,16 @@ * so, delete this exception statement from your version. */ -#ifdef HAVE_LIBOVR +#ifdef HAVE_LIBOVR_02 -#include +#include "std3d.h" #include // STL includes #include // External includes +#define OVR_NO_STDINT #include // NeL includes diff --git a/code/nel/src/3d/stereo_ovr_04.cpp b/code/nel/src/3d/stereo_ovr_04.cpp new file mode 100644 index 000000000..5751af285 --- /dev/null +++ b/code/nel/src/3d/stereo_ovr_04.cpp @@ -0,0 +1,1015 @@ +/** + * \file stereo_ovr.cpp + * \brief CStereoOVR + * \date 2014-08-04 16:21GMT + * \author Jan Boon (Kaetemi) + * CStereoOVR + */ + +/* + * Copyright (C) 2014 by authors + * + * This file is part of NL3D. + * NL3D is free software: you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * NL3D is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General + * Public License for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with NL3D. If not, see + * . + * + * Linking this library statically or dynamically with other modules + * is making a combined work based on this library. Thus, the terms + * and conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give + * you permission to link this library with the Oculus SDK to produce + * an executable, regardless of the license terms of the Oculus SDK, + * and distribute linked combinations including the two, provided that + * you also meet the terms and conditions of the license of the Oculus + * SDK. You must obey the GNU General Public License in all respects + * for all of the code used other than the Oculus SDK. If you modify + * this file, you may extend this exception to your version of the + * file, but you are not obligated to do so. If you do not wish to do + * so, delete this exception statement from your version. + */ + +#ifdef HAVE_LIBOVR + +#include "std3d.h" +#include + +// STL includes +#include + +// External includes +#define OVR_NO_STDINT +#include + +// NeL includes +// #include +#include +#include +#include +#include +#include +#include +#include + +// Project includes + +using namespace std; +// using namespace NLMISC; + +namespace NL3D { + +/*extern const char *g_StereoOVR_fp40; +extern const char *g_StereoOVR_arbfp1; +extern const char *g_StereoOVR_ps_2_0; +extern const char *g_StereoOVR_glsl330f;*/ + +namespace { +/* +class CStereoOVRLog : public OVR::Log +{ +public: + CStereoOVRLog(unsigned logMask = OVR::LogMask_All) : OVR::Log(logMask) + { + + } + + virtual void LogMessageVarg(OVR::LogMessageType messageType, const char* fmt, va_list argList) + { + if (NLMISC::INelContext::isContextInitialised()) + { + char buffer[MaxLogBufferMessageSize]; + FormatLog(buffer, MaxLogBufferMessageSize, messageType, fmt, argList); + if (IsDebugMessage(messageType)) + NLMISC::INelContext::getInstance().getDebugLog()->displayNL("OVR: %s", buffer); + else + NLMISC::INelContext::getInstance().getInfoLog()->displayNL("OVR: %s", buffer); + } + } +}; + +CStereoOVRLog *s_StereoOVRLog = NULL; +OVR::Ptr s_DeviceManager; + +class CStereoOVRSystem +{ +public: + ~CStereoOVRSystem() + { + Release(); + } + + void Init() + { + if (!s_StereoOVRLog) + { + nldebug("Initialize OVR"); + s_StereoOVRLog = new CStereoOVRLog(); + } + if (!OVR::System::IsInitialized()) + OVR::System::Init(s_StereoOVRLog); + if (!s_DeviceManager) + s_DeviceManager = OVR::DeviceManager::Create(); + } + + void Release() + { + if (s_DeviceManager) + { + nldebug("Release OVR"); + s_DeviceManager->Release(); + } + s_DeviceManager.Clear(); + if (OVR::System::IsInitialized()) + OVR::System::Destroy(); + if (s_StereoOVRLog) + nldebug("Release OVR Ok"); + delete s_StereoOVRLog; + s_StereoOVRLog = NULL; + } +}; + +CStereoOVRSystem s_StereoOVRSystem; + +sint s_DeviceCounter = 0; +*/ +} +/* +class CStereoOVRDeviceHandle : public IStereoDeviceFactory +{ +public: + // fixme: virtual destructor??? + OVR::DeviceEnumerator DeviceHandle; + IStereoDisplay *createDevice() const + { + CStereoOVR *stereo = new CStereoOVR(this); + if (stereo->isDeviceCreated()) + return stereo; + delete stereo; + return NULL; + } +}; + +class CStereoOVRDevicePtr +{ +public: + OVR::Ptr HMDDevice; + OVR::Ptr SensorDevice; + OVR::SensorFusion SensorFusion; + OVR::HMDInfo HMDInfo; +}; +*/ +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), /*m_SceneTexture(NULL),*/ m_GUITexture(NULL), /*m_PixelProgram(NULL),*/ m_EyePosition(0.0f, 0.09f, 0.15f), m_Scale(1.0f) +{ + /*++s_DeviceCounter; + m_DevicePtr = new CStereoOVRDevicePtr(); + + OVR::DeviceEnumerator dh = handle->DeviceHandle; + m_DevicePtr->HMDDevice = dh.CreateDevice(); + + if (m_DevicePtr->HMDDevice) + { + m_DevicePtr->HMDDevice->GetDeviceInfo(&m_DevicePtr->HMDInfo); + nldebug("OVR: HScreenSize: %f, VScreenSize: %f", m_DevicePtr->HMDInfo.HScreenSize, m_DevicePtr->HMDInfo.VScreenSize); + nldebug("OVR: VScreenCenter: %f", m_DevicePtr->HMDInfo.VScreenCenter); + nldebug("OVR: EyeToScreenDistance: %f", m_DevicePtr->HMDInfo.EyeToScreenDistance); + nldebug("OVR: LensSeparationDistance: %f", m_DevicePtr->HMDInfo.LensSeparationDistance); + nldebug("OVR: InterpupillaryDistance: %f", m_DevicePtr->HMDInfo.InterpupillaryDistance); + nldebug("OVR: HResolution: %i, VResolution: %i", m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); + nldebug("OVR: DistortionK[0]: %f, DistortionK[1]: %f", m_DevicePtr->HMDInfo.DistortionK[0], m_DevicePtr->HMDInfo.DistortionK[1]); + nldebug("OVR: DistortionK[2]: %f, DistortionK[3]: %f", m_DevicePtr->HMDInfo.DistortionK[2], m_DevicePtr->HMDInfo.DistortionK[3]); + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 160 NL3D::CStereoOVR::CStereoOVR : OVR: HScreenSize: 0.149760, VScreenSize: 0.093600 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 161 NL3D::CStereoOVR::CStereoOVR : OVR: VScreenCenter: 0.046800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 162 NL3D::CStereoOVR::CStereoOVR : OVR: EyeToScreenDistance: 0.041000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 163 NL3D::CStereoOVR::CStereoOVR : OVR: LensSeparationDistance: 0.063500 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 164 NL3D::CStereoOVR::CStereoOVR : OVR: InterpupillaryDistance: 0.064000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 165 NL3D::CStereoOVR::CStereoOVR : OVR: HResolution: 1280, VResolution: 800 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 166 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[0]: 1.000000, DistortionK[1]: 0.220000 + //2013/06/26 05:31:51 DBG 17a0 snowballs_client.exe stereo_ovr.cpp 167 NL3D::CStereoOVR::CStereoOVR : OVR: DistortionK[2]: 0.240000, DistortionK[3]: 0.000000 + m_DevicePtr->SensorDevice = m_DevicePtr->HMDDevice->GetSensor(); + m_DevicePtr->SensorFusion.AttachToSensor(m_DevicePtr->SensorDevice); + m_DevicePtr->SensorFusion.SetGravityEnabled(true); + m_DevicePtr->SensorFusion.SetPredictionEnabled(true); + m_DevicePtr->SensorFusion.SetYawCorrectionEnabled(true); + m_LeftViewport.init(0.f, 0.f, 0.5f, 1.0f); + m_RightViewport.init(0.5f, 0.f, 0.5f, 1.0f); + }*/ +} + +CStereoOVR::~CStereoOVR() +{ + /*if (!m_BarrelMat.empty()) + { + m_BarrelMat.getObjectPtr()->setTexture(0, NULL); + m_Driver->deleteMaterial(m_BarrelMat); + } + + delete m_PixelProgram; + m_PixelProgram = NULL; + + m_Driver = NULL; + + if (m_DevicePtr->SensorDevice) + m_DevicePtr->SensorDevice->Release(); + m_DevicePtr->SensorDevice.Clear(); + if (m_DevicePtr->HMDDevice) + m_DevicePtr->HMDDevice->Release(); + m_DevicePtr->HMDDevice.Clear(); + + delete m_DevicePtr; + m_DevicePtr = NULL; + --s_DeviceCounter;*/ +} +/* +class CPixelProgramOVR : public CPixelProgram +{ +public: + struct COVRIndices + { + uint LensCenter; + uint ScreenCenter; + uint Scale; + uint ScaleIn; + uint HmdWarpParam; + }; + + CPixelProgramOVR() + { + { + CSource *source = new CSource(); + source->Profile = glsl330f; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_glsl330f); + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = fp40; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_fp40); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = arbfp1; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_arbfp1); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + { + CSource *source = new CSource(); + source->Profile = ps_2_0; + source->Features.MaterialFlags = CProgramFeatures::TextureStages; + source->setSourcePtr(g_StereoOVR_ps_2_0); + source->ParamIndices["cLensCenter"] = 0; + source->ParamIndices["cScreenCenter"] = 1; + source->ParamIndices["cScale"] = 2; + source->ParamIndices["cScaleIn"] = 3; + source->ParamIndices["cHmdWarpParam"] = 4; + addSource(source); + } + } + + virtual ~CPixelProgramOVR() + { + + } + + virtual void buildInfo() + { + CPixelProgram::buildInfo(); + + m_OVRIndices.LensCenter = getUniformIndex("cLensCenter"); + nlassert(m_OVRIndices.LensCenter != ~0); + m_OVRIndices.ScreenCenter = getUniformIndex("cScreenCenter"); + nlassert(m_OVRIndices.ScreenCenter != ~0); + m_OVRIndices.Scale = getUniformIndex("cScale"); + nlassert(m_OVRIndices.Scale != ~0); + m_OVRIndices.ScaleIn = getUniformIndex("cScaleIn"); + nlassert(m_OVRIndices.ScaleIn != ~0); + m_OVRIndices.HmdWarpParam = getUniformIndex("cHmdWarpParam"); + nlassert(m_OVRIndices.HmdWarpParam != ~0); + } + + inline const COVRIndices &ovrIndices() { return m_OVRIndices; } + +private: + COVRIndices m_OVRIndices; + +}; +*/ +void CStereoOVR::setDriver(NL3D::UDriver *driver) +{/* + nlassert(!m_PixelProgram); + + NL3D::IDriver *drvInternal = (static_cast(driver))->getDriver(); + + if (drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) + { + m_PixelProgram = new CPixelProgramOVR(); + if (!drvInternal->compilePixelProgram(m_PixelProgram)) + { + m_PixelProgram.kill(); + } + } + + if (m_PixelProgram) + { + m_Driver = driver; + + /*m_BarrelTex = new CTextureBloom(); // lol bloom + m_BarrelTex->setRenderTarget(true); + m_BarrelTex->setReleasable(false); + m_BarrelTex->resize(m_DevicePtr->HMDInfo.HResolution, m_DevicePtr->HMDInfo.VResolution); + m_BarrelTex->setFilterMode(ITexture::Linear, ITexture::LinearMipMapOff); + m_BarrelTex->setWrapS(ITexture::Clamp); + m_BarrelTex->setWrapT(ITexture::Clamp); + drvInternal->setupTexture(*m_BarrelTex); + m_BarrelTexU = new CTextureUser(m_BarrelTex);* / + + m_BarrelMat = m_Driver->createMaterial(); + m_BarrelMat.initUnlit(); + m_BarrelMat.setColor(CRGBA::White); + m_BarrelMat.setBlend (false); + m_BarrelMat.setAlphaTest (false); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setShader(NL3D::CMaterial::Normal); + barrelMat->setBlendFunc(CMaterial::one, CMaterial::zero); + barrelMat->setZWrite(false); + barrelMat->setZFunc(CMaterial::always); + barrelMat->setDoubleSided(true); + // barrelMat->setTexture(0, m_BarrelTex); + + m_BarrelQuadLeft.V0 = CVector(0.f, 0.f, 0.5f); + m_BarrelQuadLeft.V1 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadLeft.V2 = CVector(0.5f, 1.f, 0.5f); + m_BarrelQuadLeft.V3 = CVector(0.f, 1.f, 0.5f); + + m_BarrelQuadRight.V0 = CVector(0.5f, 0.f, 0.5f); + m_BarrelQuadRight.V1 = CVector(1.f, 0.f, 0.5f); + m_BarrelQuadRight.V2 = CVector(1.f, 1.f, 0.5f); + m_BarrelQuadRight.V3 = CVector(0.5f, 1.f, 0.5f); + + // nlassert(!drvInternal->isTextureRectangle(m_BarrelTex)); // not allowed + + m_BarrelQuadLeft.Uv0 = CUV(0.f, 0.f); + m_BarrelQuadLeft.Uv1 = CUV(0.5f, 0.f); + m_BarrelQuadLeft.Uv2 = CUV(0.5f, 1.f); + m_BarrelQuadLeft.Uv3 = CUV(0.f, 1.f); + + m_BarrelQuadRight.Uv0 = CUV(0.5f, 0.f); + m_BarrelQuadRight.Uv1 = CUV(1.f, 0.f); + m_BarrelQuadRight.Uv2 = CUV(1.f, 1.f); + m_BarrelQuadRight.Uv3 = CUV(0.5f, 1.f); + } + else + { + nlwarning("VR: No pixel program support"); + }*/ +} + +bool CStereoOVR::getScreenResolution(uint &width, uint &height) +{ + /*width = m_DevicePtr->HMDInfo.HResolution; + height = m_DevicePtr->HMDInfo.VResolution;*/ + return true; +} + +void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) +{ + /*m_OriginalFrustum[cid] = camera->getFrustum(); + + float ar = (float)m_DevicePtr->HMDInfo.HResolution / ((float)m_DevicePtr->HMDInfo.VResolution * 2.0f); + float fov = 2.0f * atanf((m_DevicePtr->HMDInfo.HScreenSize * 0.5f * 0.5f) / (m_DevicePtr->HMDInfo.EyeToScreenDistance)); //(float)NLMISC::Pi/2.f; // 2.0f * atanf(m_DevicePtr->HMDInfo.VScreenSize / 2.0f * m_DevicePtr->HMDInfo.EyeToScreenDistance); + m_LeftFrustum[cid].initPerspective(fov, ar, camera->getFrustum().Near, camera->getFrustum().Far); + m_RightFrustum[cid] = m_LeftFrustum[cid]; + + float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; + float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; // docs say LensSeparationDistance, why not InterpupillaryDistance? related to how the lenses work? + float projectionCenterOffset = (eyeProjectionShift / (m_DevicePtr->HMDInfo.HScreenSize * 0.5f)) * (m_LeftFrustum[cid].Right - m_LeftFrustum[cid].Left); // used logic for this one, but it ends up being the same as the one i made up + nldebug("OVR: projectionCenterOffset = %f", projectionCenterOffset); + + m_LeftFrustum[cid].Left -= projectionCenterOffset; + m_LeftFrustum[cid].Right -= projectionCenterOffset; + m_RightFrustum[cid].Left += projectionCenterOffset; + m_RightFrustum[cid].Right += projectionCenterOffset; + + // TODO: Clipping frustum should also take into account the IPD + m_ClippingFrustum[cid] = m_LeftFrustum[cid]; + m_ClippingFrustum[cid].Left = min(m_LeftFrustum[cid].Left, m_RightFrustum[cid].Left); + m_ClippingFrustum[cid].Right = max(m_LeftFrustum[cid].Right, m_RightFrustum[cid].Right);*/ +} + +/// Get the frustum to use for clipping +void CStereoOVR::getClippingFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_ClippingFrustum[cid]); +} + +/// Get the original frustum of the camera +void CStereoOVR::getOriginalFrustum(uint cid, NL3D::UCamera *camera) const +{ + camera->setFrustum(m_OriginalFrustum[cid]); +} + +void CStereoOVR::updateCamera(uint cid, const NL3D::UCamera *camera) +{ + if (camera->getFrustum().Near != m_LeftFrustum[cid].Near + || camera->getFrustum().Far != m_LeftFrustum[cid].Far) + CStereoOVR::initCamera(cid, camera); + m_CameraMatrix[cid] = camera->getMatrix(); +} + +bool CStereoOVR::nextPass() +{ + // Do not allow weird stuff. + uint32 width, height; + m_Driver->getWindowSize(width, height); + // nlassert(width == m_DevicePtr->HMDInfo.HResolution); + // nlassert(height == m_DevicePtr->HMDInfo.VResolution); + + if (m_Driver->getPolygonMode() == UDriver::Filled) + { + switch (m_Stage) // Previous stage + { + case 0: + m_Stage += 2; + m_SubStage = 0; + // stage 2: + // draw interface 2d (onto render target) + return true; + case 2: + ++m_Stage; + m_SubStage = 0; + // stage 3: + // (initBloom) + // clear buffer + // draw scene left + return true; + case 3: + ++m_Stage; + m_SubStage = 0; + // stage 4: + // draw scene right + return true; + case 4: + ++m_Stage; + m_SubStage = 0; + // stage 5: + // (endBloom) + // draw interface 3d left + return true; + case 5: + ++m_Stage; + m_SubStage = 0; + // stage 6: + // draw interface 3d right + return true; + /*case 6: + ++m_Stage; + m_SubStage = 0; + // stage 7: + // (endInterfacesDisplayBloom) + // draw interface 2d left + return true; + case 7: + ++m_Stage; + m_SubStage = 0; + // stage 8: + // draw interface 2d right + return true;*/ + case 6: + m_Stage = 0; + m_SubStage = 0; + // present + m_OrientationCached = false; + return false; + } + } + else + { + switch (m_Stage) + { + case 0: + ++m_Stage; + m_SubStage = 0; + return true; + case 1: + m_Stage = 0; + m_SubStage = 0; + return false; + } + } + nlerror("Invalid stage"); + m_Stage = 0; + m_SubStage = 0; + m_OrientationCached = false; + return false; +} + +const NL3D::CViewport &CStereoOVR::getCurrentViewport() const +{ + if (m_Stage == 2) return m_RegularViewport; + else if (m_Stage % 2) return m_LeftViewport; + else return m_RightViewport; +} + +const NL3D::CFrustum &CStereoOVR::getCurrentFrustum(uint cid) const +{ + if (m_Stage == 2) return m_OriginalFrustum[cid]; + else if (m_Stage % 2) return m_LeftFrustum[cid]; + else return m_RightFrustum[cid]; +} + +void CStereoOVR::getCurrentFrustum(uint cid, NL3D::UCamera *camera) const +{ + if (m_Stage == 2) camera->setFrustum(m_OriginalFrustum[cid]); + else if (m_Stage % 2) camera->setFrustum(m_LeftFrustum[cid]); + else camera->setFrustum(m_RightFrustum[cid]); +} + +void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const +{/* + CMatrix translate; + if (m_Stage == 2) { } + else if (m_Stage % 2) translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * -0.5f, 0.f, 0.f)); + else translate.translate(CVector((m_DevicePtr->HMDInfo.InterpupillaryDistance * m_Scale) * 0.5f, 0.f, 0.f)); + CMatrix mat = m_CameraMatrix[cid] * translate; + if (camera->getTransformMode() == NL3D::UTransformable::RotQuat) + { + camera->setPos(mat.getPos()); + camera->setRotQuat(mat.getRot()); + } + else + { + // camera->setTransformMode(NL3D::UTransformable::DirectMatrix); + camera->setMatrix(mat); + }*/ +} + +bool CStereoOVR::wantClear() +{ + switch (m_Stage) + { + case 3: + m_SubStage = 1; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantScene() +{ + switch (m_Stage) + { + case 3: + case 4: + m_SubStage = 2; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantInterface3D() +{ + switch (m_Stage) + { + case 5: + case 6: + m_SubStage = 3; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +bool CStereoOVR::wantInterface2D() +{ + switch (m_Stage) + { + case 2: + m_SubStage = 4; + return true; + } + return m_Driver->getPolygonMode() != UDriver::Filled; +} + +/// Returns non-NULL if a new render target was set +bool CStereoOVR::beginRenderTarget() +{ + // render target always set before driver clear + // nlassert(m_SubStage <= 1); + + // Set GUI render target + if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + nlassert(!m_GUITexture); + uint32 width, height; + m_Driver->getWindowSize(width, height); + m_GUITexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height, true, UTexture::RGBA8888); + static_cast(m_Driver)->setRenderTarget(*m_GUITexture); + m_Driver->clearBuffers(NLMISC::CRGBA(0, 0, 0, 0)); + return true; + } + + // Begin 3D scene render target + /*if (m_Driver && m_Stage == 3 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + nlassert(!m_SceneTexture); + uint32 width, height; + m_Driver->getWindowSize(width, height); // Temporary limitation, TODO: scaling! + m_SceneTexture = m_Driver->getRenderTargetManager().getRenderTarget(width, height); + static_cast(m_Driver)->setRenderTarget(*m_SceneTexture); + return true; + }*/ + + return false; +} + +void CStereoOVR::setInterfaceMatrix(const NL3D::CMatrix &matrix) +{ + m_InterfaceCameraMatrix = matrix; +} + +void CStereoOVR::renderGUI() +{ + + /*CMatrix mat; + mat.translate(m_InterfaceCameraMatrix.getPos()); + CVector dir = m_InterfaceCameraMatrix.getJ(); + dir.z = 0; + dir.normalize(); + if (dir.y < 0) + mat.rotateZ(float(NLMISC::Pi+asin(dir.x))); + else + mat.rotateZ(float(NLMISC::Pi+NLMISC::Pi-asin(dir.x))); + m_Driver->setModelMatrix(mat);*/ + m_Driver->setModelMatrix(m_InterfaceCameraMatrix); + + { + NLMISC::CLine line(NLMISC::CVector(0, 5, 2), NLMISC::CVector(0, 5, 3)); + + NL3D::UMaterial mat = m_Driver->createMaterial(); + mat.setZWrite(false); + // mat.setZFunc(UMaterial::always); // Not nice! + mat.setDoubleSided(true); + mat.setColor(NLMISC::CRGBA::Red); + mat.setBlend(false); + + m_Driver->drawLine(line, mat); + + m_Driver->deleteMaterial(mat); + } + + { + nlassert(m_GUITexture); + + NLMISC::CQuadUV quad; + + NL3D::UMaterial umat = m_Driver->createMaterial(); + umat.initUnlit(); + umat.setColor(NLMISC::CRGBA::White); + umat.setDoubleSided(true); + umat.setBlend(true); + umat.setAlphaTest(false); + NL3D::CMaterial *mat = umat.getObjectPtr(); + mat->setShader(NL3D::CMaterial::Normal); + mat->setBlendFunc(CMaterial::one, CMaterial::invsrcalpha); + mat->setZWrite(false); + // mat->setZFunc(CMaterial::always); // Not nice + mat->setDoubleSided(true); + mat->setTexture(0, m_GUITexture->getITexture()); + + // user options + float scale = 1.0f; + float distance = 1.5f; + float offcenter = 0.75f; + + float height = scale * distance * 2.0f; + + uint32 winw, winh; + m_Driver->getWindowSize(winw, winh); + float width = height * (float)winw / (float)winh; + + float bottom = -(height * 0.5f); + float top = (height * 0.5f); + + NLMISC::CQuadUV quadUV; + quadUV.V0 = CVector(-(width * 0.5f), distance, -(height * 0.5f)); + quadUV.V1 = CVector((width * 0.5f), distance, -(height * 0.5f)); + quadUV.V2 = CVector((width * 0.5f), distance, (height * 0.5f)); + quadUV.V3 = CVector(-(width * 0.5f), distance, (height * 0.5f)); + quadUV.Uv0 = CUV(0.f, 0.f); + quadUV.Uv1 = CUV(1.f, 0.f); + quadUV.Uv2 = CUV(1.f, 1.f); + quadUV.Uv3 = CUV(0.f, 1.f); + + const uint nbQuads = 128; + static CVertexBuffer vb; + static CIndexBuffer ib; + + vb.setVertexFormat(CVertexBuffer::PositionFlag | CVertexBuffer::TexCoord0Flag); + vb.setPreferredMemory(CVertexBuffer::RAMVolatile, false); + vb.setNumVertices((nbQuads + 1) * 2); + + { + CVertexBufferReadWrite vba; + vb.lock(vba); + float radius = distance + offcenter; + float relWidth = width / radius; + float quadWidth = relWidth / (float)nbQuads; + for (uint i = 0; i < nbQuads + 1; ++i) + { + uint vi0 = i * 2; + uint vi1 = vi0 + 1; + float lineH = -(relWidth * 0.5f) + quadWidth * (float)i; + float lineUV = (float)i / (float)(nbQuads); + float left = sin(lineH) * radius; + float forward = cos(lineH) * radius; + vba.setVertexCoord(vi0, left, forward - offcenter, bottom); + vba.setTexCoord(vi0, 0, lineUV, 0.0f); + vba.setVertexCoord(vi1, left, forward - offcenter, top); + vba.setTexCoord(vi1, 0, lineUV, 1.0f); + } + } + + ib.setFormat(NL_DEFAULT_INDEX_BUFFER_FORMAT); + ib.setPreferredMemory(CIndexBuffer::RAMVolatile, false); + ib.setNumIndexes(nbQuads * 6); + + { + CIndexBufferReadWrite iba; + ib.lock(iba); + for (uint i = 0; i < nbQuads; ++i) + { + uint ti0 = i * 2; + uint ti1 = ti0 + 1; + uint bl = ti0; + uint tl = ti0 + 1; + uint br = ti0 + 2; + uint tr = ti0 + 3; + iba.setTri(ti0 * 3, bl, tl, br); + iba.setTri(ti1 * 3, br, tl, tr); + } + } + + IDriver *driver = static_cast(m_Driver)->getDriver(); + // m_Driver->setPolygonMode(UDriver::Line); + driver->activeVertexBuffer(vb); + driver->activeIndexBuffer(ib); + driver->renderTriangles(*umat.getObjectPtr(), 0, nbQuads * 2); //renderRawQuads(umat, 0, 128); + // m_Driver->setPolygonMode(UDriver::Filled); + + // m_Driver->drawQuad(quadUV, umat); + + m_Driver->deleteMaterial(umat); + } +} + +/// Returns true if a render target was fully drawn +bool CStereoOVR::endRenderTarget() +{ + // after rendering of course + // nlassert(m_SubStage > 1); + + // End GUI render target + if (m_Driver && m_Stage == 2 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // End GUI render target + nlassert(m_GUITexture); + CTextureUser texNull; + (static_cast(m_Driver))->setRenderTarget(texNull); + } + + // End of 3D Interface pass left + if (m_Driver && m_Stage == 5 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // Render 2D GUI in 3D space, assume existing camera is OK + renderGUI(); + } + + // End of 3D Interface pass right + if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) + { + // Render 2D GUI in 3D space, assume existing camera is OK + renderGUI(); + + // Recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(m_GUITexture); + m_GUITexture = NULL; + } + + // End 3D scene render target + /*if (m_Driver && m_Stage == 6 && (m_Driver->getPolygonMode() == UDriver::Filled)) // set to 4 to turn off distortion of 2d gui + { + nlassert(m_SceneTexture); + + CTextureUser texNull; + (static_cast(m_Driver))->setRenderTarget(texNull); + bool fogEnabled = m_Driver->fogEnabled(); + m_Driver->enableFog(false); + + m_Driver->setMatrixMode2D11(); + CViewport vp = CViewport(); + m_Driver->setViewport(vp); + uint32 width, height; + m_Driver->getWindowSize(width, height); + NL3D::IDriver *drvInternal = (static_cast(m_Driver))->getDriver(); + NL3D::CMaterial *barrelMat = m_BarrelMat.getObjectPtr(); + barrelMat->setTexture(0, m_SceneTexture->getITexture()); + + drvInternal->activePixelProgram(m_PixelProgram); + + float w = float(m_BarrelQuadLeft.V1.x),// / float(width), + h = float(m_BarrelQuadLeft.V2.y),// / float(height), + x = float(m_BarrelQuadLeft.V0.x),/// / float(width), + y = float(m_BarrelQuadLeft.V0.y);// / float(height); + + float lensOffset = m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; + float lensShift = m_DevicePtr->HMDInfo.HScreenSize * 0.25f - lensOffset; + float lensViewportShift = 4.0f * lensShift / m_DevicePtr->HMDInfo.HScreenSize; + + float lensCenterX = x + (w + lensViewportShift * 0.5f) * 0.5f; + float lensCenterY = y + h * 0.5f; + float screenCenterX = x + w * 0.5f; + float screenCenterY = y + h * 0.5f; + float scaleX = (w / 2); + float scaleY = (h / 2); + float scaleInX = (2 / w); + float scaleInY = (2 / h); + + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().Scale, + scaleX, scaleY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScaleIn, + scaleInX, scaleInY); + + + drvInternal->setUniform4fv(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().HmdWarpParam, + 1, m_DevicePtr->HMDInfo.DistortionK); + + m_Driver->drawQuad(m_BarrelQuadLeft, m_BarrelMat); + + x = w; + lensCenterX = x + (w - lensViewportShift * 0.5f) * 0.5f; + screenCenterX = x + w * 0.5f; + + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().LensCenter, + lensCenterX, lensCenterY); + + drvInternal->setUniform2f(IDriver::PixelProgram, + m_PixelProgram->ovrIndices().ScreenCenter, + screenCenterX, screenCenterY); + + + m_Driver->drawQuad(m_BarrelQuadRight, m_BarrelMat); + + drvInternal->activePixelProgram(NULL); + m_Driver->enableFog(fogEnabled); + + // Recycle render target + m_Driver->getRenderTargetManager().recycleRenderTarget(m_SceneTexture); + m_SceneTexture = NULL; + + return true; + }*/ + + return false; +} + +NLMISC::CQuat CStereoOVR::getOrientation() const +{ + //if (m_OrientationCached) + return m_OrientationCache; +/* + OVR::Quatf quatovr = m_DevicePtr->SensorFusion.GetPredictedOrientation(); + NLMISC::CMatrix coordsys; + float csys[] = { + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, 1.0f, + }; + coordsys.set(csys); + NLMISC::CMatrix matovr; + matovr.setRot(NLMISC::CQuat(quatovr.x, quatovr.y, quatovr.z, quatovr.w)); + NLMISC::CMatrix matr; + matr.rotateX(NLMISC::Pi * 0.5f); // fix this properly... :) (note: removing this allows you to use rift while lying down) + NLMISC::CMatrix matnel = matr * matovr * coordsys; + NLMISC::CQuat finalquat = matnel.getRot(); + m_OrientationCache = finalquat; + m_OrientationCached = true; + return finalquat;*/ +} + +/// Get GUI shift +void CStereoOVR::getInterface2DShift(uint cid, float &x, float &y, float distance) const +{ + +} + +void CStereoOVR::setEyePosition(const NLMISC::CVector &v) +{ + m_EyePosition = v; +} + +const NLMISC::CVector &CStereoOVR::getEyePosition() const +{ + return m_EyePosition; +} + +void CStereoOVR::setScale(float s) +{ + m_EyePosition = m_EyePosition * (s / m_Scale); + m_Scale = s; +} + +void CStereoOVR::listDevices(std::vector &devicesOut) +{ + /* + s_StereoOVRSystem.Init(); + OVR::DeviceEnumerator devices = s_DeviceManager->EnumerateDevices(); + uint id = 1; + do + { + CStereoDeviceInfo deviceInfoOut; + OVR::DeviceInfo deviceInfo; + if (devices.IsAvailable()) + { + devices.GetDeviceInfo(&deviceInfo); + CStereoOVRDeviceHandle *handle = new CStereoOVRDeviceHandle(); + deviceInfoOut.Factory = static_cast(handle); + handle->DeviceHandle = devices; + deviceInfoOut.Class = CStereoDeviceInfo::StereoHMD; // 1; // OVR::HMDDevice + deviceInfoOut.Library = CStereoDeviceInfo::OVR; // "Oculus SDK"; + deviceInfoOut.Manufacturer = deviceInfo.Manufacturer; + deviceInfoOut.ProductName = deviceInfo.ProductName; + deviceInfoOut.AllowAuto = true; + stringstream ser; + ser << id; + deviceInfoOut.Serial = ser.str(); // can't get the real serial from the sdk... + devicesOut.push_back(deviceInfoOut); + ++id; + } + + } while (devices.Next());*/ +} + +bool CStereoOVR::isLibraryInUse() +{ + /*nlassert(s_DeviceCounter >= 0); + return s_DeviceCounter > 0;*/ + return false; +} + +void CStereoOVR::releaseLibrary() +{ + /*nlassert(s_DeviceCounter == 0); + s_StereoOVRSystem.Release();*/ +} + +bool CStereoOVR::isDeviceCreated() +{ + /*return m_DevicePtr->HMDDevice != NULL;*/ + return false; +} + +} /* namespace NL3D */ + +#endif /* HAVE_LIBOVR */ + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr_04_program.h b/code/nel/src/3d/stereo_ovr_04_program.h new file mode 100644 index 000000000..940be0bfe --- /dev/null +++ b/code/nel/src/3d/stereo_ovr_04_program.h @@ -0,0 +1,249 @@ +/************************************************************************************ + +Filename : stereo_ovf_fp.cpp +Content : Barrel fragment program compiled to a blob of assembly +Created : July 01, 2013 +Modified by : Jan Boon (Kaetemi) + +Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +namespace NL3D { +const char *g_StereoOVR_fp40 = + "!!ARBfp1.0\n" + "OPTION NV_fragment_program2;\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile fp40 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile fp40 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 + "PARAM c[6] = { program.env[0..4],\n" // program.local->program.env! + " { 0.25, 0.5, 0 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "SHORT TEMP H0;\n" + "TEMP RC;\n" + "TEMP HC;\n" + "OUTPUT oCol = result.color;\n" + "ADDR R0.xy, fragment.texcoord[0], -c[0];\n" + "MULR R0.xy, R0, c[3];\n" + "MULR R0.z, R0.y, R0.y;\n" + "MADR R1.x, R0, R0, R0.z;\n" + "MULR R0.zw, R1.x, c[4].xywz;\n" + "MADR R1.y, R1.x, c[4], c[4].x;\n" + "MADR R0.w, R0, R1.x, R1.y;\n" + "MULR R0.z, R0, R1.x;\n" + "MADR R0.z, R0, R1.x, R0.w;\n" + "MULR R1.xy, R0, R0.z;\n" + "MOVR R0.xy, c[5];\n" + "ADDR R1.zw, R0.xyxy, c[1].xyxy;\n" + "MOVR R0.zw, c[0].xyxy;\n" + "MADR R0.zw, R1.xyxy, c[2].xyxy, R0;\n" + "MINR R1.xy, R0.zwzw, R1.zwzw;\n" + "ADDR R0.xy, -R0, c[1];\n" + "MAXR R0.xy, R0, R1;\n" + "SEQR H0.xy, R0, R0.zwzw;\n" + "MULXC HC.x, H0, H0.y;\n" + "IF EQ.x;\n" + "MOVR oCol, c[5].z;\n" + "ELSE;\n" + "TEX oCol, R0.zwzw, texture[0], 2D;\n" + "ENDIF;\n" + "END\n"; + //# 24 instructions, 2 R-regs, 1 H-regs + +const char *g_StereoOVR_arbfp1 = + "!!ARBfp1.0\n" + //# cgc version 3.1.0013, build date Apr 18 2012 + //# command line args: -profile arbfp1 + //# source file: pp_oculus_vr.cg + //#vendor NVIDIA Corporation + //#version 3.1.0.13 + //#profile arbfp1 + //#program pp_oculus_vr + //#semantic pp_oculus_vr.cLensCenter + //#semantic pp_oculus_vr.cScreenCenter + //#semantic pp_oculus_vr.cScale + //#semantic pp_oculus_vr.cScaleIn + //#semantic pp_oculus_vr.cHmdWarpParam + //#semantic pp_oculus_vr.cTex0 : TEX0 + //#var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //#var float2 cLensCenter : : c[0] : 1 : 1 + //#var float2 cScreenCenter : : c[1] : 2 : 1 + //#var float2 cScale : : c[2] : 3 : 1 + //#var float2 cScaleIn : : c[3] : 4 : 1 + //#var float4 cHmdWarpParam : : c[4] : 5 : 1 + //#var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //#var float4 oCol : $vout.COLOR : COL : 7 : 1 + //#const c[5] = 0.25 0.5 0 1 + "PARAM c[6] = { program.env[0..4],\n" + " { 0.25, 0.5, 0, 1 } };\n" + "TEMP R0;\n" + "TEMP R1;\n" + "ADD R0.xy, fragment.texcoord[0], -c[0];\n" + "MUL R0.xy, R0, c[3];\n" + "MUL R0.z, R0.y, R0.y;\n" + "MAD R0.z, R0.x, R0.x, R0;\n" + "MUL R0.w, R0.z, c[4];\n" + "MUL R0.w, R0, R0.z;\n" + "MAD R1.y, R0.z, c[4], c[4].x;\n" + "MUL R1.x, R0.z, c[4].z;\n" + "MAD R1.x, R0.z, R1, R1.y;\n" + "MAD R0.z, R0.w, R0, R1.x;\n" + "MUL R0.xy, R0, R0.z;\n" + "MOV R0.zw, c[5].xyxy;\n" + "ADD R1.xy, R0.zwzw, c[1];\n" + "MUL R0.xy, R0, c[2];\n" + "ADD R0.xy, R0, c[0];\n" + "MIN R1.xy, R1, R0;\n" + "ADD R0.zw, -R0, c[1].xyxy;\n" + "MAX R0.zw, R0, R1.xyxy;\n" + "ADD R0.zw, R0, -R0.xyxy;\n" + "ABS R0.zw, R0;\n" + "CMP R0.zw, -R0, c[5].z, c[5].w;\n" + "MUL R0.z, R0, R0.w;\n" + "ABS R0.z, R0;\n" + "CMP R0.z, -R0, c[5], c[5].w;\n" + "ABS R1.x, R0.z;\n" + "TEX R0, R0, texture[0], 2D;\n" + "CMP R1.x, -R1, c[5].z, c[5].w;\n" + "CMP result.color, -R1.x, R0, c[5].z;\n" + "END\n"; + //# 28 instructions, 2 R-regs + +const char *g_StereoOVR_ps_2_0 = + "ps_2_0\n" + // cgc version 3.1.0013, build date Apr 18 2012 + // command line args: -profile ps_2_0 + // source file: pp_oculus_vr.cg + //vendor NVIDIA Corporation + //version 3.1.0.13 + //profile ps_2_0 + //program pp_oculus_vr + //semantic pp_oculus_vr.cLensCenter + //semantic pp_oculus_vr.cScreenCenter + //semantic pp_oculus_vr.cScale + //semantic pp_oculus_vr.cScaleIn + //semantic pp_oculus_vr.cHmdWarpParam + //semantic pp_oculus_vr.cTex0 : TEX0 + //var float2 texCoord : $vin.TEXCOORD0 : TEX0 : 0 : 1 + //var float2 cLensCenter : : c[0] : 1 : 1 + //var float2 cScreenCenter : : c[1] : 2 : 1 + //var float2 cScale : : c[2] : 3 : 1 + //var float2 cScaleIn : : c[3] : 4 : 1 + //var float4 cHmdWarpParam : : c[4] : 5 : 1 + //var sampler2D nlTex0 : TEX0 : texunit 0 : 6 : 1 + //var float4 oCol : $vout.COLOR : COL : 7 : 1 + //const c[5] = -0.25 -0.5 0.25 0.5 + //const c[6] = 1 0 + "dcl_2d s0\n" + "def c5, -0.25000000, -0.50000000, 0.25000000, 0.50000000\n" + "def c6, 1.00000000, 0.00000000, 0, 0\n" + "dcl t0.xy\n" + "add r0.xy, t0, -c0\n" + "mul r4.xy, r0, c3\n" + "mul r0.x, r4.y, r4.y\n" + "mad r0.x, r4, r4, r0\n" + "mul r1.x, r0, c4.w\n" + "mul r1.x, r1, r0\n" + "mad r3.x, r0, c4.y, c4\n" + "mul r2.x, r0, c4.z\n" + "mad r2.x, r0, r2, r3\n" + "mad r0.x, r1, r0, r2\n" + "mul r0.xy, r4, r0.x\n" + "mul r0.xy, r0, c2\n" + "add r3.xy, r0, c0\n" + "mov r1.x, c5.z\n" + "mov r1.y, c5.w\n" + "mov r2.xy, c1\n" + "add r2.xy, r1, r2\n" + "mov r1.xy, c1\n" + "min r2.xy, r2, r3\n" + "add r1.xy, c5, r1\n" + "max r1.xy, r1, r2\n" + "add r1.xy, r1, -r3\n" + "abs r1.xy, r1\n" + "cmp r1.xy, -r1, c6.x, c6.y\n" + "mul_pp r1.x, r1, r1.y\n" + "abs_pp r1.x, r1\n" + "cmp_pp r1.x, -r1, c6, c6.y\n" + "abs_pp r1.x, r1\n" + "texld r0, r3, s0\n" + "cmp r0, -r1.x, r0, c6.y\n" + "mov oC0, r0\n"; + +const char *g_StereoOVR_glsl330f = + "#version 330\n" + "\n" + "bool _TMP2;\n" + "bvec2 _TMP1;\n" + "vec2 _TMP3;\n" + "uniform vec2 cLensCenter;\n" + "uniform vec2 cScreenCenter;\n" + "uniform vec2 cScale;\n" + "uniform vec2 cScaleIn;\n" + "uniform vec4 cHmdWarpParam;\n" + "uniform sampler2D nlTex0;\n" + "vec2 _TMP10;\n" + "vec2 _b0011;\n" + "vec2 _a0011;\n" + "in vec4 nlTexCoord0;\n" + "out vec4 nlCol;\n" + "\n" + "void main()\n" + "{\n" + " vec2 _theta;\n" + " float _rSq;\n" + " vec2 _theta1;\n" + " vec2 _tc;\n" + "\n" + " _theta = (nlTexCoord0.xy - cLensCenter)*cScaleIn;\n" + " _rSq = _theta.x*_theta.x + _theta.y*_theta.y;\n" + " _theta1 = _theta*(cHmdWarpParam.x + cHmdWarpParam.y*_rSq + cHmdWarpParam.z*_rSq*_rSq + cHmdWarpParam.w*_rSq*_rSq*_rSq);\n" + " _tc = cLensCenter + cScale*_theta1;\n" + " _a0011 = cScreenCenter - vec2( 0.25, 0.5);\n" + " _b0011 = cScreenCenter + vec2( 0.25, 0.5);\n" + " _TMP3 = min(_b0011, _tc);\n" + " _TMP10 = max(_a0011, _TMP3);\n" + " _TMP1 = bvec2(_TMP10.x == _tc.x, _TMP10.y == _tc.y);\n" + " _TMP2 = _TMP1.x && _TMP1.y;\n" + " if (!_TMP2) {\n" + " nlCol = vec4(0, 0, 0, 0);\n" + " } else {\n" + " nlCol = texture(nlTex0, _tc);\n" + " }\n" + "}\n"; + +} + +/* end of file */ diff --git a/code/nel/src/3d/stereo_ovr_fp.cpp b/code/nel/src/3d/stereo_ovr_fp.cpp index 940be0bfe..84a74598e 100644 --- a/code/nel/src/3d/stereo_ovr_fp.cpp +++ b/code/nel/src/3d/stereo_ovr_fp.cpp @@ -21,6 +21,8 @@ limitations under the License. ************************************************************************************/ +#include "std3d.h" + namespace NL3D { const char *g_StereoOVR_fp40 = "!!ARBfp1.0\n"