From d71f4c28c86fc2616157949969df9758871cf658 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 3 Aug 2014 22:15:44 +0200 Subject: [PATCH] Adjust render target handling for effects --- code/nel/include/nel/3d/bloom_effect.h | 7 +- code/nel/src/3d/bloom_effect.cpp | 43 +--------- code/ryzom/client/src/init_main_loop.cpp | 27 ++++++ code/ryzom/client/src/main_loop.cpp | 100 ++++++++++++++++------- code/ryzom/client/src/release.cpp | 4 + 5 files changed, 103 insertions(+), 78 deletions(-) diff --git a/code/nel/include/nel/3d/bloom_effect.h b/code/nel/include/nel/3d/bloom_effect.h index cb577f5bd..49c959e23 100644 --- a/code/nel/include/nel/3d/bloom_effect.h +++ b/code/nel/include/nel/3d/bloom_effect.h @@ -72,8 +72,8 @@ public: void setDensityBloom(uint8 densityBloom) { _DensityBloom = densityBloom; } uint8 getDensityBloom() const { return _DensityBloom; } - // Applies bloom to the current render target, if backbuffer is true the final image is rendered to the backbuffer instead of to a render target - void applyBloom(bool backbuffer); + // Applies bloom to the current render target + void applyBloom(); // Called at the beginning of renderAll method in the main loop, if window has been resized, // reinitialize bloom textures according to new window size. @@ -143,8 +143,6 @@ private: // materials // used to display first texture in doBlur passes. NL3D::UMaterial _BlurMat; - // used to display final render target texture onto the backbuffer - NL3D::UMaterial _DisplayInitMat; // used to blend initial scene render target texture and blur texture according to a // dest+src - dest*src blend operation. NL3D::UMaterial _DisplayBlurMat; @@ -154,7 +152,6 @@ private: // quads NLMISC::CQuadUV _BlurQuad; - NLMISC::CQuadUV _DisplayQuad; // textures and materials already initialized? bool _Init; diff --git a/code/nel/src/3d/bloom_effect.cpp b/code/nel/src/3d/bloom_effect.cpp index 7d009e29b..842423661 100644 --- a/code/nel/src/3d/bloom_effect.cpp +++ b/code/nel/src/3d/bloom_effect.cpp @@ -83,11 +83,6 @@ CBloomEffect::~CBloomEffect() { if (_Init) { - if (!_DisplayInitMat.empty()) - { - if (_Driver) _Driver->deleteMaterial(_DisplayInitMat); - } - if (!_DisplayBlurMat.empty()) { if (_Driver) _Driver->deleteMaterial(_DisplayBlurMat); @@ -160,18 +155,6 @@ void CBloomEffect::init() matObject->texEnvArg1RGB(3, CMaterial::Constant, CMaterial::SrcColor); matObject->texEnvArg2RGB(3, CMaterial::Previous, CMaterial::SrcColor); - // initialize display materials - _DisplayInitMat = _Driver->createMaterial(); - CMaterial * matObjectInit = _DisplayInitMat.getObjectPtr(); - _DisplayInitMat.initUnlit(); - _DisplayInitMat.setColor(CRGBA::White); - _DisplayInitMat.setBlend(false); - _DisplayInitMat.setAlphaTest (false); - matObjectInit->setBlendFunc(CMaterial::one, CMaterial::zero); - matObjectInit->setZWrite(false); - matObjectInit->setZFunc(CMaterial::always); - matObjectInit->setDoubleSided(true); - // initialize linear blur material _DisplayBlurMat = _Driver->createMaterial(); CMaterial * matObjectFinal = _DisplayBlurMat.getObjectPtr(); @@ -208,15 +191,6 @@ void CBloomEffect::init() matObjectFinal->texEnvArg1RGB(1, CMaterial::Previous, CMaterial::SrcColor); // initialize quads - _DisplayQuad.V0 = CVector(0.f, 0.f, 0.5f); - _DisplayQuad.V1 = CVector(1.f, 0.f, 0.5f); - _DisplayQuad.V2 = CVector(1.f, 1.f, 0.5f); - _DisplayQuad.V3 = CVector(0.f, 1.f, 0.5f); - _DisplayQuad.Uv0 = CUV(0.f, 0.f); - _DisplayQuad.Uv1 = CUV(1.f, 0.f); - _DisplayQuad.Uv2 = CUV(1.f, 1.f); - _DisplayQuad.Uv3 = CUV(0.f, 1.f); - _BlurQuad.V0 = CVector(-1.f, -1.f, 0.5f); _BlurQuad.V1 = CVector(1.f, -1.f, 0.5f); _BlurQuad.V2 = CVector(1.f, 1.f, 0.5f); @@ -241,7 +215,7 @@ void CBloomEffect::init() //----------------------------------------------------------------------------------------------------------- -void CBloomEffect::applyBloom(bool backbuffer) +void CBloomEffect::applyBloom() { if (!((CDriverUser *)_Driver)->getDriver()->supportBloomEffect()) return; @@ -301,22 +275,7 @@ void CBloomEffect::applyBloom(bool backbuffer) drv->setRenderTarget(renderTarget); applyBlur(); - // draw final result to backbuffer if last effect - if (backbuffer) - { - CTextureUser texNull; - dru->setRenderTarget(texNull); - - _DisplayInitMat.getObjectPtr()->setTexture(0, renderTarget); - - UCamera pCam = _Scene->getCam(); - _Driver->setMatrixMode2D11(); - _Driver->drawQuad(_DisplayQuad, _DisplayInitMat); - _Driver->setMatrixMode3D(pCam); - } - // cleanup material texture references - _DisplayInitMat.getObjectPtr()->setTexture(0, NULL); _DisplayBlurMat.getObjectPtr()->setTexture(0, NULL); _DisplaySquareBlurMat.getObjectPtr()->setTexture(0, NULL); _DisplaySquareBlurMat.getObjectPtr()->setTexture(1, NULL); diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index c0da76a32..a2db91b4f 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -40,6 +40,7 @@ #include "nel/3d/u_cloud_scape.h" #include "nel/3d/u_shape_bank.h" #include "nel/3d/u_water_env_map.h" +#include "nel/3d/material.h" // Sound #include "nel/sound/u_audio_mixer.h" // Client @@ -136,6 +137,9 @@ std::string LoadingBitmapFilename; uint64 StartInitTime = 0; uint64 StartPlayTime = 0; +UMaterial EffectMaterial; +NLMISC::CQuadUV EffectQuad; + // texture for the logos std::vector LogoBitmaps; @@ -568,6 +572,29 @@ void initMainLoop() // use this scene for bloom effect CBloomEffect::getInstance().setScene(Scene); + if (EffectMaterial.empty()) + { + EffectMaterial = Driver->createMaterial(); + CMaterial *mat = EffectMaterial.getObjectPtr(); + EffectMaterial.initUnlit(); + EffectMaterial.setColor(CRGBA::White); + EffectMaterial.setBlend(false); + EffectMaterial.setAlphaTest (false); + mat->setBlendFunc(CMaterial::one, CMaterial::zero); + mat->setZWrite(false); + mat->setZFunc(CMaterial::always); + mat->setDoubleSided(true); + } + + EffectQuad.V0 = CVector(0.f, 0.f, 0.5f); + EffectQuad.V1 = CVector(1.f, 0.f, 0.5f); + EffectQuad.V2 = CVector(1.f, 1.f, 0.5f); + EffectQuad.V3 = CVector(0.f, 1.f, 0.5f); + EffectQuad.Uv0 = CUV(0.f, 0.f); + EffectQuad.Uv1 = CUV(1.f, 0.f); + EffectQuad.Uv2 = CUV(1.f, 1.f); + EffectQuad.Uv3 = CUV(0.f, 1.f); + CLandscapePolyDrawer::getInstance().initLandscapePolyDrawingCallback(); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 6fd494093..1a67866ec 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -185,6 +185,9 @@ extern std::vector LogoBitmaps; extern bool IsInRingSession; extern std::string UsedFSAddr; +extern UMaterial EffectMaterial; +extern NLMISC::CQuadUV EffectQuad; + // temp extern NLMISC::CValueSmoother smoothFPS; extern NLMISC::CValueSmoother moreSmoothFPS; @@ -569,8 +572,8 @@ void renderScene(bool forceFullDetail, bool bloom) // set bloom parameters before applying bloom effect CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); - // init bloom - // CBloomEffect::getInstance().initBloom(); + + // init effect render target uint32 winw, winh; Driver->getWindowSize(winw, winh); effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); @@ -590,9 +593,25 @@ void renderScene(bool forceFullDetail, bool bloom) if (bloom) { // apply bloom effect - // CBloomEffect::getInstance().endBloom(); - // CBloomEffect::getInstance().endInterfacesDisplayBloom(); - CBloomEffect::getInstance().applyBloom(effectRenderTarget != NULL); // TODO + CBloomEffect::getInstance().applyBloom(); + + // draw final result to backbuffer + CDriverUser *dru = static_cast(Driver); + + CTextureUser texNull; + dru->setRenderTarget(texNull); + + EffectMaterial.getObjectPtr()->setTexture(0, effectRenderTarget->getITexture()); + + UCamera pCam = Scene->getCam(); + Driver->setMatrixMode2D11(); + Driver->drawQuad(EffectQuad, EffectMaterial); + Driver->setMatrixMode3D(pCam); + + EffectMaterial.getObjectPtr()->setTexture(0, NULL); + + Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); + effectRenderTarget = NULL; } } @@ -1629,8 +1648,24 @@ bool mainLoop() } uint i = 0; - uint bloomStage = 0; + bool effectRender = false; CTextureUser *effectRenderTarget = NULL; + bool haveEffects = Render && ClientCfg.Bloom; + if (haveEffects) + { + if (!StereoDisplay) + { + uint32 winw, winh; + Driver->getWindowSize(winw, winh); + effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); + static_cast(Driver)->setRenderTarget(*effectRenderTarget); + } + if (ClientCfg.Bloom) + { + CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); + CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); + } + } while ((!StereoDisplay && i == 0) || (StereoDisplay && StereoDisplay->nextPass())) { ++i; @@ -1673,22 +1708,7 @@ bool mainLoop() { if (Render) { - if (ClientCfg.Bloom && bloomStage == 0) - { - // set bloom parameters before applying bloom effect - CBloomEffect::getInstance().setSquareBloom(ClientCfg.SquareBloom); - CBloomEffect::getInstance().setDensityBloom((uint8)ClientCfg.DensityBloom); - // start bloom effect (just before the first scene element render) - if (!StereoDisplay) // FIXME: Assumes rendering to render target...! - { - uint32 winw, winh; - Driver->getWindowSize(winw, winh); - effectRenderTarget = Driver->getRenderTargetManager().getRenderTarget(winw, winh); - static_cast(Driver)->setRenderTarget(*effectRenderTarget); - } - // CBloomEffect::instance().initBloom(); - bloomStage = 1; - } + effectRender = haveEffects; } // Clear buffers @@ -1729,18 +1749,15 @@ bool mainLoop() // Render if (Render) { - if (ClientCfg.Bloom && bloomStage == 1) + if (effectRender) { - // End the actual bloom effect visible in the scene. - if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); - CBloomEffect::instance().applyBloom(effectRenderTarget != NULL); - if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); - if (effectRenderTarget) + if (ClientCfg.Bloom) { - Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); - effectRenderTarget = NULL; + if (StereoDisplay) Driver->setViewport(NL3D::CViewport()); + CBloomEffect::instance().applyBloom(); + if (StereoDisplay) Driver->setViewport(StereoDisplay->getCurrentViewport()); } - bloomStage = 0; + effectRender = false; } // for that frame and @@ -2182,6 +2199,27 @@ bool mainLoop() } } /* stereo pass */ + if (effectRenderTarget) + { + // draw final result to backbuffer + CDriverUser *dru = static_cast(Driver); + + CTextureUser texNull; + dru->setRenderTarget(texNull); + + EffectMaterial.getObjectPtr()->setTexture(0, effectRenderTarget->getITexture()); + + UCamera pCam = Scene->getCam(); + Driver->setMatrixMode2D11(); + Driver->drawQuad(EffectQuad, EffectMaterial); + Driver->setMatrixMode3D(pCam); + + EffectMaterial.getObjectPtr()->setTexture(0, NULL); + + Driver->getRenderTargetManager().recycleRenderTarget(effectRenderTarget); + effectRenderTarget = NULL; + } + // Draw to screen. static CQuat MainCamOri; if (FirstFrame) diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 3f36bca5d..c5b422fc0 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -120,6 +120,7 @@ extern bool userChar; extern bool serverReceivedReady; extern bool CharNameValidArrived; +extern UMaterial EffectMaterial; extern void releaseContextualCursor(); extern void selectTipsOfTheDay (uint tips); @@ -585,6 +586,9 @@ void release() // Delete the driver. if(Driver) { + if (!EffectMaterial.empty()) + Driver->deleteMaterial(EffectMaterial); + // Release the prim PrimFiles.release (*Driver);