From 15e51b76de89c8366d6573700f63f6f6290c7e3d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Feb 2013 15:46:23 +0100 Subject: [PATCH] Experimental: Directional shading on local map, separated out refraction render, no longer uses screen depth --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/loadingscreen.cpp | 2 +- apps/openmw/mwrender/characterpreview.cpp | 9 ++-- apps/openmw/mwrender/localmap.cpp | 34 +++++++++---- apps/openmw/mwrender/localmap.hpp | 9 +++- apps/openmw/mwrender/npcanimation.cpp | 6 ++- apps/openmw/mwrender/occlusionquery.cpp | 7 ++- apps/openmw/mwrender/occlusionquery.hpp | 8 +++ apps/openmw/mwrender/refraction.cpp | 62 +++++++++++++++++++++++ apps/openmw/mwrender/refraction.hpp | 36 +++++++++++++ apps/openmw/mwrender/renderconst.hpp | 4 +- apps/openmw/mwrender/renderingmanager.cpp | 53 ++++++++++++------- apps/openmw/mwrender/renderingmanager.hpp | 8 +-- apps/openmw/mwrender/ripplesimulation.cpp | 11 ++-- apps/openmw/mwrender/ripplesimulation.hpp | 3 -- apps/openmw/mwrender/sky.cpp | 4 ++ apps/openmw/mwrender/sky.hpp | 1 + apps/openmw/mwrender/water.cpp | 34 +++++++++---- apps/openmw/mwrender/water.hpp | 5 +- apps/openmw/mwworld/weather.cpp | 4 +- extern/shiny/Main/Factory.cpp | 2 - files/materials/openmw.configuration | 1 - files/materials/water.mat | 2 +- files/materials/water.shader | 22 ++------ libs/openengine/ogre/renderer.cpp | 13 +++++ 25 files changed, 250 insertions(+), 92 deletions(-) create mode 100644 apps/openmw/mwrender/refraction.cpp create mode 100644 apps/openmw/mwrender/refraction.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 2c49e848e..94952329e 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -16,7 +16,7 @@ source_group(game FILES ${GAME} ${GAME_HEADER}) add_openmw_dir (mwrender renderingmanager debugging sky player animation npcanimation creatureanimation actors objects renderinginterface localmap occlusionquery terrain terrainmaterial water shadows - compositors characterpreview externalrendering globalmap videoplayer ripplesimulation + compositors characterpreview externalrendering globalmap videoplayer ripplesimulation refraction ) add_openmw_dir (mwinput diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index dd5289edb..8fecf4c34 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -150,7 +150,7 @@ namespace MWGui if (!mFirstLoad) { mBackgroundMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName(chain->getCompositor ("gbufferFinalizer")->getTextureInstance ("no_mrt_output", 0)->getName()); - mRectangle->setVisible(true); + //mRectangle->setVisible(true); } for (unsigned int i = 0; igetNumCompositors(); ++i) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index a172d02b1..704d0b6fd 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -59,7 +59,7 @@ namespace MWRender mNode = renderRoot->createChildSceneNode(); mAnimation = new NpcAnimation(mCharacter, mNode, - MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview); + MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0); mNode->setVisible (false); @@ -81,7 +81,6 @@ namespace MWRender mViewport->setOverlaysEnabled(false); mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); mViewport->setShadowsEnabled(false); - mViewport->setVisibilityMask (RV_PlayerPreview); mRenderTarget->setActive(true); mRenderTarget->setAutoUpdated (false); @@ -102,7 +101,7 @@ namespace MWRender delete mAnimation; mAnimation = new NpcAnimation(mCharacter, mNode, - MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), RV_PlayerPreview); + MWWorld::Class::get(mCharacter).getInventoryStore (mCharacter), 0); mNode->setVisible (false); @@ -118,6 +117,7 @@ namespace MWRender InventoryPreview::InventoryPreview(MWWorld::Ptr character) : CharacterPreview(character, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0)) + , mSelectionBuffer(NULL) { } @@ -149,7 +149,8 @@ namespace MWRender void InventoryPreview::onSetup () { - mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); + if (!mSelectionBuffer) + mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, 0); mAnimation->playGroup ("inventoryhandtohand", 0, 1); mAnimation->runAnimation (0); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index b34942d28..1d338df12 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -32,6 +32,12 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag mCellCamera->setOrientation(Quaternion(sqrt0pt5, -sqrt0pt5, 0, 0)); mCameraNode->attachObject(mCellCamera); + + mLight = mRendering->getScene()->createLight(); + mLight->setType (Ogre::Light::LT_DIRECTIONAL); + mLight->setDirection (Ogre::Vector3(0.3, -0.7, 0.3)); + mLight->setVisible (false); + mLight->setDiffuseColour (ColourValue(0.7,0.7,0.7)); } LocalMap::~LocalMap() @@ -181,17 +187,14 @@ void LocalMap::render(const float x, const float y, const float zlow, const float zhigh, const float xw, const float yw, const std::string& texture) { - // disable fog - // changing FOG_MODE is not a solution when using shaders, thus we have to push linear start/end + // disable fog (only necessary for fixed function, the shader based + // materials already do this through local_map material configuration) const float fStart = mRendering->getScene()->getFogStart(); const float fEnd = mRendering->getScene()->getFogEnd(); const ColourValue& clr = mRendering->getScene()->getFogColour(); - mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, 1000000, 10000000); + mRendering->getScene()->setFog(FOG_NONE); // make everything visible - mRendering->getScene()->setAmbientLight(ColourValue(1,1,1)); - mRenderingManager->disableLights(); - mCameraNode->setPosition(Vector3(x, zhigh+100000, y)); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); mCellCamera->setFarClipDistance(0); // infinite @@ -231,7 +234,8 @@ void LocalMap::render(const float x, const float y, // use fallback techniques without shadows and without mrt vp->setMaterialScheme("local_map"); - rtt->update(); + rtt->setAutoUpdated(true); + rtt->addListener(this); // create "fog of war" texture TexturePtr tex2 = TextureManager::getSingleton().createManual( @@ -263,12 +267,24 @@ void LocalMap::render(const float x, const float y, } } - mRenderingManager->enableLights(); - // re-enable fog mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); } +void LocalMap::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) +{ + mRenderingManager->disableLights(true); + mLight->setVisible(true); + evt.source->setAutoUpdated(false); +} + +void LocalMap::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) +{ + mRenderingManager->enableLights(true); + mLight->setVisible(false); + evt.source->removeListener(this); +} + void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) { pos = rotatePoint(pos, Vector2(mBounds.getCenter().x, mBounds.getCenter().z), mAngle); diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 1aedf1325..2b1aa3f62 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -4,6 +4,7 @@ #include #include +#include namespace MWWorld { @@ -17,7 +18,7 @@ namespace MWRender /// /// \brief Local map rendering /// - class LocalMap + class LocalMap : public Ogre::RenderTargetListener { public: LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering); @@ -69,6 +70,9 @@ namespace MWRender */ bool isPositionExplored (float nX, float nY, int x, int y, bool interior); + void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + private: OEngine::Render::OgreRenderer* mRendering; MWRender::RenderingManager* mRenderingManager; @@ -90,6 +94,9 @@ namespace MWRender Ogre::SceneNode* mCameraPosNode; Ogre::SceneNode* mCameraRotNode; + // directional light from a fixed angle + Ogre::Light* mLight; + float mAngle; const Ogre::Vector2 rotatePoint(const Ogre::Vector2& p, const Ogre::Vector2& c, const float angle); diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index d33bdda91..52ad24523 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -95,7 +95,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, MWWor base->getUserObjectBindings ().setUserAny (Ogre::Any(-1)); - base->setVisibilityFlags(mVisibilityFlags); + if (mVisibilityFlags != 0) + base->setVisibilityFlags(mVisibilityFlags); bool transparent = false; for(unsigned int j=0;j < base->getNumSubEntities();++j) { @@ -362,7 +363,8 @@ NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int std::vector &parts = entities.mEntities; for(size_t i = 0;i < parts.size();i++) { - parts[i]->setVisibilityFlags(mVisibilityFlags); + if (mVisibilityFlags != 0) + parts[i]->setVisibilityFlags(mVisibilityFlags); parts[i]->getUserObjectBindings ().setUserAny (Ogre::Any(group)); } return entities; diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 6d3f67de9..c9e649fe6 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -16,7 +16,7 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0), mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false), - mBBNode(0) + mBBNode(0), mActive(false) { mRendering = renderer; mSunNode = sunNode; @@ -108,8 +108,9 @@ bool OcclusionQuery::supported() void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source, const LightList* pLightList, bool suppressRenderStateChanges) { + if (!mActive) return; // The following code activates and deactivates the occlusion queries - // so that the queries only include the rendering of their intended targets + // so that the queries only include the rendering of the intended meshes // Close the last occlusion query // Each occlusion query should only last a single rendering @@ -146,6 +147,8 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass void OcclusionQuery::renderQueueEnded(uint8 queueGroupId, const String& invocation, bool& repeatThisInvocation) { + if (!mActive) return; + if (mActiveQuery != NULL) { mActiveQuery->endOcclusionQuery(); diff --git a/apps/openmw/mwrender/occlusionquery.hpp b/apps/openmw/mwrender/occlusionquery.hpp index c76fcccd0..af6f668c1 100644 --- a/apps/openmw/mwrender/occlusionquery.hpp +++ b/apps/openmw/mwrender/occlusionquery.hpp @@ -29,6 +29,12 @@ namespace MWRender */ bool supported(); + /** + * make sure to disable occlusion queries before updating unrelated render targets + * @param active + */ + void setActive (bool active) { mActive = active; } + /** * per-frame update */ @@ -85,6 +91,8 @@ namespace MWRender bool mTestResult; + bool mActive; + bool mSupported; bool mDoQuery; bool mDoQuery2; diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp new file mode 100644 index 000000000..175b85223 --- /dev/null +++ b/apps/openmw/mwrender/refraction.cpp @@ -0,0 +1,62 @@ +#include "refraction.hpp" + +#include +#include +#include +#include +#include +#include + +#include "renderconst.hpp" + +namespace MWRender +{ + + Refraction::Refraction(Ogre::Camera *parentCamera) + : mParentCamera(parentCamera) + { + mCamera = mParentCamera->getSceneManager()->createCamera("RefractionCamera"); + + Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().createManual("WaterRefraction", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET); + + mRenderTarget = texture->getBuffer()->getRenderTarget(); + Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera); + vp->setOverlaysEnabled(false); + vp->setShadowsEnabled(false); + vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain); + mRenderTarget->setAutoUpdated(true); + mRenderTarget->addListener(this); + } + + Refraction::~Refraction() + { + Ogre::TextureManager::getSingleton().remove("WaterRefraction"); + mParentCamera->getSceneManager()->destroyCamera(mCamera); + mRenderTarget->removeListener(this); + } + + void Refraction::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) + { + mParentCamera->getParentSceneNode ()->needUpdate (); + mCamera->setOrientation(mParentCamera->getDerivedOrientation()); + mCamera->setPosition(mParentCamera->getDerivedPosition()); + mCamera->setNearClipDistance(mParentCamera->getNearClipDistance()); + mCamera->setFarClipDistance(mParentCamera->getFarClipDistance()); + mCamera->setAspectRatio(mParentCamera->getAspectRatio()); + mCamera->setFOVy(mParentCamera->getFOVy()); + + mCamera->enableCustomNearClipPlane(mNearClipPlane); + } + + void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) + { + + } + + void Refraction::setWaterPlane(Ogre::Plane plane) + { + mNearClipPlane = Ogre::Plane(-plane.normal, - (plane.d + 5) ); + } + +} diff --git a/apps/openmw/mwrender/refraction.hpp b/apps/openmw/mwrender/refraction.hpp new file mode 100644 index 000000000..01ec86521 --- /dev/null +++ b/apps/openmw/mwrender/refraction.hpp @@ -0,0 +1,36 @@ +#ifndef MWRENDER_REFRACTION_H +#define MWRENDER_REFRACTION_H + +#include +#include + +namespace Ogre +{ + class Camera; + class RenderTarget; +} + +namespace MWRender +{ + + class Refraction : public Ogre::RenderTargetListener + { + + public: + Refraction(Ogre::Camera* parentCamera); + ~Refraction(); + + void setWaterPlane (Ogre::Plane plane); + void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + + private: + Ogre::Camera* mParentCamera; + Ogre::Camera* mCamera; + Ogre::RenderTarget* mRenderTarget; + Ogre::Plane mNearClipPlane; + }; + +} + +#endif diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index 75e243ec7..ee7e023a1 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -54,9 +54,7 @@ enum VisibilityFlags RV_OcclusionQuery = 256, - RV_PlayerPreview = 512, - - RV_Debug = 1024, + RV_Debug = 512, RV_Map = RV_Terrain + RV_Statics + RV_StaticsSmall + RV_Misc + RV_Water }; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 3fed4d994..18337c7d7 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -334,8 +334,13 @@ void RenderingManager::update (float duration, bool paused) mPlayer->setCameraDistance(test.second * orig.distance(dest), false, false); } } + mOcclusionQuery->update(duration); - + + // deactivate queries to make sure we aren't getting false results from several misc render targets + // (will be reactivated at the bottom of this method) + mOcclusionQuery->setActive(false); + mVideoPlayer->update (); mRendering.update(duration); @@ -391,6 +396,8 @@ void RenderingManager::update (float duration, bool paused) orig = Ogre::Vector3(orig.x, orig.z, -orig.y); mWater->update(duration, orig); } + + mOcclusionQuery->setActive(true); } void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store) @@ -608,22 +615,28 @@ void RenderingManager::setAmbientColour(const Ogre::ColourValue& colour) mTerrainManager->setAmbient(colour); } -void RenderingManager::sunEnable() +void RenderingManager::sunEnable(bool real) { - // Don't disable the light, as the shaders assume the first light to be directional. - //if (mSun) mSun->setVisible(true); - mSunEnabled = true; + if (real && mSun) mSun->setVisible(true); + else + { + // Don't disable the light, as the shaders assume the first light to be directional. + mSunEnabled = true; + } } -void RenderingManager::sunDisable() +void RenderingManager::sunDisable(bool real) { - // Don't disable the light, as the shaders assume the first light to be directional. - //if (mSun) mSun->setVisible(false); - mSunEnabled = false; - if (mSun) + if (real && mSun) mSun->setVisible(false); + else { - mSun->setDiffuseColour(ColourValue(0,0,0)); - mSun->setSpecularColour(ColourValue(0,0,0)); + // Don't disable the light, as the shaders assume the first light to be directional. + mSunEnabled = false; + if (mSun) + { + mSun->setDiffuseColour(ColourValue(0,0,0)); + mSun->setSpecularColour(ColourValue(0,0,0)); + } } } @@ -654,16 +667,16 @@ void RenderingManager::preCellChange(MWWorld::Ptr::CellStore* cell) mLocalMap->saveFogOfWar(cell); } -void RenderingManager::disableLights() +void RenderingManager::disableLights(bool sun) { mObjects.disableLights(); - sunDisable(); + sunDisable(sun); } -void RenderingManager::enableLights() +void RenderingManager::enableLights(bool sun) { mObjects.enableLights(); - sunEnable(); + sunEnable(sun); } const bool RenderingManager::useMRT() @@ -867,14 +880,16 @@ void RenderingManager::applyCompositors() mCompositors->removeAll(); if (useMRT()) { + /* mCompositors->addCompositor("gbuffer", 0); mCompositors->setCompositorEnabled("gbuffer", true); mCompositors->addCompositor("gbufferFinalizer", 2); mCompositors->setCompositorEnabled("gbufferFinalizer", true); - } + */ +} - if (mWater) - mWater->assignTextures(); + //if (mWater) + //mWater->assignTextures(); } void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 68f2d79c3..0a92bb2ea 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -131,11 +131,11 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void setAmbientColour(const Ogre::ColourValue& colour); void setSunColour(const Ogre::ColourValue& colour); void setSunDirection(const Ogre::Vector3& direction); - void sunEnable(); - void sunDisable(); + void sunEnable(bool real); ///< @param real whether or not to really disable the sunlight (otherwise just set diffuse to 0) + void sunDisable(bool real); - void disableLights(); - void enableLights(); + void disableLights(bool sun); ///< @param sun whether or not to really disable the sunlight (otherwise just set diffuse to 0) + void enableLights(bool sun); bool occlusionQuerySupported() { return mOcclusionQuery->supported(); } OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; } diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index 6096c7ba3..043757e88 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -25,10 +25,6 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) Ogre::AxisAlignedBox aabInf; aabInf.setInfinite(); - - mHeightToNormalMapMaterial = Ogre::MaterialManager::getSingleton().getByName("HeightToNormalMap"); - mHeightmapMaterial = Ogre::MaterialManager::getSingleton().getByName("HeightmapSimulation"); - mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); mCamera = mSceneMgr->createCamera("RippleCamera"); @@ -46,7 +42,7 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) Ogre::SceneNode* impulseNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); impulseNode->attachObject(mImpulse); - float w=0.05; + //float w=0.05; for (int i=0; i<4; ++i) { Ogre::TexturePtr texture; @@ -65,11 +61,11 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) rt->getViewport(0)->setClearEveryFrame(false); // debug overlay + /* Ogre::Rectangle2D* debugOverlay = new Ogre::Rectangle2D(true); debugOverlay->setCorners(w*2-1, 0.9, (w+0.18)*2-1, 0.4, false); w += 0.2; debugOverlay->setBoundingBox(aabInf); - Ogre::SceneNode* debugNode = mMainSceneMgr->getRootSceneNode()->createChildSceneNode(); debugNode->attachObject(debugOverlay); @@ -83,6 +79,7 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) debugMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false); debugOverlay->setMaterial("RippleDebug" + Ogre::StringConverter::toString(i)); + */ mRenderTargets[i] = rt; mTextures[i] = texture; @@ -126,8 +123,6 @@ void RippleSimulation::update(float dt, Ogre::Vector2 position) // texture coordinate space mCurrentFrameOffset /= mRippleAreaLength; - std::cout << "Offset " << mCurrentFrameOffset << std::endl; - mRippleCenter = position; addImpulses(); diff --git a/apps/openmw/mwrender/ripplesimulation.hpp b/apps/openmw/mwrender/ripplesimulation.hpp index 6096fa866..72ff3dbd8 100644 --- a/apps/openmw/mwrender/ripplesimulation.hpp +++ b/apps/openmw/mwrender/ripplesimulation.hpp @@ -43,9 +43,6 @@ private: // scenemanager to create the debug overlays on Ogre::SceneManager* mMainSceneMgr; - Ogre::MaterialPtr mHeightmapMaterial; - Ogre::MaterialPtr mHeightToNormalMapMaterial; - static const int TEX_NORMAL = 3; Ogre::Rectangle2D* mImpulse; diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 60ecd4303..91277ebf6 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -628,6 +628,10 @@ void SkyManager::setLightningStrength(const float factor) else mLightning->setVisible(false); } +void SkyManager::setLightningEnabled(bool enabled) +{ + /// \todo +} void SkyManager::setLightningDirection(const Ogre::Vector3& dir) { diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index ee1360853..04d56d4af 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -167,6 +167,7 @@ namespace MWRender void setLightningStrength(const float factor); void setLightningDirection(const Ogre::Vector3& dir); + void setLightningEnabled(bool enabled); ///< disable prior to map render void setGlare(const float glare); void setGlareEnabled(bool enabled); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 6ee3890dd..0533388bc 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -13,6 +13,7 @@ #include "renderingmanager.hpp" #include "compositors.hpp" #include "ripplesimulation.hpp" +#include "refraction.hpp" #include #include @@ -85,7 +86,7 @@ PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* s mSceneMgr->addRenderQueueListener(this); mTexture = TextureManager::getSingleton().createManual("WaterReflection", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 0, PF_A8R8G8B8, TU_RENDERTARGET); + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 0, PF_R8G8B8, TU_RENDERTARGET); mRenderTarget = mTexture->getBuffer()->getRenderTarget(); Viewport* vp = mRenderTarget->addViewport(mCamera); @@ -96,6 +97,7 @@ PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* s vp->setMaterialScheme("water_reflection"); mRenderTarget->addListener(this); mRenderTarget->setActive(true); + mRenderTarget->setAutoUpdated(true); sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mTexture->getName()); } @@ -104,6 +106,7 @@ PlaneReflection::~PlaneReflection () { mRenderTarget->removeListener (this); mSceneMgr->destroyCamera (mCamera); + mSceneMgr->removeRenderQueueListener(this); TextureManager::getSingleton ().remove("WaterReflection"); } @@ -127,7 +130,7 @@ void PlaneReflection::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::St } } -void PlaneReflection::preRenderTargetUpdate(const RenderTargetEvent& evt) +void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) { mParentCamera->getParentSceneNode ()->needUpdate (); mCamera->setOrientation(mParentCamera->getDerivedOrientation()); @@ -144,7 +147,7 @@ void PlaneReflection::preRenderTargetUpdate(const RenderTargetEvent& evt) mCamera->enableReflection(mWaterPlane); } -void PlaneReflection::postRenderTargetUpdate(const RenderTargetEvent& evt) +void PlaneReflection::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) { mSky->resetSkyPosition(); mCamera->disableReflection(); @@ -232,7 +235,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water"); m->setListener (this); - // ---------------------------------------------------------------------------------------------- // ---------------------------------- reflection debug overlay ---------------------------------- // ---------------------------------------------------------------------------------------------- @@ -296,6 +298,9 @@ Water::~Water() mWaterNode->detachObject(mWater); mSceneMgr->destroyEntity(mWater); mSceneMgr->destroySceneNode(mWaterNode); + + delete mReflection; + delete mRefraction; } void Water::changeCell(const ESM::Cell* cell) @@ -316,6 +321,8 @@ void Water::setHeight(const float height) if (mReflection) mReflection->setWaterPlane(mWaterPlane); + if (mRefraction) + mRefraction->setWaterPlane(mWaterPlane); mWaterNode->setPosition(0, height, 0); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty(new sh::FloatValue(height))); @@ -353,7 +360,7 @@ void Water::assignTextures() { if (Settings::Manager::getBool("shader", "Water")) { - +/* CompositorInstance* compositor = CompositorManager::getSingleton().getCompositorChain(mRendering->getViewport())->getCompositor("gbuffer"); TexturePtr colorTexture = compositor->getTextureInstance("mrt_output", 0); @@ -361,6 +368,7 @@ void Water::assignTextures() TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1); sh::Factory::getInstance ().setTextureAlias ("SceneDepth", depthTexture->getName()); + */ } } @@ -397,15 +405,15 @@ void Water::update(float dt, Ogre::Vector3 player) mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); } mSimulation->update(dt, Ogre::Vector2(player.x, player.z)); + + if (mReflection) + mReflection->update(); } void Water::applyRTT() { - if (mReflection) - { - delete mReflection; - mReflection = NULL; - } + delete mReflection; + mReflection = NULL; // Create rendertarget for reflection int rttsize = Settings::Manager::getInt("rtt size", "Water"); @@ -419,6 +427,12 @@ void Water::applyRTT() } else mWater->setRenderQueueGroup(RQG_Alpha); + + + delete mRefraction; + mRefraction = NULL; + + mRefraction = new Refraction(mCamera); } void Water::applyVisibilityMask() diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 97eb590b3..67c788c81 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -30,12 +30,14 @@ namespace MWRender { class SkyManager; class RenderingManager; class RippleSimulation; + class Refraction; class Reflection { public: Reflection(Ogre::SceneManager* sceneManager) : mSceneMgr(sceneManager) {} + virtual ~Reflection() {} virtual void setWaterPlane (Ogre::Plane plane) {} virtual void setParentCamera (Ogre::Camera* parent) { mParentCamera = parent; } @@ -111,7 +113,6 @@ namespace MWRender { float mWaterTimer; - RippleSimulation* mSimulation; Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); @@ -132,6 +133,8 @@ namespace MWRender { int mVisibilityFlags; Reflection* mReflection; + Refraction* mRefraction; + RippleSimulation* mSimulation; public: Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell); diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 917a8d7d4..514276f9b 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -718,14 +718,14 @@ void WeatherManager::update(float duration) mRendering->getSkyManager()->setLightningStrength(0.f); mRendering->setAmbientColour(result.mAmbientColor); - mRendering->sunEnable(); + mRendering->sunEnable(false); mRendering->setSunColour(result.mSunColor); mRendering->getSkyManager()->setWeather(result); } else { - mRendering->sunDisable(); + mRendering->sunDisable(false); mRendering->skyDisable(); mRendering->getSkyManager()->setLightningStrength(0.f); } diff --git a/extern/shiny/Main/Factory.cpp b/extern/shiny/Main/Factory.cpp index 6e87800e5..82d664811 100644 --- a/extern/shiny/Main/Factory.cpp +++ b/extern/shiny/Main/Factory.cpp @@ -219,8 +219,6 @@ namespace sh break; } - std::cout << "loading " << it->first << std::endl; - MaterialInstance newInstance(it->first, this); newInstance.create(mPlatform); if (!mShadersEnabled) diff --git a/files/materials/openmw.configuration b/files/materials/openmw.configuration index ee97451d3..db3693dd6 100644 --- a/files/materials/openmw.configuration +++ b/files/materials/openmw.configuration @@ -10,7 +10,6 @@ configuration local_map { fog false mrt_output false - lighting false shadows false shadows_pssm false simple_water true diff --git a/files/materials/water.mat b/files/materials/water.mat index c427447d2..2717f26fc 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -20,7 +20,7 @@ material Water texture_unit refractionMap { - texture_alias WaterRefraction + direct_texture WaterRefraction tex_address_mode clamp } diff --git a/files/materials/water.shader b/files/materials/water.shader index 1e14dd596..dbe36a91c 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -201,13 +201,9 @@ SH_START_PROGRAM { - float2 screenCoords = screenCoordsPassthrough.xy / screenCoordsPassthrough.z; screenCoords.y = (1-shSaturate(renderTargetFlipping))+renderTargetFlipping*screenCoords.y; - float depth = shSample(depthMap, screenCoords).x * far - depthPassthrough; - float shoreFade = shSaturate(depth / 50.0); - float2 nCoord = float2(0,0); nCoord = UV * (WAVE_SCALE * 0.05) + WIND_DIR * waterTimer * (WIND_SPEED*0.04); @@ -272,14 +268,8 @@ // refraction float3 R = reflect(vVec, normal); - - // check the depth at the refracted coords, and don't do any normal distortion for the refraction if the object to refract - // is actually above the water (objectDepth < waterDepth) - // this solves silhouettes around objects above the water - float refractDepth = shSample(depthMap, screenCoords-(shoreFade * normal.xz*REFR_BUMP)).x * far - depthPassthrough; - float doRefraction = (refractDepth < 0) ? 0.f : 1.f; - - float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(shoreFade * normal.xz*REFR_BUMP * doRefraction))*1.0).rgb); + + float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(normal.xz*REFR_BUMP))*1.0).rgb); // brighten up the refraction underwater refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction; @@ -288,10 +278,7 @@ float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS); shOutputColour(0).xyz = shLerp( shLerp(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * sunSpecular.xyz; - - // smooth transition to shore (above water only) - shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, refraction, (1-shoreFade) * (1-isUnderwater)); - + // fog if (isUnderwater == 1) { @@ -319,8 +306,7 @@ } shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - //shOutputColour(0).xyz = float3(relPos.x, relPos.y, 0); - shOutputColour(0).w = 1; + shOutputColour(0).w = 1; } #endif diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index ed5cc9b43..e6e1d46b8 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -210,11 +210,24 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& assert(mRoot); mRoot->initialise(false); + // create a hidden 1x1 background window to keep resources when recreating the secondary (real) window + /// \todo Why does this break occlusion queries? :( + /* + NameValuePairList params_; + params_.insert(std::make_pair("title", title)); + params_.insert(std::make_pair("FSAA", "0")); + params_.insert(std::make_pair("vsync", "false")); + params_.insert(std::make_pair("hidden", "true")); + Ogre::RenderWindow* hiddenWindow = mRoot->createRenderWindow("InactiveHidden", 1, 1, false, ¶ms_); + hiddenWindow->setActive(false); + */ + NameValuePairList params; params.insert(std::make_pair("title", title)); params.insert(std::make_pair("FSAA", settings.fsaa)); params.insert(std::make_pair("vsync", settings.vsync ? "true" : "false")); + mWindow = mRoot->createRenderWindow(title, settings.window_x, settings.window_y, settings.fullscreen, ¶ms); // create the semi-transparent black background texture used by the GUI.