diff --git a/ogre/fader.cpp b/ogre/fader.cpp new file mode 100644 index 0000000000..062559e000 --- /dev/null +++ b/ogre/fader.cpp @@ -0,0 +1,136 @@ +#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_In), + mRemainingTime(0.f), + mTargetTime(0.f), + mTargetAlpha(0.f), + mCurrentAlpha(0.f), + mStartAlpha(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 (mRemainingTime > 0) + { + if (mMode == FadingMode_In) + { + mCurrentAlpha -= dt/mTargetTime * (mStartAlpha-mTargetAlpha); + if (mCurrentAlpha < mTargetAlpha) mCurrentAlpha = mTargetAlpha; + } + else if (mMode == FadingMode_Out) + { + mCurrentAlpha += dt/mTargetTime * (mTargetAlpha-mStartAlpha); + if (mCurrentAlpha > mTargetAlpha) mCurrentAlpha = mTargetAlpha; + } + + applyAlpha(); + + mRemainingTime -= dt; + } + + 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.f) return; + if (time==0.f) + { + mCurrentAlpha = 0.f; + applyAlpha(); + return; + } + + mStartAlpha = mCurrentAlpha; + mTargetAlpha = 0.f; + mMode = FadingMode_In; + mTargetTime = time; + mRemainingTime = time; +} + +void Fader::fadeOut(const float time) +{ + 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; +} + +void Fader::fadeTo(const int percent, const float time) +{ + 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; + + mTargetTime = time; + mRemainingTime = time; +} diff --git a/ogre/fader.hpp b/ogre/fader.hpp new file mode 100644 index 0000000000..f76ac51ef9 --- /dev/null +++ b/ogre/fader.hpp @@ -0,0 +1,57 @@ +#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 + }; + + void applyAlpha(); + + Ogre::TextureUnitState* mFadeTextureUnit; + Ogre::Overlay* mOverlay; + + FadingMode mMode; + + float mRemainingTime; + float mTargetTime; + float mTargetAlpha; + float mCurrentAlpha; + float mStartAlpha; + + protected: + }; +}} +#endif diff --git a/ogre/renderer.cpp b/ogre/renderer.cpp index 137b4dd213..ccbc4e1914 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); @@ -104,4 +112,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 982534e6b7..0c2f0d3d17 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; }