From 3a12aa5894fa51d7382063e7a4b1f4ac728f5ad2 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 2 Jul 2013 00:55:13 +0200 Subject: [PATCH] Render the scene to a target texture for the stereo rendering filter, ref #43 --- code/nel/include/nel/3d/bloom_effect.h | 2 +- code/nel/include/nel/3d/stereo_display.h | 2 +- code/nel/include/nel/3d/stereo_ovr.h | 2 +- code/nel/src/3d/bloom_effect.cpp | 7 ++-- code/nel/src/3d/stereo_ovr.cpp | 20 +++++---- code/snowballs2/client/src/camera.cpp | 12 ++++-- .../client/src/snowballs_client.cpp | 41 +++++++++++-------- 7 files changed, 49 insertions(+), 37 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index f5da7a4dd..b637fe937 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -83,7 +83,7 @@ public: // If window size exceeds 256*256 the textures used to apply blur are reinitialized with // 256*256 size. If a dimension is less than 256, the texture is initialized with the nearer // power of 2, lower than this window dimension. - void initBloom(UTexture &renderTarget); + void initBloom(UTexture *renderTarget); void initBloom(); // Called at the end of renderAll method in the main loop, recover stretched texture, apply diff --git a/code/nel/include/nel/3d/stereo_display.h b/code/nel/include/nel/3d/stereo_display.h index 2f6592b60..aa98dae50 100644 --- a/code/nel/include/nel/3d/stereo_display.h +++ b/code/nel/include/nel/3d/stereo_display.h @@ -124,7 +124,7 @@ public: /// 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 unset) = 0; + virtual bool endRenderTarget() = 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 f25ef10e0..1a4ebf916 100644 --- a/code/nel/include/nel/3d/stereo_ovr.h +++ b/code/nel/include/nel/3d/stereo_ovr.h @@ -111,7 +111,7 @@ public: /// 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 unset); + virtual bool endRenderTarget(); /// Get the HMD orientation diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 0bc9c1e41..60b7d36b7 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -273,16 +273,15 @@ void CBloomEffect::initTexture(CSmartPtr & tex, bool isMode2D, uint32 void CBloomEffect::initBloom() { - CTextureUser cu; - initBloom(cu); + initBloom(NULL); } -void CBloomEffect::initBloom(UTexture &renderTarget) // clientcfg +void CBloomEffect::initBloom(UTexture *renderTarget) // clientcfg { if(!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; - m_UserRenderTarget = dynamic_cast(renderTarget).getITexture(); + m_UserRenderTarget = renderTarget ? dynamic_cast(renderTarget)->getITexture() : NULL; // don't activate bloom when PolygonMode is different from Filled if (_Driver->getPolygonMode() != UDriver::Filled) return; diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 8eb8e1f9b..68fd1400e 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -163,7 +163,7 @@ public: OVR::HMDInfo HMDInfo; }; -CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_BarrelTexU(NULL) +CStereoOVR::CStereoOVR(const CStereoOVRDeviceHandle *handle) : m_Stage(0), m_SubStage(0), m_OrientationCached(false), m_Driver(NULL), m_BarrelTexU(NULL) { ++s_DeviceCounter; m_DevicePtr = new CStereoOVRDevicePtr(); @@ -453,7 +453,7 @@ UTexture *CStereoOVR::beginRenderTarget(bool set) { // render target always set before driver clear // nlassert(m_SubStage <= 1); - if (m_Stage == 1) + if (m_Driver && m_Stage == 1) { if (set) { @@ -465,17 +465,19 @@ UTexture *CStereoOVR::beginRenderTarget(bool set) } /// Returns true if a render target was fully drawn -bool CStereoOVR::endRenderTarget(bool unset) +bool CStereoOVR::endRenderTarget() { // after rendering of course // nlassert(m_SubStage > 1); - if (m_Stage == 4) + if (m_Driver && m_Stage == 4) { - if (unset) - { - CTextureUser cu; - (static_cast(m_Driver))->setRenderTarget(cu); - } + CTextureUser cu; + (static_cast(m_Driver))->setRenderTarget(cu); + + m_Driver->setMatrixMode2D11(); + m_Driver->setViewport(CViewport()); + m_Driver->drawQuad(m_BarrelQuad, m_BarrelMat); + return true; } return false; diff --git a/code/snowballs2/client/src/camera.cpp b/code/snowballs2/client/src/camera.cpp index f4f5ea2b4..92216fe98 100644 --- a/code/snowballs2/client/src/camera.cpp +++ b/code/snowballs2/client/src/camera.cpp @@ -113,10 +113,14 @@ void initCamera() { nlinfo("Create VR stereo display device"); StereoDisplay = IStereoDisplay::createDevice(*deviceInfo); - if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + if (StereoDisplay) { - nlinfo("Stereo display device is a HMD"); - StereoHMD = static_cast(StereoDisplay); + if (deviceInfo->Class == CStereoDeviceInfo::StereoHMD) + { + nlinfo("Stereo display device is a HMD"); + StereoHMD = static_cast(StereoDisplay); + } + StereoDisplay->setDriver(Driver); // move after driver creation, move stereodisplay before driver creation } } IStereoDisplay::releaseUnusedLibraries(); @@ -212,7 +216,7 @@ void releaseSky() // -- -- random note: update and render makes more sense than animate and update void animateSky(double dt) { - Clouds->anim(dt); + if (!StereoDisplay) Clouds->anim(dt); } // this is actually render diff --git a/code/snowballs2/client/src/snowballs_client.cpp b/code/snowballs2/client/src/snowballs_client.cpp index e6754388a..e71136377 100644 --- a/code/snowballs2/client/src/snowballs_client.cpp +++ b/code/snowballs2/client/src/snowballs_client.cpp @@ -736,26 +736,28 @@ void loopIngame() { uint i = 0; uint bloomStage = 0; - while ((!StereoHMD && i == 0) || (StereoHMD && StereoHMD->nextPass())) + while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { ++i; - if (StereoHMD) + if (StereoDisplay) { - const CViewport &vp = StereoHMD->getCurrentViewport(); + const CViewport &vp = StereoDisplay->getCurrentViewport(); Driver->setViewport(vp); Scene->setViewport(vp); SkyScene->setViewport(vp); - StereoHMD->getCurrentFrustum(0, &Camera); - StereoHMD->getCurrentFrustum(0, &SkyCamera); - StereoHMD->getCurrentMatrix(0, &Camera); + StereoDisplay->getCurrentFrustum(0, &Camera); + StereoDisplay->getCurrentFrustum(0, &SkyCamera); + StereoDisplay->getCurrentMatrix(0, &Camera); } - if (!StereoHMD || StereoHMD->wantClear()) + if (!StereoDisplay || StereoDisplay->wantClear()) { + NL3D::UTexture *rt = StereoDisplay ? StereoDisplay->beginRenderTarget(!s_EnableBloom) : NULL; + if (s_EnableBloom) { nlassert(bloomStage == 0); - CBloomEffect::instance().initBloom(); // start bloom effect (just before the first scene element render) + CBloomEffect::instance().initBloom(/*rt*/); // start bloom effect (just before the first scene element render) bloomStage = 1; } @@ -763,7 +765,7 @@ void loopIngame() Driver->clearBuffers(CRGBA(0, 0, 127)); // clear all buffers, if you see this blue there's a problem with scene rendering } - if (!StereoHMD || StereoHMD->wantScene()) + if (!StereoDisplay || StereoDisplay->wantScene()) { // 02. Render Sky (sky scene) updateSky(); // Render the sky scene before the main scene @@ -772,17 +774,17 @@ void loopIngame() Scene->render(); // Render // 05. Render Effects (flare) - if (!StereoHMD) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) + if (!StereoDisplay) updateLensFlare(); // Render the lens flare (left eye stretched with stereo...) } - if (!StereoHMD || StereoHMD->wantInterface3D()) + if (!StereoDisplay || StereoDisplay->wantInterface3D()) { if (s_EnableBloom && bloomStage == 1) { // End the actual bloom effect visible in the scene. - if (StereoHMD) Driver->setViewport(NL3D::CViewport()); + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); CBloomEffect::instance().endBloom(); - if (StereoHMD) Driver->setViewport(StereoHMD->getCurrentViewport()); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); bloomStage = 2; } @@ -790,14 +792,14 @@ void loopIngame() // ... } - if (!StereoHMD || StereoHMD->wantInterface2D()) + if (!StereoDisplay || StereoDisplay->wantInterface2D()) { if (s_EnableBloom && bloomStage == 2) { // End bloom effect system after drawing the 3d interface (z buffer related). - if (StereoHMD) Driver->setViewport(NL3D::CViewport()); + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); CBloomEffect::instance().endInterfacesDisplayBloom(); - if (StereoHMD) Driver->setViewport(StereoHMD->getCurrentViewport()); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); bloomStage = 0; } @@ -810,11 +812,16 @@ void loopIngame() renderEntitiesNames(); // Render the name on top of the other players updateInterface(); // Update interface renderInformation(); - if (!StereoHMD) update3dLogo(); // broken with stereo + if (!StereoDisplay) update3dLogo(); // broken with stereo // 08. Render Debug (stuff for dev) // ... } + + if (StereoDisplay) + { + StereoDisplay->endRenderTarget(); + } } // 09. Render Buffer