From b77f5c06cc3fd818a5efbbb42d6c2a079fa91143 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 18 Feb 2012 18:25:02 +0100 Subject: [PATCH 1/2] added facilities for fading the screen in/out --- ogre/fader.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++++ ogre/fader.hpp | 54 ++++++++++++++++++++++++ ogre/renderer.cpp | 10 +++++ ogre/renderer.hpp | 7 ++++ 4 files changed, 175 insertions(+) create mode 100644 ogre/fader.cpp create mode 100644 ogre/fader.hpp diff --git a/ogre/fader.cpp b/ogre/fader.cpp new file mode 100644 index 000000000..6e15d91b7 --- /dev/null +++ b/ogre/fader.cpp @@ -0,0 +1,104 @@ +#include "fader.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define FADE_OVERLAY_NAME "FadeInOutOverlay" +#define FADE_OVERLAY_PANEL_NAME "FadeInOutOverlayPanel" +#define FADE_MATERIAL_NAME "FadeInOutMaterial" + +using namespace Ogre; +using namespace OEngine::Render; + +Fader::Fader() : + mMode(FadingMode_None), + mRemainingTime(0.f), + mTargetTime(0.f), + mTargetAlpha(0.f) +{ + + // Create the fading material + MaterialPtr material = MaterialManager::getSingleton().create( FADE_MATERIAL_NAME, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME ); + Pass* pass = material->getTechnique(0)->getPass(0); + pass->setSceneBlending(SBT_TRANSPARENT_ALPHA); + mFadeTextureUnit = pass->createTextureUnitState(); + mFadeTextureUnit->setColourOperationEx(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, ColourValue(0.f, 0.f, 0.f)); // always black colour + + // Create the overlay + OverlayManager& ovm = OverlayManager::getSingleton(); + + mOverlay = ovm.create( FADE_OVERLAY_NAME ); + + OverlayContainer* overlay_panel; + overlay_panel = (OverlayContainer*)ovm.createOverlayElement("Panel", FADE_OVERLAY_PANEL_NAME); + + // position it over the whole screen + overlay_panel->_setPosition(0, 0); + overlay_panel->_setDimensions(1, 1); + + overlay_panel->setMaterialName( FADE_MATERIAL_NAME ); + overlay_panel->show(); + mOverlay->add2D(overlay_panel); + mOverlay->hide(); +} + +void Fader::update(float dt) +{ + if (mMode == FadingMode_None) return; + + if (mRemainingTime > 0) + { + mOverlay->show(); + float alpha; + if (mMode == FadingMode_In) + alpha = (mRemainingTime/mTargetTime) * 1.f; + else if (mMode == FadingMode_Out) + alpha = (1-(mRemainingTime/mTargetTime)) * 1.f; + else if (mMode == FadingMode_To) + alpha = (1-(mRemainingTime/mTargetTime)) * mTargetAlpha; + + mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, alpha); + + mRemainingTime -= dt; + } + else + { + mMode = FadingMode_None; + mOverlay->hide(); + } +} + +void Fader::fadeIn(float time) +{ + if (time<=0) return; + + mMode = FadingMode_In; + mTargetTime = time; + mRemainingTime = time; +} + +void Fader::fadeOut(const float time) +{ + if (time<=0) return; + + mMode = FadingMode_Out; + mTargetTime = time; + mRemainingTime = time; +} + +void Fader::fadeTo(const int percent, const float time) +{ + if (time<=0) return; + + mMode = FadingMode_To; + mTargetTime = time; + mRemainingTime = time; + mTargetAlpha = percent/100.f; +} diff --git a/ogre/fader.hpp b/ogre/fader.hpp new file mode 100644 index 000000000..0bc96acfa --- /dev/null +++ b/ogre/fader.hpp @@ -0,0 +1,54 @@ +#ifndef OENGINE_OGRE_FADE_H +#define OENGINE_OGRE_FADE_H + +/* + A class that handles fading in the screen from black or fading it out to black. + + To achieve this, it uses a full-screen Ogre::Overlay + + inspired by http://www.ogre3d.org/tikiwiki/FadeEffectOverlay (heavily adjusted) + */ + +#include + +namespace Ogre +{ + class TextureUnitState; + class Overlay; +} + +namespace OEngine { +namespace Render +{ + class Fader + { + public: + Fader(); + + void update(float dt); + + void fadeIn(const float time); + void fadeOut(const float time); + void fadeTo(const int percent, const float time); + + private: + enum FadingMode + { + FadingMode_In, + FadingMode_Out, + FadingMode_To, + FadingMode_None // no fading + }; + + Ogre::TextureUnitState* mFadeTextureUnit; + Ogre::Overlay* mOverlay; + + FadingMode mMode; + float mRemainingTime; + float mTargetTime; + float mTargetAlpha; + + protected: + }; +}} +#endif diff --git a/ogre/renderer.cpp b/ogre/renderer.cpp index ca263d815..1ce1d2609 100644 --- a/ogre/renderer.cpp +++ b/ogre/renderer.cpp @@ -1,4 +1,5 @@ #include "renderer.hpp" +#include "fader.hpp" #include "OgreRoot.h" #include "OgreRenderWindow.h" @@ -12,6 +13,8 @@ using namespace OEngine::Render; void OgreRenderer::cleanup() { + delete mFader; + if(mRoot) delete mRoot; mRoot = NULL; @@ -22,6 +25,11 @@ void OgreRenderer::start() mRoot->startRendering(); } +void OgreRenderer::update(float dt) +{ + mFader->update(dt); +} + void OgreRenderer::screenshot(const std::string &file) { mWindow->writeContentsToFile(file); @@ -98,4 +106,6 @@ void OgreRenderer::createScene(const std::string camName, float fov, float nearC // Alter the camera aspect ratio to match the viewport mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight())); + + mFader = new Fader(); } diff --git a/ogre/renderer.hpp b/ogre/renderer.hpp index 982534e6b..0c2f0d3d1 100644 --- a/ogre/renderer.hpp +++ b/ogre/renderer.hpp @@ -19,6 +19,7 @@ namespace Ogre namespace OEngine { namespace Render { + class Fader; class OgreRenderer { Ogre::Root *mRoot; @@ -26,6 +27,7 @@ namespace Render Ogre::SceneManager *mScene; Ogre::Camera *mCamera; Ogre::Viewport *mView; + Fader* mFader; bool logging; public: @@ -66,6 +68,8 @@ namespace Render /// Start the main rendering loop void start(); + + void update(float dt); /// Write a screenshot to file void screenshot(const std::string &file); @@ -80,6 +84,9 @@ namespace Render /// Get the scene manager Ogre::SceneManager *getScene() { return mScene; } + + /// Get the screen colour fader + Fader *getFader() { return mFader; } /// Camera Ogre::Camera *getCamera() { return mCamera; } From eb61ba59e64c332931c12251cac40de5836ff9cd Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 19 Feb 2012 17:45:57 +0100 Subject: [PATCH 2/2] updated the fading calculation (the alpha value stays now, even after the specified time - this is how it is in morrowind) --- ogre/fader.cpp | 82 +++++++++++++++++++++++++++++++++++--------------- ogre/fader.hpp | 11 ++++--- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/ogre/fader.cpp b/ogre/fader.cpp index 6e15d91b7..062559e00 100644 --- a/ogre/fader.cpp +++ b/ogre/fader.cpp @@ -18,10 +18,12 @@ using namespace Ogre; using namespace OEngine::Render; Fader::Fader() : - mMode(FadingMode_None), + mMode(FadingMode_In), mRemainingTime(0.f), mTargetTime(0.f), - mTargetAlpha(0.f) + mTargetAlpha(0.f), + mCurrentAlpha(0.f), + mStartAlpha(0.f) { // Create the fading material @@ -50,35 +52,46 @@ Fader::Fader() : } void Fader::update(float dt) -{ - if (mMode == FadingMode_None) return; - +{ if (mRemainingTime > 0) { - mOverlay->show(); - float alpha; if (mMode == FadingMode_In) - alpha = (mRemainingTime/mTargetTime) * 1.f; + { + mCurrentAlpha -= dt/mTargetTime * (mStartAlpha-mTargetAlpha); + if (mCurrentAlpha < mTargetAlpha) mCurrentAlpha = mTargetAlpha; + } else if (mMode == FadingMode_Out) - alpha = (1-(mRemainingTime/mTargetTime)) * 1.f; - else if (mMode == FadingMode_To) - alpha = (1-(mRemainingTime/mTargetTime)) * mTargetAlpha; - - mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, alpha); + { + mCurrentAlpha += dt/mTargetTime * (mTargetAlpha-mStartAlpha); + if (mCurrentAlpha > mTargetAlpha) mCurrentAlpha = mTargetAlpha; + } + + applyAlpha(); mRemainingTime -= dt; } - else - { - mMode = FadingMode_None; - mOverlay->hide(); - } + + if (mCurrentAlpha == 0.f) mOverlay->hide(); +} + +void Fader::applyAlpha() +{ + mOverlay->show(); + mFadeTextureUnit->setAlphaOperation(LBX_SOURCE1, LBS_MANUAL, LBS_CURRENT, mCurrentAlpha); } void Fader::fadeIn(float time) { - if (time<=0) return; - + if (time<0.f) return; + if (time==0.f) + { + mCurrentAlpha = 0.f; + applyAlpha(); + return; + } + + mStartAlpha = mCurrentAlpha; + mTargetAlpha = 0.f; mMode = FadingMode_In; mTargetTime = time; mRemainingTime = time; @@ -86,8 +99,16 @@ void Fader::fadeIn(float time) void Fader::fadeOut(const float time) { - if (time<=0) return; - + if (time<0.f) return; + if (time==0.f) + { + mCurrentAlpha = 1.f; + applyAlpha(); + return; + } + + mStartAlpha = mCurrentAlpha; + mTargetAlpha = 1.f; mMode = FadingMode_Out; mTargetTime = time; mRemainingTime = time; @@ -95,10 +116,21 @@ void Fader::fadeOut(const float time) void Fader::fadeTo(const int percent, const float time) { - if (time<=0) return; + if (time<0.f) return; + if (time==0.f) + { + mCurrentAlpha = percent/100.f; + applyAlpha(); + return; + } + + mStartAlpha = mCurrentAlpha; + mTargetAlpha = percent/100.f; + + if (mTargetAlpha == mStartAlpha) return; + else if (mTargetAlpha > mStartAlpha) mMode = FadingMode_Out; + else mMode = FadingMode_In; - mMode = FadingMode_To; mTargetTime = time; mRemainingTime = time; - mTargetAlpha = percent/100.f; } diff --git a/ogre/fader.hpp b/ogre/fader.hpp index 0bc96acfa..f76ac51ef 100644 --- a/ogre/fader.hpp +++ b/ogre/fader.hpp @@ -30,23 +30,26 @@ namespace Render void fadeIn(const float time); void fadeOut(const float time); void fadeTo(const int percent, const float time); - + private: enum FadingMode { FadingMode_In, - FadingMode_Out, - FadingMode_To, - FadingMode_None // no fading + FadingMode_Out }; + + void applyAlpha(); Ogre::TextureUnitState* mFadeTextureUnit; Ogre::Overlay* mOverlay; FadingMode mMode; + float mRemainingTime; float mTargetTime; float mTargetAlpha; + float mCurrentAlpha; + float mStartAlpha; protected: };