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; }