From 9e177df61b1fe33140db6200328c32d2530e94c0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 21 Apr 2015 23:27:26 +0200 Subject: [PATCH] Add fog, view distance, and far plane culling --- apps/openmw/mwrender/renderingmanager.cpp | 54 +++++++++++++++++++++-- apps/openmw/mwrender/renderingmanager.hpp | 4 +- apps/openmw/mwworld/scene.cpp | 2 +- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 412d10ba2..b7265533c 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -5,10 +5,13 @@ #include #include #include +#include #include #include +#include + #include #include @@ -26,25 +29,49 @@ namespace MWRender class StateUpdater : public SceneUtil::StateSetUpdater { public: + StateUpdater() + : mFogEnd(0.f) + { + } + virtual void setDefaults(osg::StateSet *stateset) { osg::LightModel* lightModel = new osg::LightModel; stateset->setAttribute(lightModel, osg::StateAttribute::ON); + osg::Fog* fog = new osg::Fog; + fog->setStart(1); + stateset->setAttributeAndModes(fog, osg::StateAttribute::ON); } virtual void apply(osg::StateSet* stateset, osg::NodeVisitor*) { osg::LightModel* lightModel = static_cast(stateset->getAttribute(osg::StateAttribute::LIGHTMODEL)); lightModel->setAmbientIntensity(mAmbientColor); + osg::Fog* fog = static_cast(stateset->getAttribute(osg::StateAttribute::FOG)); + fog->setColor(mFogColor); + fog->setEnd(mFogEnd); + fog->setMode(osg::Fog::LINEAR); } - void setAmbientColor(osg::Vec4f col) + void setAmbientColor(const osg::Vec4f& col) { mAmbientColor = col; } + void setFogColor(const osg::Vec4f& col) + { + mFogColor = col; + } + + void setFogEnd(float end) + { + mFogEnd = end; + } + private: osg::Vec4f mAmbientColor; + osg::Vec4f mFogColor; + float mFogEnd; }; RenderingManager::RenderingManager(osgViewer::Viewer &viewer, osg::ref_ptr rootNode, Resource::ResourceSystem* resourceSystem) @@ -80,16 +107,25 @@ namespace MWRender source->setStateSetModes(*mRootNode->getOrCreateStateSet(), osg::StateAttribute::ON); mStateUpdater = new StateUpdater; - mRootNode->addUpdateCallback(mStateUpdater); + lightRoot->addUpdateCallback(mStateUpdater); + + osg::Camera::CullingMode cullingMode = osg::Camera::DEFAULT_CULLING|osg::Camera::FAR_PLANE_CULLING; // for consistent benchmarks against the ogre branch. remove later - osg::CullStack::CullingMode cullingMode = viewer.getCamera()->getCullingMode(); cullingMode &= ~(osg::CullStack::SMALL_FEATURE_CULLING); + viewer.getCamera()->setCullingMode( cullingMode ); + mViewer.getCamera()->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); + mViewer.getCamera()->setCullingMode(cullingMode); + + mViewDistance = Settings::Manager::getFloat("viewing distance", "Viewing distance"); + double fovy, aspect, zNear, zFar; mViewer.getCamera()->getProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar); fovy = 55.f; + zNear = 5.f; + zFar = mViewDistance; mViewer.getCamera()->setProjectionMatrixAsPerspective(fovy, aspect, zNear, zFar); } @@ -153,9 +189,19 @@ namespace MWRender mSky->setEnabled(enabled); } - void RenderingManager::configureFog(float fogDepth, const osg::Vec4f &colour) + void RenderingManager::configureFog(const ESM::Cell *cell) + { + osg::Vec4f color = SceneUtil::colourFromRGB(cell->mAmbi.mFog); + + configureFog (cell->mAmbi.mFogDensity, color); + } + + void RenderingManager::configureFog(float /* fogDepth */, const osg::Vec4f &colour) { mViewer.getCamera()->setClearColor(colour); + + mStateUpdater->setFogColor(colour); + mStateUpdater->setFogEnd(mViewDistance); } SkyManager* RenderingManager::getSkyManager() diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 61f611a8c..d8744db4a 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -53,7 +53,7 @@ namespace MWRender void setSunColour(const osg::Vec4f& colour); void configureAmbient(const ESM::Cell* cell); - + void configureFog(const ESM::Cell* cell); void configureFog(float fogDepth, const osg::Vec4f& colour); void removeCell(const MWWorld::CellStore* store); @@ -87,6 +87,8 @@ namespace MWRender osg::ref_ptr mStateUpdater; + float mViewDistance; + void operator = (const RenderingManager&); RenderingManager(const RenderingManager&); }; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index c9fd84ee3..aabe4d6d8 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -511,7 +511,7 @@ namespace MWWorld changePlayerCell(cell, position, true); // adjust fog - //mRendering.configureFog(*mCurrentCell); + mRendering.configureFog(mCurrentCell->getCell()); // Sky system MWBase::Environment::get().getWorld()->adjustSky();