From f25a9da7184427732a4c61f2fab6f734878a2265 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 1 Jul 2013 21:23:47 +0200 Subject: [PATCH] Add interface for stereo display render targets, ref #43 --- code/nel/include/nel/3d/stereo_display.h | 26 ++++---- code/nel/include/nel/3d/stereo_ovr.h | 24 +++---- code/nel/src/3d/stereo_ovr.cpp | 62 ++++++++++++------- .../client/src/snowballs_client.cpp | 18 ++---- 4 files changed, 69 insertions(+), 61 deletions(-) diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index b2547bef9..ad75ad934 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -42,6 +42,8 @@ class UCamera; class CViewport; class CFrustum; class IStereoDisplay; +class UTexture; +class UDriver; class IStereoDeviceFactory : public NLMISC::CRefCount { @@ -88,6 +90,9 @@ class IStereoDisplay public: IStereoDisplay(); virtual ~IStereoDisplay(); + + /// Sets driver and generates necessary render targets + virtual void setDriver(NL3D::UDriver &driver) = 0; /// Gets the required screen resolution for this device virtual void getScreenResolution(uint &width, uint &height) = 0; @@ -108,21 +113,18 @@ public: virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const = 0; /// At the start of a new render target - virtual bool beginClear() = 0; - // virtual void *getRenderTarget() const; - virtual void endClear() = 0; - + virtual bool wantClear() = 0; /// The 3D scene - virtual bool beginScene() = 0; - virtual void endScene() = 0; - + virtual bool wantScene() = 0; /// Interface within the 3D scene - virtual bool beginInterface3D() = 0; - virtual void endInterface3D() = 0; - + virtual bool wantInterface3D() = 0; /// 2D Interface - virtual bool beginInterface2D() = 0; - virtual void endInterface2D() = 0; + virtual bool wantInterface2D() = 0; + + /// Returns non-NULL if a new render target was set + virtual UTexture *beginRenderTarget(bool set) = 0; + /// Returns true if a render target was fully drawn + virtual bool endRenderTarget(bool render) = 0; static const char *getLibraryName(CStereoDeviceInfo::TStereoDeviceLibrary library); static void listDevices(std::vector &devicesOut); diff --git a/code/nel/include/nel/3d/stereo_ovr.h b/code/nel/include/nel/3d/stereo_ovr.h index e3c8361f8..3fff84ffb 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -74,6 +74,8 @@ 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 void getScreenResolution(uint &width, uint &height); @@ -94,21 +96,18 @@ public: virtual void getCurrentMatrix(uint cid, NL3D::UCamera *camera) const; /// At the start of a new render target - virtual bool beginClear(); - // virtual void *getRenderTarget() const; - virtual void endClear(); - + virtual bool wantClear(); /// The 3D scene - virtual bool beginScene(); - virtual void endScene(); - + virtual bool wantScene(); /// Interface within the 3D scene - virtual bool beginInterface3D(); - virtual void endInterface3D(); - + virtual bool wantInterface3D(); /// 2D Interface - virtual bool beginInterface2D(); - virtual void endInterface2D(); + virtual bool wantInterface2D(); + + /// Returns non-NULL if a new render target was set, always NULL if not using render targets + virtual UTexture *beginRenderTarget(bool set); + /// Returns true if a render target was fully drawn, always false if not using render targets + virtual bool endRenderTarget(bool render); /// Get the HMD orientation @@ -130,6 +129,7 @@ public: private: CStereoOVRDevicePtr *m_DevicePtr; int m_Stage; + int m_SubStage; CViewport m_LeftViewport; CViewport m_RightViewport; CFrustum m_ClippingFrustum[NL_STEREO_MAX_USER_CAMERAS]; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index de27a032e..a4b92b39e 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -155,7 +155,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_OrientationCached(false) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -206,6 +206,11 @@ CStereoOVR::~CStereoOVR() --s_DeviceCounter; } +void CStereoOVR::setDriver(NL3D::UDriver &driver) +{ + // ... +} + void CStereoOVR::getScreenResolution(uint &width, uint &height) { width = m_DevicePtr->HMDInfo.HResolution; @@ -220,7 +225,7 @@ void CStereoOVR::initCamera(uint cid, const NL3D::UCamera *camera) m_RightFrustum[cid] = m_LeftFrustum[cid]; float viewCenter = m_DevicePtr->HMDInfo.HScreenSize * 0.25f; - float eyeProjectionShift = viewCenter - m_DevicePtr->HMDInfo.LensSeparationDistance * 0.5f; + 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); @@ -255,6 +260,7 @@ bool CStereoOVR::nextPass() { case 0: ++m_Stage; + m_SubStage = 0; // stage 1: // (initBloom) // clear buffer @@ -262,39 +268,46 @@ bool CStereoOVR::nextPass() return true; case 1: ++m_Stage; + m_SubStage = 0; // stage 2: // draw scene right return true; case 2: ++m_Stage; + m_SubStage = 0; // stage 3: // (endBloom) // draw interface 3d left return true; case 3: ++m_Stage; + m_SubStage = 0; // stage 4: // draw interface 3d right return true; case 4: ++m_Stage; + m_SubStage = 0; // stage 5: // (endInterfacesDisplayBloom) // draw interface 2d left return true; case 5: ++m_Stage; + m_SubStage = 0; // stage 6: // draw interface 2d right return true; case 6: m_Stage = 0; + m_SubStage = 0; // present m_OrientationCached = false; return false; } - nlassert(false); + nlerror("Invalid stage"); m_Stage = 0; + m_SubStage = 0; m_OrientationCached = false; return false; } @@ -326,67 +339,68 @@ void CStereoOVR::getCurrentMatrix(uint cid, NL3D::UCamera *camera) const camera->setMatrix(m_CameraMatrix[cid] * translate); } -bool CStereoOVR::beginClear() +bool CStereoOVR::wantClear() { switch (m_Stage) { case 1: + m_SubStage = 1; return true; } return false; } - -void CStereoOVR::endClear() -{ - -} -bool CStereoOVR::beginScene() +bool CStereoOVR::wantScene() { switch (m_Stage) { case 1: case 2: + m_SubStage = 2; return true; } return false; } -void CStereoOVR::endScene() -{ - -} - -bool CStereoOVR::beginInterface3D() +bool CStereoOVR::wantInterface3D() { switch (m_Stage) { case 3: case 4: + m_SubStage = 3; return true; } return false; } -void CStereoOVR::endInterface3D() -{ - -} - -bool CStereoOVR::beginInterface2D() +bool CStereoOVR::wantInterface2D() { switch (m_Stage) { case 5: case 6: + m_SubStage = 4; return true; } return false; } -void CStereoOVR::endInterface2D() -{ +/// Returns non-NULL if a new render target was set +UTexture *CStereoOVR::beginRenderTarget(bool set) +{ + // render target always set before driver clear + nlassert(m_SubStage == 1); + return NULL; +} + +/// Returns true if a render target was fully drawn +bool CStereoOVR::endRenderTarget( bool render) +{ + // after rendering of course + nlassert(m_SubStage > 1); + return false; } NLMISC::CQuat CStereoOVR::getOrientation() const diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index 5cb7aa8df..e6754388a 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -750,7 +750,7 @@ void loopIngame() StereoHMD->getCurrentMatrix(0, &Camera); } - if (!StereoHMD || StereoHMD->beginClear()) + if (!StereoHMD || StereoHMD->wantClear()) { if (s_EnableBloom) { @@ -761,11 +761,9 @@ void loopIngame() // 01. Render Driver (background color) Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering - - if (StereoHMD) StereoHMD->endClear(); } - if (!StereoHMD || StereoHMD->beginScene()) + if (!StereoHMD || StereoHMD->wantScene()) { // 02. Render Sky (sky scene) updateSky(); // Render the sky scene before the main scene @@ -775,11 +773,9 @@ void loopIngame() // 05. Render Effects (flare) if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) - - if (StereoHMD) StereoHMD->endScene(); } - if (!StereoHMD || StereoHMD->beginInterface3D()) + if (!StereoHMD || StereoHMD->wantInterface3D()) { if (s_EnableBloom && bloomStage == 1) { @@ -791,12 +787,10 @@ void loopIngame() } // 06. Render Interface 3D (player names) - // ... - - if (StereoHMD) StereoHMD->endInterface3D(); + // ... } - if (!StereoHMD || StereoHMD->beginInterface2D()) + if (!StereoHMD || StereoHMD->wantInterface2D()) { if (s_EnableBloom && bloomStage == 2) { @@ -820,8 +814,6 @@ void loopIngame() // 08. Render Debug (stuff for dev) // ... - - if (StereoHMD) StereoHMD->endInterface2D(); } }