diff --git a/apps/openmw/mwrender/compositors.cpp b/apps/openmw/mwrender/compositors.cpp index 4c9f08b72..d786c263b 100644 --- a/apps/openmw/mwrender/compositors.cpp +++ b/apps/openmw/mwrender/compositors.cpp @@ -26,6 +26,21 @@ void Compositors::setEnabled (const bool enabled) mEnabled = enabled; } +void Compositors::recreate() +{ + Ogre::CompositorManager::getSingleton().removeCompositorChain(mViewport); + + CompositorMap temp = mCompositors; + mCompositors.clear(); + + for (CompositorMap::iterator it=temp.begin(); + it != temp.end(); ++it) + { + addCompositor(it->first, it->second.second); + setCompositorEnabled(it->first, mEnabled && it->second.first); + } +} + void Compositors::addCompositor (const std::string& name, const int priority) { int id = 0; diff --git a/apps/openmw/mwrender/compositors.hpp b/apps/openmw/mwrender/compositors.hpp index 50b53f84a..f249ece42 100644 --- a/apps/openmw/mwrender/compositors.hpp +++ b/apps/openmw/mwrender/compositors.hpp @@ -25,6 +25,11 @@ namespace MWRender */ void setEnabled (const bool enabled); + void setViewport(Ogre::Viewport* vp) { mViewport = vp; } + + /// recreate compositors (call this after viewport size changes) + void recreate(); + bool toggle() { setEnabled(!mEnabled); return mEnabled; } /** diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 86c1f752c..e5ce6b0dd 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -11,6 +11,7 @@ #include "../mwworld/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwworld/ptr.hpp" +#include "../mwworld/player.hpp" #include "../mwbase/environment.hpp" #include #include @@ -30,6 +31,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) { mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); + mRendering.setWindowEventListener(this); mCompositors = new Compositors(mRendering.getViewport()); @@ -567,6 +569,7 @@ Compositors* RenderingManager::getCompositors() void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { + bool changeRes = false; for (Settings::CategorySettingVector::const_iterator it=settings.begin(); it != settings.end(); ++it) { @@ -574,6 +577,24 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec { setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); } + else if (it->second == "max viewing distance" && it->first == "Viewing distance") + { + if (!MWBase::Environment::get().getWorld()->isCellExterior() && !MWBase::Environment::get().getWorld()->isCellQuasiExterior()) + configureFog(*MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()); + } + else if (it->first == "Video" && ( + it->second == "resolution x" + || it->second == "resolution y" + || it->second == "fullscreen")) + changeRes = true; + } + + if (changeRes) + { + int x = Settings::Manager::getInt("resolution x", "Video"); + int y = Settings::Manager::getInt("resolution y", "Video"); + mRendering.getWindow()->resize(x, y); + mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } } @@ -587,4 +608,15 @@ void RenderingManager::setMenuTransparency(float val) tex->getBuffer()->unlock(); } +void RenderingManager::windowResized(Ogre::RenderWindow* rw) +{ + mCompositors->setViewport(mRendering.recreateViewport()); + mCompositors->recreate(); + mWater->assignTextures(); +} + +void RenderingManager::windowClosed(Ogre::RenderWindow* rw) +{ +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index edee193f3..562184c62 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -8,6 +8,8 @@ #include "../mwworld/class.hpp" +#include + #include #include #include @@ -51,7 +53,7 @@ namespace MWRender class Water; class Compositors; -class RenderingManager: private RenderingInterface { +class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { private: @@ -161,6 +163,12 @@ class RenderingManager: private RenderingInterface { void processChangedSettings(const Settings::CategorySettingVector& settings); + Ogre::Viewport* getViewport() { return mRendering.getViewport(); } + + protected: + virtual void windowResized(Ogre::RenderWindow* rw); + virtual void windowClosed(Ogre::RenderWindow* rw); + private: void setAmbientMode(); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 72f88c6c5..19e45c189 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -374,7 +374,7 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) , mSunGlare(NULL) , mMasser(NULL) , mSecunda(NULL) - , mViewport(NULL) + , mCamera(pCamera) , mRootNode(NULL) , mSceneMgr(NULL) , mAtmosphereDay(NULL) @@ -399,9 +399,8 @@ SkyManager::SkyManager (SceneNode* pMwRoot, Camera* pCamera) , mSecundaEnabled(true) , mCreated(false) { - mViewport = pCamera->getViewport(); mSceneMgr = pMwRoot->getCreator(); - mRootNode = pCamera->getParentSceneNode()->createChildSceneNode(); + mRootNode = mCamera->getParentSceneNode()->createChildSceneNode(); mRootNode->pitch(Degree(-90)); // convert MW to ogre coordinates mRootNode->setInheritOrientation(false); } @@ -741,7 +740,7 @@ void SkyManager::update(float duration) // on how directly the player is looking at the sun Vector3 sun = mSunGlare->getPosition(); sun = Vector3(sun.x, sun.z, -sun.y); - Vector3 cam = mViewport->getCamera()->getRealDirection(); + Vector3 cam = mCamera->getRealDirection(); const Degree angle = sun.angleBetween( cam ); float val = 1- (angle.valueDegrees() / 180.f); val = (val*val*val*val)*2; diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index da89d0eb0..e11745e82 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -185,7 +185,7 @@ namespace MWRender Moon* mMasser; Moon* mSecunda; - Ogre::Viewport* mViewport; + Ogre::Camera* mCamera; Ogre::SceneNode* mRootNode; Ogre::SceneManager* mSceneMgr; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index dda215999..981343e91 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -10,7 +10,7 @@ namespace MWRender { Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : - mCamera (camera), mViewport (camera->getViewport()), mSceneManager (camera->getSceneManager()), + mCamera (camera), mSceneManager (camera->getSceneManager()), mIsUnderwater(false), mVisibilityFlags(0), mReflectionTarget(0), mActive(1), mToggled(1), mReflectionRenderActive(false), mRendering(rend) @@ -80,6 +80,8 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel mSceneManager->addRenderQueueListener(this); + assignTextures(); + // ---------------------------------------------------------------------------------------------- // ---------------------------------- reflection debug overlay ---------------------------------- @@ -262,10 +264,13 @@ void Water::createMaterial() // use technique without shaders if reflection is disabled if (mReflectionTarget == 0) mMaterial->removeTechnique(0); +} +void Water::assignTextures() +{ if (Settings::Manager::getBool("shader", "Water")) { - CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mViewport)->getCompositor("gbuffer"); + CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer"); TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0); TextureUnitState* tus = mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState("refractionMap"); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 25631b4af..edd217e84 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -17,7 +17,6 @@ namespace MWRender { static const int CELL_SIZE = 8192; Ogre::Camera *mCamera; Ogre::SceneManager *mSceneManager; - Ogre::Viewport *mViewport; Ogre::Plane mWaterPlane; Ogre::SceneNode *mWaterNode; @@ -65,6 +64,8 @@ namespace MWRender { void toggle(); void update(); + void assignTextures(); + void setViewportBackground(const Ogre::ColourValue& bg); void checkUnderwater(float y); diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index ab7920ab8..579ba3dd7 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -144,3 +144,18 @@ void OgreRenderer::createScene(const std::string camName, float fov, float nearC mFader = new Fader(); } + +Ogre::Viewport* OgreRenderer::recreateViewport() +{ + mWindow->removeViewport(mView->getZOrder()); + mView = mWindow->addViewport(mCamera); + + // Alter the camera aspect ratio to match the viewport + mCamera->setAspectRatio(Real(mView->getActualWidth()) / Real(mView->getActualHeight())); + return mView; +} + +void OgreRenderer::setWindowEventListener(Ogre::WindowEventListener* listener) +{ + Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener); +} diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index 50fe64015..7a0fd11df 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -25,6 +25,7 @@ #endif #include "OgreTexture.h" +#include namespace Ogre { @@ -104,6 +105,8 @@ namespace OEngine ~OgreRenderer() { cleanup(); } + void setWindowEventListener(Ogre::WindowEventListener* listener); + /** Configure the renderer. This will load configuration files and set up the Root and logging classes. */ void configure( @@ -153,6 +156,8 @@ namespace OEngine /// Viewport Ogre::Viewport *getViewport() { return mView; } + + Ogre::Viewport* recreateViewport(); }; } }