From bc73c5b1ecaa8001bdeeac46864d4e22026b104a Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 9 Jan 2013 20:08:59 +0100 Subject: [PATCH 01/61] enable directional lighting for character previews --- apps/openmw/mwrender/characterpreview.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index b034e098b..a172d02b1 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -39,6 +39,15 @@ namespace MWRender void CharacterPreview::setup () { mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); + + /// \todo Read the fallback values from INIImporter (Inventory:Directional*) + Ogre::Light* l = mSceneMgr->createLight(); + l->setType (Ogre::Light::LT_DIRECTIONAL); + l->setDirection (Ogre::Vector3(0.3, -0.7, 0.3)); + l->setDiffuseColour (Ogre::ColourValue(1,1,1)); + + mSceneMgr->setAmbientLight (Ogre::ColourValue(0.5, 0.5, 0.5)); + mCamera = mSceneMgr->createCamera (mName); mCamera->setAspectRatio (float(mSizeX) / float(mSizeY)); @@ -72,7 +81,6 @@ namespace MWRender mViewport->setOverlaysEnabled(false); mViewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); mViewport->setShadowsEnabled(false); - mViewport->setMaterialScheme("local_map"); mViewport->setVisibilityMask (RV_PlayerPreview); mRenderTarget->setActive(true); mRenderTarget->setAutoUpdated (false); From 111e38ef25546836d243c9b14c72bd055478a53b Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 9 Jan 2013 20:18:26 +0100 Subject: [PATCH 02/61] Revert "fog now distance based instead of depth" This reverts commit 7ee038fdd7fcb51f901893ae0e6554a2f0cc3dc1. --- files/materials/objects.shader | 2 +- files/materials/openmw.configuration | 1 + files/materials/terrain.shader | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 25624351c..130de0f3d 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -265,7 +265,7 @@ #endif #if FOG - float fogValue = shSaturate((length(cameraPos.xyz-worldPos) - fogParams.y) * fogParams.w); + float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); #if UNDERWATER // regular fog only if fragment is above water diff --git a/files/materials/openmw.configuration b/files/materials/openmw.configuration index 2f84680f0..ee97451d3 100644 --- a/files/materials/openmw.configuration +++ b/files/materials/openmw.configuration @@ -1,5 +1,6 @@ configuration water_reflection { + fog false shadows false shadows_pssm false mrt_output false diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index dee733263..9494c1de9 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -337,7 +337,7 @@ #if FOG - float fogValue = shSaturate((length(cameraPos.xyz-worldPos) - fogParams.y) * fogParams.w); + float fogValue = shSaturate((depth - fogParams.y) * fogParams.w); #if UNDERWATER // regular fog only if fragment is above water From bd8d793fec20fe751651abfcebd7ef0704ffbb8b Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 9 Jan 2013 21:41:40 +0100 Subject: [PATCH 03/61] Removing gamma correction due to caused inconsistencies. --- files/materials/core.h | 7 ++++--- files/materials/objects.shader | 2 +- files/materials/terrain.shader | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/files/materials/core.h b/files/materials/core.h index 1c9ea1d1d..0e46369ef 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -1,7 +1,8 @@ -#define gammaCorrectRead(v) pow(max(v, 0.00001f), float3(gammaCorrection,gammaCorrection,gammaCorrection)) -#define gammaCorrectOutput(v) pow(max(v, 0.00001f), float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection)) - +//#define gammaCorrectRead(v) pow(max(v, 0.00001f), float3(gammaCorrection,gammaCorrection,gammaCorrection)) +//#define gammaCorrectOutput(v) pow(max(v, 0.00001f), float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection)) +#define gammaCorrectRead(v) v +#define gammaCorrectOutput(v) v #if SH_HLSL == 1 || SH_CG == 1 diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 130de0f3d..c68705c42 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -112,7 +112,7 @@ shUniform(float, far) @shAutoConstant(far, far_clip_distance) #endif - shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) + //shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) #if LIGHTING shInput(float3, normalPassthrough) diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 9494c1de9..dfe998210 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -137,7 +137,7 @@ shSampler2D(normalMap) // global normal map - shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) + //shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) @shForeach(@shPropertyString(num_blendmaps)) From b8c6f6640b9f01c0f7925f33819e1da73b34c509 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 9 Jan 2013 21:56:26 +0100 Subject: [PATCH 04/61] Fixing water <-> waterfall blending issues (Sort of... the second part will follow later) --- apps/openmw/mwrender/water.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index e8f099640..80fe54707 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -48,7 +48,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel mWater = mSceneManager->createEntity("water"); mWater->setVisibilityFlags(RV_Water); - mWater->setRenderQueueGroup(RQG_Water); mWater->setCastShadows(false); mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); @@ -324,7 +323,11 @@ void Water::applyRTT() mReflectionTarget = rtt; sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName()); + + mWater->setRenderQueueGroup(RQG_Water); } + else + mWater->setRenderQueueGroup(RQG_Alpha); } void Water::applyVisibilityMask() From d3c0851aa72cb47b977cf6377ae03c73a2859335 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 9 Jan 2013 22:08:42 +0100 Subject: [PATCH 05/61] Changed light attenuation back to linear in all cases, this seems to be what MW does. --- apps/openmw/mwrender/objects.cpp | 7 +++---- apps/openmw/mwrender/water.cpp | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index ee36126f8..810d7af41 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -238,17 +238,16 @@ void Objects::insertLight (const MWWorld::Ptr& ptr, float r, float g, float b, f info.time = Ogre::Math::RangeRandom(-500, +500); info.phase = Ogre::Math::RangeRandom(-500, +500); - // adjust the lights depending if we're in an interior or exterior cell - // quadratic means the light intensity falls off quite fast, resulting in a - // dark, atmospheric environment (perfect for exteriors) - // for interiors, we want more "warm" lights, so use linear attenuation. + // changed to linear to look like morrowind bool quadratic = false; + /* if (!lightOutQuadInLin) quadratic = lightQuadratic; else { quadratic = !info.interior; } + */ if (!quadratic) { diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 80fe54707..a16a23b26 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -315,7 +315,7 @@ void Water::applyRTT() vp->setOverlaysEnabled(false); vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); vp->setShadowsEnabled(false); - // use fallback techniques without shadows and without mrt (currently not implemented for sky and terrain) + // use fallback techniques without shadows and without mrt vp->setMaterialScheme("water_reflection"); rtt->addListener(this); rtt->setActive(true); From 455ec0996df77bea43903741b37eda7b57aecb51 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 9 Jan 2013 22:27:58 +0100 Subject: [PATCH 06/61] Shaders & textures are now loaded upon loading the NIF, instead of when the object becomes visible in the camera frustum. Should improve responsiveness. --- components/nifogre/ogre_nif_loader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index 31d873489..35060e50b 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -656,6 +656,8 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String else instance->getMaterial ()->setShadowCasterMaterial ("openmw_shadowcaster_noalpha"); + sh::Factory::getInstance ()._ensureMaterial (matname, "Default"); + // As of yet UNTESTED code from Chris: /*pass->setTextureFiltering(Ogre::TFO_ANISOTROPIC); pass->setDepthFunction(Ogre::CMPF_LESS_EQUAL); From 35015ef11002547835851979ad6ffd9e48487ceb Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 9 Jan 2013 23:11:15 +0100 Subject: [PATCH 07/61] Change default settings to use no object shaders and per vertex lighting, as some lights in MW look clearly broken with per pixel lighting enabled (e.g. fireplace in census office, ghostfence) --- files/settings-default.cfg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 1768b2f5e..26546c2b1 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -96,7 +96,7 @@ fps = 0 crosshair = true [Objects] -shaders = true +shaders = false # Max. number of lights that affect objects. Setting to 1 will only reflect sunlight # Note: has no effect when shaders are turned off @@ -132,7 +132,7 @@ num lights = 8 # Enable this to get fancy-looking water with reflections and refractions # Only available if object shaders are on # All the settings below have no effect if this is false -shader = true +shader = false rtt size = 512 reflect terrain = true @@ -142,7 +142,7 @@ reflect actors = false reflect misc = false # Enable underwater effect. It is not resource intensive, so only disable it if you have problems. -underwater effect = true +underwater effect = false [Sound] # Device name. Blank means default From 55769aaf911cb06ffa856d5a9d14a77c5f4b3ada Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 10 Jan 2013 01:46:00 +0100 Subject: [PATCH 08/61] Fix selection buffer (i.e. item selection on the inventory character preview) when object shaders were disabled --- apps/openmw/engine.cpp | 4 +--- files/materials/selection.mat | 1 + files/materials/water.mat | 2 +- files/materials/water.shader | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 8c288a2ee..31eb68fa7 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -391,8 +391,6 @@ void OMW::Engine::go() MWBase::Environment::get().getWorld()->changeToInteriorCell (mCellName, pos); } - std::cout << "\nPress Q/ESC or close window to exit.\n"; - mOgre->getRoot()->addFrameListener (this); // Play some good 'ol tunes @@ -420,7 +418,7 @@ void OMW::Engine::go() // Save user settings settings.saveUser(settingspath); - std::cout << "Quitting peacefully.\n"; + std::cout << "Quitting peacefully." << std::endl; } void OMW::Engine::activate() diff --git a/files/materials/selection.mat b/files/materials/selection.mat index a76dd7179..2cb92f884 100644 --- a/files/materials/selection.mat +++ b/files/materials/selection.mat @@ -1,5 +1,6 @@ material SelectionColour { + allow_fixed_function false pass { vertex_program selection_vertex diff --git a/files/materials/water.mat b/files/materials/water.mat index dcea5a0d0..a5f9f2ec9 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -2,7 +2,7 @@ material Water { pass { - emissive 0.6 0.7 1.0 + emissive 1.0 1.0 1.0 ambient 0 0 0 diffuse 0 0 0 1 specular 0 0 0 32 diff --git a/files/materials/water.shader b/files/materials/water.shader index 6bd277eab..9ebea0f00 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -42,7 +42,7 @@ SH_START_PROGRAM { - shOutputColour(0).xyz = shSample(animatedTexture, UV * 15).xyz * float3(0.6, 0.7, 1.0); + shOutputColour(0).xyz = shSample(animatedTexture, UV * 15).xyz * float3(1.0, 1.0, 1.0); shOutputColour(0).w = 0.7; float fogValue = shSaturate((depth - fogParams.y) * fogParams.w); From 30136eb4496b4e81e62548825ef468906db32029 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 12 Jan 2013 06:36:48 +0100 Subject: [PATCH 09/61] Update settings UI --- apps/openmw/mwgui/settingswindow.cpp | 56 +++++++++-------------- apps/openmw/mwgui/settingswindow.hpp | 3 +- apps/openmw/mwgui/windowmanagerimp.cpp | 4 +- apps/openmw/mwrender/renderingmanager.cpp | 7 +-- files/mygui/openmw_settings_window.layout | 38 ++++++--------- files/settings-default.cfg | 2 - 6 files changed, 40 insertions(+), 70 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index cdfe4d2b6..294921cdd 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -109,6 +109,7 @@ namespace MWGui getWidget(mReflectActorsButton, "ReflectActorsButton"); getWidget(mReflectTerrainButton, "ReflectTerrainButton"); getWidget(mShadersButton, "ShadersButton"); + getWidget(mShaderModeButton, "ShaderModeButton"); getWidget(mShadowsEnabledButton, "ShadowsEnabledButton"); getWidget(mShadowsLargeDistance, "ShadowsLargeDistance"); getWidget(mShadowsTextureSize, "ShadowsTextureSize"); @@ -122,7 +123,6 @@ namespace MWGui getWidget(mInvertYButton, "InvertYButton"); getWidget(mUISensitivitySlider, "UISensitivitySlider"); getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); - getWidget(mGammaSlider, "GammaSlider"); mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -130,6 +130,7 @@ namespace MWGui mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled); + mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled); mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -144,7 +145,6 @@ namespace MWGui mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected); mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mGammaSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -202,14 +202,6 @@ namespace MWGui getWidget(fovText, "FovText"); fovText->setCaption("Field of View (" + boost::lexical_cast(int(Settings::Manager::getFloat("field of view", "General"))) + ")"); - float gammaVal = (Settings::Manager::getFloat("gamma", "Video")-0.1f)/(3.f-0.1f); - mGammaSlider->setScrollPosition(gammaVal * (mGammaSlider->getScrollRange()-1)); - MyGUI::TextBox* gammaText; - getWidget(gammaText, "GammaText"); - std::stringstream gamma; - gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video"); - gammaText->setCaption("Gamma (" + gamma.str() + ")"); - float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0; mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1)); std::string tf = Settings::Manager::getString("texture filtering", "General"); @@ -250,14 +242,8 @@ namespace MWGui mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}"); - std::string shaders; - if (!Settings::Manager::getBool("shaders", "Objects")) - shaders = "off"; - else - { - shaders = Settings::Manager::getString("shader mode", "General"); - } - mShadersButton->setCaption (shaders); + mShadersButton->setCaption (Settings::Manager::getBool("shaders", "Objects") ? "on" : "off"); + mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General")); if (!MWRender::RenderingManager::waterShaderSupported()) { @@ -267,7 +253,7 @@ namespace MWGui mReflectTerrainButton->setEnabled(false); } - if (shaders == "off") + if (!Settings::Manager::getBool("shaders", "Objects")) { mUnderwaterButton->setEnabled (false); mShadowsEnabledButton->setEnabled(false); @@ -424,20 +410,32 @@ namespace MWGui } } - void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender) + void SettingsWindow::onShaderModeToggled(MyGUI::Widget* _sender) { std::string val = static_cast(_sender)->getCaption(); - if (val == "off") + if (val == "cg") { val = hlslGlsl(); } - else if (val == hlslGlsl()) - val = "cg"; else - val = "off"; + val = "cg"; static_cast(_sender)->setCaption(val); + Settings::Manager::setString("shader mode", "General", val); + + apply(); + } + + void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender) + { + std::string val = static_cast(_sender)->getCaption(); + if (val == "off") + val = "on"; + else + val = "off"; + static_cast(_sender)->setCaption (val); + if (val == "off") { Settings::Manager::setBool("shaders", "Objects", false); @@ -461,7 +459,6 @@ namespace MWGui else { Settings::Manager::setBool("shaders", "Objects", true); - Settings::Manager::setString("shader mode", "General", val); // re-enable if (MWRender::RenderingManager::waterShaderSupported()) @@ -521,15 +518,6 @@ namespace MWGui fovText->setCaption("Field of View (" + boost::lexical_cast(int((1-val) * sFovMin + val * sFovMax)) + ")"); Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax); } - else if (scroller == mGammaSlider) - { - Settings::Manager::setFloat("gamma", "Video", (1-val) * 0.1f + val * 3.f); - MyGUI::TextBox* gammaText; - getWidget(gammaText, "GammaText"); - std::stringstream gamma; - gamma << std::setprecision (2) << Settings::Manager::getFloat("gamma", "Video"); - gammaText->setCaption("Gamma (" + gamma.str() + ")"); - } else if (scroller == mAnisotropySlider) { mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast(int(val*16)) + ")"); diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index e878d0abe..8ca3ad758 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -40,7 +40,6 @@ namespace MWGui MyGUI::Button* mFPSButton; MyGUI::ScrollBar* mViewDistanceSlider; MyGUI::ScrollBar* mFOVSlider; - MyGUI::ScrollBar* mGammaSlider; MyGUI::ScrollBar* mAnisotropySlider; MyGUI::Button* mTextureFilteringButton; MyGUI::TextBox* mAnisotropyLabel; @@ -50,6 +49,7 @@ namespace MWGui MyGUI::Button* mReflectActorsButton; MyGUI::Button* mReflectTerrainButton; MyGUI::Button* mShadersButton; + MyGUI::Button* mShaderModeButton; MyGUI::Button* mUnderwaterButton; MyGUI::Button* mShadowsEnabledButton; @@ -84,6 +84,7 @@ namespace MWGui void onResolutionCancel(); void onShadersToggled(MyGUI::Widget* _sender); + void onShaderModeToggled(MyGUI::Widget* _sender); void onShadowTextureSize(MyGUI::Widget* _sender); void onRebindAction(MyGUI::Widget* _sender); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 8ec495550..a1f915ac9 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -177,8 +177,7 @@ WindowManager::WindowManager( mInputBlocker = mGui->createWidget("",0,0,w,h,MyGUI::Align::Default,"Windows",""); - // The HUD is always on - mHud->setVisible(true); + mHud->setVisible(mHudEnabled); mCharGen = new CharacterCreation(this); @@ -1001,7 +1000,6 @@ void WindowManager::notifyInputActionBound () allowMouse(); } - void WindowManager::showCrosshair (bool show) { mHud->setCrosshairVisible (show && mCrosshairEnabled); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ae7d6612b..ff26b087c 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -134,7 +134,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty(new sh::Vector2(1, 0.6))); sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty(new sh::FloatValue( - Settings::Manager::getFloat ("gamma", "Video")))); + 1.f))); applyCompositors(); @@ -782,11 +782,6 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); mObjects.rebuildStaticGeometry (); } - else if (it->second == "gamma" && it->first == "Video") - { - sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty(new sh::FloatValue( - Settings::Manager::getFloat ("gamma", "Video")))); - } else if (it->second == "shader mode" && it->first == "General") { sh::Language lang; diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 2f9b5a67f..f03305ae7 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -157,54 +157,44 @@ - + - + - + - - + + - + - - + + - + - - - - - - - - - - - - - - + + + + + - diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 26546c2b1..31aa60c42 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -28,8 +28,6 @@ vsync = false # PBuffer, FBO, Copy opengl rtt mode = FBO -gamma = 2.2 - [GUI] # 1 is fully opaque menu transparency = 0.84 From 2c3719a6f5f2a4110e412781de0f4b955e1b2441 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 12 Jan 2013 07:02:12 +0100 Subject: [PATCH 10/61] Disabling PSSM feature to make sure we can fit the max. amount of terrain textures in Morrowind.esm in a single pass. --- apps/openmw/mwgui/settingswindow.cpp | 5 ++++- apps/openmw/mwrender/shadows.cpp | 4 ++-- apps/openmw/mwrender/terrainmaterial.cpp | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 294921cdd..c5c6eada2 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -225,7 +225,10 @@ namespace MWGui mUnderwaterButton->setCaptionWithReplacing(Settings::Manager::getBool("underwater effect", "Water") ? "#{sOn}" : "#{sOff}"); mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows")); - mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}"); + //mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}"); + mShadowsLargeDistance->setCaptionWithReplacing("#{sOff}"); + mShadowsLargeDistance->setEnabled (false); + mShadowsEnabledButton->setCaptionWithReplacing(Settings::Manager::getBool("enabled", "Shadows") ? "#{sOn}" : "#{sOff}"); mActorShadows->setCaptionWithReplacing(Settings::Manager::getBool("actor shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); mStaticsShadows->setCaptionWithReplacing(Settings::Manager::getBool("statics shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index 3d9f13243..808c8b5d9 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -33,8 +33,8 @@ void Shadows::recreate() // Split shadow maps are currently disabled because the terrain cannot cope with them // (Too many texture units) Solution would be a multi-pass terrain material - bool split = Settings::Manager::getBool("split", "Shadows"); - //const bool split = false; + //bool split = Settings::Manager::getBool("split", "Shadows"); + const bool split = false; sh::Factory::getInstance ().setGlobalSetting ("shadows", enabled && !split ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("shadows_pssm", enabled && split ? "true" : "false"); diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 5ef9fe58f..d5e531f86 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -153,7 +153,8 @@ namespace MWRender --freeTextureUnits; // colourmap --freeTextureUnits; - freeTextureUnits -= 3; // shadow PSSM + // shadow + --freeTextureUnits; --freeTextureUnits; // caustics From e4f140841e2e9eacb25c671cbe03c61938b1219c Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 12 Jan 2013 08:23:15 +0100 Subject: [PATCH 11/61] Make OpenMW work with Ogre 1.9 --- apps/launcher/graphicspage.cpp | 1 + apps/openmw/mwrender/localmap.cpp | 1 - apps/openmw/mwrender/shadows.cpp | 5 ++--- apps/openmw/mwrender/terrainmaterial.hpp | 1 + apps/openmw/mwrender/water.cpp | 3 --- components/bsa/bsa_archive.cpp | 5 +++++ libs/openengine/ogre/renderer.cpp | 1 + 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 2c4f3430c..cc4cbfe7d 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -122,6 +122,7 @@ bool GraphicsPage::setupOgre() pluginDir = absPluginPath.string(); Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre); + Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mOgre); Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre); #ifdef ENABLE_PLUGIN_GL diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index d878cb86e..b34942d28 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -1,6 +1,5 @@ #include "localmap.hpp" -#include #include #include diff --git a/apps/openmw/mwrender/shadows.cpp b/apps/openmw/mwrender/shadows.cpp index 808c8b5d9..595a82294 100644 --- a/apps/openmw/mwrender/shadows.cpp +++ b/apps/openmw/mwrender/shadows.cpp @@ -9,9 +9,6 @@ #include #include -#include -#include - #include #include "renderconst.hpp" @@ -125,6 +122,7 @@ void Shadows::recreate() // -------------------------------------------------------------------------------------------------------------------- // --------------------------- Debug overlays to display the content of shadow maps ----------------------------------- // -------------------------------------------------------------------------------------------------------------------- + /* if (Settings::Manager::getBool("debug", "Shadows")) { OverlayManager& mgr = OverlayManager::getSingleton(); @@ -181,6 +179,7 @@ void Shadows::recreate() if ((overlay = mgr.getByName("DebugOverlay"))) mgr.destroy(overlay); } + */ } PSSMShadowCameraSetup* Shadows::getPSSMSetup() diff --git a/apps/openmw/mwrender/terrainmaterial.hpp b/apps/openmw/mwrender/terrainmaterial.hpp index 3e31b2a58..fe1214cf5 100644 --- a/apps/openmw/mwrender/terrainmaterial.hpp +++ b/apps/openmw/mwrender/terrainmaterial.hpp @@ -67,6 +67,7 @@ namespace MWRender void setGlobalColourMapEnabled(bool enabled); void setGlobalColourMap (Ogre::Terrain* terrain, const std::string& name); + virtual void setLightmapEnabled(bool) {} private: sh::MaterialInstance* mMaterial; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index a16a23b26..04a126367 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -8,9 +8,6 @@ #include #include #include -#include -#include -#include #include "sky.hpp" #include "renderingmanager.hpp" diff --git a/components/bsa/bsa_archive.cpp b/components/bsa/bsa_archive.cpp index 9913fb8aa..3bff93baa 100644 --- a/components/bsa/bsa_archive.cpp +++ b/components/bsa/bsa_archive.cpp @@ -403,6 +403,11 @@ public: return new BSAArchive(name); } + virtual Archive* createInstance(const String& name, bool readOnly) + { + return new BSAArchive(name); + } + void destroyInstance( Archive* arch) { delete arch; } }; diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 3cdb00518..ed5cc9b43 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -192,6 +192,7 @@ void OgreRenderer::configure(const std::string &logPath, pluginDir = absPluginPath.string(); Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mRoot); + Files::loadOgrePlugin(pluginDir, "RenderSystem_GL3Plus", *mRoot); Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mRoot); Files::loadOgrePlugin(pluginDir, "Plugin_CgProgramManager", *mRoot); From df602553d10fa69ed4ab6a4902daaefed276749d Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 16 Jan 2013 09:13:36 +0100 Subject: [PATCH 12/61] Reworked MWRender::Water to be more OOP-ish and possibly allow other reflection types. --- apps/openmw/mwrender/water.cpp | 270 +++++++++++++++++++++------------ apps/openmw/mwrender/water.hpp | 77 ++++++++-- 2 files changed, 238 insertions(+), 109 deletions(-) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 04a126367..27b9fc679 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -24,12 +24,163 @@ using namespace Ogre; namespace MWRender { +CubeReflection::CubeReflection(Ogre::SceneManager* sceneManager) + : Reflection(sceneManager) +{ + Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton ().createManual("CubeReflection", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_CUBE_MAP, + 512,512, 0, PF_R8G8B8, TU_RENDERTARGET); + + mCamera = mSceneMgr->createCamera ("CubeCamera"); + mCamera->setNearClipDistance (5); + mCamera->setFarClipDistance (1000); + + for (int face = 0; face < 6; ++face) + { + mRenderTargets[face] = texture->getBuffer (face)->getRenderTarget(); + mRenderTargets[face]->removeAllViewports (); + Viewport* vp = mRenderTargets[face]->addViewport (mCamera); + vp->setOverlaysEnabled(false); + vp->setShadowsEnabled(false); + vp->setMaterialScheme ("water_reflection"); + mRenderTargets[face]->setAutoUpdated(false); + + /* + Vector3 lookAt(0,0,0), up(0,0,0), right(0,0,0); + switch(face) + { + case 0: lookAt.x =-1; up.y = 1; right.z = 1; break; // +X + case 1: lookAt.x = 1; up.y = 1; right.z =-1; break; // -X + case 2: lookAt.y =-1; up.z = 1; right.x = 1; break; // +Y + case 3: lookAt.y = 1; up.z =-1; right.x = 1; break; // -Y + case 4: lookAt.z = 1; up.y = 1; right.x =-1; break; // +Z + case 5: lookAt.z =-1; up.y = 1; right.x =-1; break; // -Z + } + Quaternion orient(right, up, lookAt); + mCamera->setOrientation(orient); + */ + } +} + +CubeReflection::~CubeReflection () +{ + Ogre::TextureManager::getSingleton ().remove("CubeReflection"); + mSceneMgr->destroyCamera (mCamera); +} + +void CubeReflection::update () +{ + mParentCamera->getParentSceneNode ()->needUpdate (); + mCamera->setPosition(mParentCamera->getDerivedPosition()); +} + +// -------------------------------------------------------------------------------------------------------------------------------- + +PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky) + : Reflection(sceneManager) + , mSky(sky) +{ + mCamera = mSceneMgr->createCamera ("PlaneReflectionCamera"); + mSceneMgr->addRenderQueueListener(this); + + mTexture = TextureManager::getSingleton().createManual("WaterReflection", + ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, 512, 512, 0, PF_A8R8G8B8, TU_RENDERTARGET); + + mRenderTarget = mTexture->getBuffer()->getRenderTarget(); + Viewport* vp = mRenderTarget->addViewport(mCamera); + vp->setOverlaysEnabled(false); + vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); + vp->setShadowsEnabled(false); + // use fallback techniques without shadows and without mrt + vp->setMaterialScheme("water_reflection"); + mRenderTarget->addListener(this); + mRenderTarget->setActive(true); + + sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mTexture->getName()); +} + +PlaneReflection::~PlaneReflection () +{ + mRenderTarget->removeListener (this); + mSceneMgr->destroyCamera (mCamera); + TextureManager::getSingleton ().remove("WaterReflection"); +} + +void PlaneReflection::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) +{ + // We don't want the sky to get clipped by custom near clip plane (the water plane) + if (queueGroupId < 20 && mRenderActive) + { + mCamera->disableCustomNearClipPlane(); + Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); + } +} + +void PlaneReflection::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) +{ + if (queueGroupId < 20 && mRenderActive) + { + if (!mIsUnderwater) + mCamera->enableCustomNearClipPlane(mErrorPlane); + Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); + } +} + +void PlaneReflection::preRenderTargetUpdate(const 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()); + mRenderActive = true; + + Vector3 pos = mParentCamera->getRealPosition(); + pos.y = (mWaterPlane).d*2 - pos.y; + mSky->setSkyPosition(pos); + mCamera->enableReflection(mWaterPlane); +} + +void PlaneReflection::postRenderTargetUpdate(const RenderTargetEvent& evt) +{ + mSky->resetSkyPosition(); + mCamera->disableReflection(); + mCamera->disableCustomNearClipPlane(); + mRenderActive = false; +} + +void PlaneReflection::setWaterPlane (Plane plane) +{ + mWaterPlane = plane; + mErrorPlane = Plane(plane.normal, mWaterPlane.d - 5); +} + +void PlaneReflection::setActive (bool active) +{ + mRenderTarget->setActive(active); +} + +void PlaneReflection::setViewportBackground(Ogre::ColourValue colour) +{ + mRenderTarget->getViewport (0)->setBackgroundColour (colour); +} + +void PlaneReflection::setVisibilityMask (int flags) +{ + mRenderTarget->getViewport (0)->setVisibilityMask (flags); +} + +// -------------------------------------------------------------------------------------------------------------------------------- + Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : - mCamera (camera), mSceneManager (camera->getSceneManager()), + mCamera (camera), mSceneMgr (camera->getSceneManager()), mIsUnderwater(false), mVisibilityFlags(0), - mReflectionTarget(0), mActive(1), mToggled(1), - mReflectionRenderActive(false), mRendering(rend), - mWaterTimer(0.f) + mActive(1), mToggled(1), + mRendering(rend), + mWaterTimer(0.f), + mReflection(NULL) { mSky = rend->getSkyManager(); @@ -43,13 +194,11 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel MeshManager::getSingleton().createPlane("water", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, mWaterPlane, CELL_SIZE*5, CELL_SIZE * 5, 10, 10, true, 1, 3,3, Vector3::UNIT_Z); - mWater = mSceneManager->createEntity("water"); + mWater = mSceneMgr->createEntity("water"); mWater->setVisibilityFlags(RV_Water); mWater->setCastShadows(false); - mWaterNode = mSceneManager->getRootSceneNode()->createChildSceneNode(); - - mReflectionCamera = mSceneManager->createCamera("ReflectionCamera"); + mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); if(!(cell->mData.mFlags & cell->Interior)) { @@ -72,8 +221,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel underwaterDome->setMaterialName("Underwater_Dome"); */ - mSceneManager->addRenderQueueListener(this); - assignTextures(); setHeight(mTop); @@ -142,12 +289,9 @@ Water::~Water() { MeshManager::getSingleton().remove("water"); - if (mReflectionTarget) - mReflectionTexture->getBuffer()->getRenderTarget()->removeListener(this); - mWaterNode->detachObject(mWater); - mSceneManager->destroyEntity(mWater); - mSceneManager->destroySceneNode(mWaterNode); + mSceneMgr->destroyEntity(mWater); + mSceneMgr->destroySceneNode(mWaterNode); } void Water::changeCell(const ESM::Cell* cell) @@ -166,8 +310,8 @@ void Water::setHeight(const float height) mWaterPlane = Plane(Vector3::UNIT_Y, height); - // small error due to reflection texture size & reflection distortion - mErrorPlane = Plane(Vector3::UNIT_Y, height - 5); + if (mReflection) + mReflection->setWaterPlane(mWaterPlane); mWaterNode->setPosition(0, height, 0); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty(new sh::FloatValue(height))); @@ -190,6 +334,9 @@ Water::updateUnderwater(bool underwater) mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID; + if (mReflection) + mReflection->setUnderwater (mIsUnderwater); + updateVisible(); } @@ -198,37 +345,6 @@ Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2)); } -void Water::preRenderTargetUpdate(const RenderTargetEvent& evt) -{ - if (evt.source == mReflectionTarget) - { - mCamera->getParentSceneNode ()->needUpdate (); - mReflectionCamera->setOrientation(mCamera->getDerivedOrientation()); - mReflectionCamera->setPosition(mCamera->getDerivedPosition()); - mReflectionCamera->setNearClipDistance(mCamera->getNearClipDistance()); - mReflectionCamera->setFarClipDistance(mCamera->getFarClipDistance()); - mReflectionCamera->setAspectRatio(mCamera->getAspectRatio()); - mReflectionCamera->setFOVy(mCamera->getFOVy()); - mReflectionRenderActive = true; - - Vector3 pos = mCamera->getRealPosition(); - pos.y = mTop*2 - pos.y; - mSky->setSkyPosition(pos); - mReflectionCamera->enableReflection(mWaterPlane); - } -} - -void Water::postRenderTargetUpdate(const RenderTargetEvent& evt) -{ - if (evt.source == mReflectionTarget) - { - mSky->resetSkyPosition(); - mReflectionCamera->disableReflection(); - mReflectionCamera->disableCustomNearClipPlane(); - mReflectionRenderActive = false; - } -} - void Water::assignTextures() { if (Settings::Manager::getBool("shader", "Water")) @@ -246,34 +362,16 @@ void Water::assignTextures() void Water::setViewportBackground(const ColourValue& bg) { - if (mReflectionTarget) - mReflectionTarget->getViewport(0)->setBackgroundColour(bg); + if (mReflection) + mReflection->setViewportBackground(bg); } void Water::updateVisible() { mWater->setVisible(mToggled && mActive); - if (mReflectionTarget) - mReflectionTarget->setActive(mToggled && mActive); -} - -void Water::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) -{ - // We don't want the sky to get clipped by custom near clip plane (the water plane) - if (queueGroupId < 20 && mReflectionRenderActive) - { - mReflectionCamera->disableCustomNearClipPlane(); - Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); - } -} - -void Water::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) -{ - if (queueGroupId < 20 && mReflectionRenderActive) + if (mReflection) { - if (!mIsUnderwater) - mReflectionCamera->enableCustomNearClipPlane(mErrorPlane); - Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mReflectionCamera->getProjectionMatrixRS()); + mReflection->setActive(mToggled && mActive); } } @@ -293,10 +391,10 @@ void Water::update(float dt) void Water::applyRTT() { - if (mReflectionTarget) + if (mReflection) { - TextureManager::getSingleton().remove("WaterReflection"); - mReflectionTarget = 0; + delete mReflection; + mReflection = NULL; } // Create rendertarget for reflection @@ -304,23 +402,9 @@ void Water::applyRTT() if (Settings::Manager::getBool("shader", "Water")) { - mReflectionTexture = TextureManager::getSingleton().createManual("WaterReflection", - ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, TEX_TYPE_2D, rttsize, rttsize, 0, PF_A8R8G8B8, TU_RENDERTARGET); - - RenderTarget* rtt = mReflectionTexture->getBuffer()->getRenderTarget(); - Viewport* vp = rtt->addViewport(mReflectionCamera); - vp->setOverlaysEnabled(false); - vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); - vp->setShadowsEnabled(false); - // use fallback techniques without shadows and without mrt - vp->setMaterialScheme("water_reflection"); - rtt->addListener(this); - rtt->setActive(true); - - mReflectionTarget = rtt; - - sh::Factory::getInstance ().setTextureAlias ("WaterReflection", mReflectionTexture->getName()); - + mReflection = new PlaneReflection(mSceneMgr, mSky); + mReflection->setParentCamera (mCamera); + mReflection->setWaterPlane(mWaterPlane); mWater->setRenderQueueGroup(RQG_Water); } else @@ -336,10 +420,8 @@ void Water::applyVisibilityMask() + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + RV_Sky; - if (mReflectionTarget) - { - mReflectionTexture->getBuffer()->getRenderTarget()->getViewport(0)->setVisibilityMask(mVisibilityFlags); - } + if (mReflection) + mReflection->setVisibilityMask(mVisibilityFlags); } void Water::processChangedSettings(const Settings::CategorySettingVector& settings) diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index f1e3d7a3b..de78542b7 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -30,15 +30,73 @@ namespace MWRender { class SkyManager; class RenderingManager; + class Reflection + { + public: + Reflection(Ogre::SceneManager* sceneManager) + : mSceneMgr(sceneManager) {} + + virtual void setWaterPlane (Ogre::Plane plane) {} + virtual void setParentCamera (Ogre::Camera* parent) { mParentCamera = parent; } + void setUnderwater(bool underwater) { mIsUnderwater = underwater; } + virtual void setActive (bool active) {} + virtual void setViewportBackground(Ogre::ColourValue colour) {} + virtual void update() {} + virtual void setVisibilityMask (int flags) {} + + protected: + Ogre::Camera* mCamera; + Ogre::Camera* mParentCamera; + Ogre::TexturePtr mTexture; + Ogre::SceneManager* mSceneMgr; + bool mIsUnderwater; + }; + + class CubeReflection : public Reflection + { + public: + CubeReflection(Ogre::SceneManager* sceneManager); + virtual ~CubeReflection(); + + virtual void update(); + protected: + Ogre::RenderTarget* mRenderTargets[6]; + }; + + class PlaneReflection : public Reflection, public Ogre::RenderQueueListener, public Ogre::RenderTargetListener + { + public: + PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky); + virtual ~PlaneReflection(); + + virtual void setWaterPlane (Ogre::Plane plane); + virtual void setActive (bool active); + virtual void setVisibilityMask (int flags); + + void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + + void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); + void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); + + virtual void setViewportBackground(Ogre::ColourValue colour); + + protected: + Ogre::RenderTarget* mRenderTarget; + SkyManager* mSky; + Ogre::Plane mWaterPlane; + Ogre::Plane mErrorPlane; + bool mRenderActive; + }; + /// Water rendering class Water : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener, public sh::MaterialInstanceListener { static const int CELL_SIZE = 8192; Ogre::Camera *mCamera; - Ogre::SceneManager *mSceneManager; + Ogre::SceneManager *mSceneMgr; Ogre::Plane mWaterPlane; - Ogre::Plane mErrorPlane; Ogre::SceneNode *mWaterNode; Ogre::Entity *mWater; @@ -52,17 +110,9 @@ namespace MWRender { float mWaterTimer; - bool mReflectionRenderActive; - Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); protected: - void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); - void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); - - void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); - void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); - void applyRTT(); void applyVisibilityMask(); @@ -75,14 +125,11 @@ namespace MWRender { Ogre::MaterialPtr mMaterial; - Ogre::Camera* mReflectionCamera; - - Ogre::TexturePtr mReflectionTexture; - Ogre::RenderTarget* mReflectionTarget; - bool mUnderwaterEffect; int mVisibilityFlags; + Reflection* mReflection; + public: Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell); ~Water(); From a461b282c15083e6987356a1643c7b8a5b4295a3 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 1 Feb 2013 23:43:23 +0100 Subject: [PATCH 13/61] water ripples (experimental) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 5 +- apps/openmw/mwrender/ripplesimulation.cpp | 212 ++++++++++++++++++ apps/openmw/mwrender/ripplesimulation.hpp | 72 ++++++ apps/openmw/mwrender/water.cpp | 14 +- apps/openmw/mwrender/water.hpp | 5 +- extern/shiny/Main/Factory.cpp | 2 + files/CMakeLists.txt | 7 + files/materials/core.h | 4 + files/materials/quad.mat | 2 +- files/materials/quad.shaderset | 2 +- files/materials/water.mat | 8 +- files/materials/water.shader | 28 ++- files/materials/watersim.mat | 59 +++++ files/materials/watersim.shaderset | 31 +++ files/materials/watersim_addimpulse.shader | 12 + files/materials/watersim_common.h | 25 +++ files/materials/watersim_heightmap.shader | 42 ++++ .../materials/watersim_heighttonormal.shader | 27 +++ files/water/circle.png | Bin 0 -> 753 bytes 20 files changed, 545 insertions(+), 14 deletions(-) create mode 100644 apps/openmw/mwrender/ripplesimulation.cpp create mode 100644 apps/openmw/mwrender/ripplesimulation.hpp create mode 100644 files/materials/watersim.mat create mode 100644 files/materials/watersim.shaderset create mode 100644 files/materials/watersim_addimpulse.shader create mode 100644 files/materials/watersim_common.h create mode 100644 files/materials/watersim_heightmap.shader create mode 100644 files/materials/watersim_heighttonormal.shader create mode 100644 files/water/circle.png diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 482007090..2c49e848e 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 + compositors characterpreview externalrendering globalmap videoplayer ripplesimulation ) add_openmw_dir (mwinput diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ff26b087c..3fed4d994 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -386,7 +386,10 @@ void RenderingManager::update (float duration, bool paused) *world->getPlayer().getPlayer().getCell()->mCell, Ogre::Vector3(cam.x, -cam.z, cam.y)) ); - mWater->update(duration); + + // MW to ogre coordinates + orig = Ogre::Vector3(orig.x, orig.z, -orig.y); + mWater->update(duration, orig); } } diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp new file mode 100644 index 000000000..6096c7ba3 --- /dev/null +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -0,0 +1,212 @@ +#include "ripplesimulation.hpp" + +#include +#include +#include +#include + +#include + +namespace MWRender +{ + + +RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) + : mMainSceneMgr(mainSceneManager), + mTime(0), + mCurrentFrameOffset(0,0), + mPreviousFrameOffset(0,0), + mRippleCenter(0,0), + mTextureSize(512), + mRippleAreaLength(1000), + mImpulseSize(20), + mTexelOffset(0,0) +{ + 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"); + + mRectangle = new Ogre::Rectangle2D(true); + mRectangle->setBoundingBox(aabInf); + mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0, false); + Ogre::SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + node->attachObject(mRectangle); + + mImpulse = new Ogre::Rectangle2D(true); + mImpulse->setCorners(-0.1, 0.1, 0.1, -0.1, false); + mImpulse->setBoundingBox(aabInf); + mImpulse->setMaterial("AddImpulse"); + Ogre::SceneNode* impulseNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); + impulseNode->attachObject(mImpulse); + + float w=0.05; + for (int i=0; i<4; ++i) + { + Ogre::TexturePtr texture; + if (i != 3) + texture = Ogre::TextureManager::getSingleton().createManual("RippleHeight" + Ogre::StringConverter::toString(i), + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mTextureSize, mTextureSize, 1, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET); + else + texture = Ogre::TextureManager::getSingleton().createManual("RippleNormal", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, mTextureSize, mTextureSize, 1, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET); + + + Ogre::RenderTexture* rt = texture->getBuffer()->getRenderTarget(); + rt->removeAllViewports(); + rt->addViewport(mCamera); + rt->setAutoUpdated(false); + 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); + + Ogre::MaterialPtr debugMaterial = Ogre::MaterialManager::getSingleton().create("RippleDebug" + Ogre::StringConverter::toString(i), + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); + + if (i != 3) + debugMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("RippleHeight" + Ogre::StringConverter::toString(i)); + else + debugMaterial->getTechnique(0)->getPass(0)->createTextureUnitState("RippleNormal"); + debugMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false); + + debugOverlay->setMaterial("RippleDebug" + Ogre::StringConverter::toString(i)); + + mRenderTargets[i] = rt; + mTextures[i] = texture; + } + + sh::Factory::getInstance().setSharedParameter("rippleTextureSize", sh::makeProperty( + new sh::Vector4(1.0/512, 1.0/512, 512, 512))); + sh::Factory::getInstance().setSharedParameter("rippleCenter", sh::makeProperty( + new sh::Vector3(0, 0, 0))); + sh::Factory::getInstance().setSharedParameter("rippleAreaLength", sh::makeProperty( + new sh::FloatValue(mRippleAreaLength))); + +} + +RippleSimulation::~RippleSimulation() +{ + delete mRectangle; + + Ogre::Root::getSingleton().destroySceneManager(mSceneMgr); +} + +void RippleSimulation::update(float dt, Ogre::Vector2 position) +{ + // try to keep 20 fps + mTime += dt; + + while (mTime >= 1/20.0) + { + mPreviousFrameOffset = mCurrentFrameOffset; + + mCurrentFrameOffset = position - mRippleCenter; + // add texel offsets from previous frame. + mCurrentFrameOffset += mTexelOffset; + + mTexelOffset = Ogre::Vector2(std::fmod(mCurrentFrameOffset.x, 1.0f/mTextureSize), + std::fmod(mCurrentFrameOffset.y, 1.0f/mTextureSize)); + + // now subtract new offset in order to snap to texels + mCurrentFrameOffset -= mTexelOffset; + + // texture coordinate space + mCurrentFrameOffset /= mRippleAreaLength; + + std::cout << "Offset " << mCurrentFrameOffset << std::endl; + + mRippleCenter = position; + + addImpulses(); + waterSimulation(); + heightMapToNormalMap(); + + swapHeightMaps(); + mTime -= 1/20.0; + } + + sh::Factory::getInstance().setSharedParameter("rippleCenter", sh::makeProperty( + new sh::Vector3(mRippleCenter.x + mTexelOffset.x, mRippleCenter.y + mTexelOffset.y, 0))); +} + +void RippleSimulation::addImpulse(Ogre::Vector2 position) +{ + mImpulses.push(position); +} + +void RippleSimulation::addImpulses() +{ + mRectangle->setVisible(false); + mImpulse->setVisible(true); + + while (mImpulses.size()) + { + Ogre::Vector2 pos = mImpulses.front(); + pos -= mRippleCenter; + pos /= mRippleAreaLength; + float size = mImpulseSize / mRippleAreaLength; + mImpulse->setCorners(pos.x-size, pos.y+size, pos.x+size, pos.y-size, false); + mImpulses.pop(); + + mRenderTargets[1]->update(); + } + + mImpulse->setVisible(false); + mRectangle->setVisible(true); +} + +void RippleSimulation::waterSimulation() +{ + mRectangle->setMaterial("HeightmapSimulation"); + + sh::Factory::getInstance().setTextureAlias("Heightmap0", mTextures[0]->getName()); + sh::Factory::getInstance().setTextureAlias("Heightmap1", mTextures[1]->getName()); + + sh::Factory::getInstance().setSharedParameter("currentFrameOffset", sh::makeProperty( + new sh::Vector3(mCurrentFrameOffset.x, mCurrentFrameOffset.y, 0))); + sh::Factory::getInstance().setSharedParameter("previousFrameOffset", sh::makeProperty( + new sh::Vector3(mPreviousFrameOffset.x, mPreviousFrameOffset.y, 0))); + + mRenderTargets[2]->update(); +} + +void RippleSimulation::heightMapToNormalMap() +{ + mRectangle->setMaterial("HeightToNormalMap"); + + sh::Factory::getInstance().setTextureAlias("Heightmap2", mTextures[2]->getName()); + + mRenderTargets[TEX_NORMAL]->update(); +} + +void RippleSimulation::swapHeightMaps() +{ + // 0 -> 1 -> 2 to 2 -> 0 ->1 + Ogre::RenderTexture* tmp = mRenderTargets[0]; + Ogre::TexturePtr tmp2 = mTextures[0]; + + mRenderTargets[0] = mRenderTargets[1]; + mTextures[0] = mTextures[1]; + + mRenderTargets[1] = mRenderTargets[2]; + mTextures[1] = mTextures[2]; + + mRenderTargets[2] = tmp; + mTextures[2] = tmp2; +} + + +} diff --git a/apps/openmw/mwrender/ripplesimulation.hpp b/apps/openmw/mwrender/ripplesimulation.hpp new file mode 100644 index 000000000..6096fa866 --- /dev/null +++ b/apps/openmw/mwrender/ripplesimulation.hpp @@ -0,0 +1,72 @@ +#ifndef RIPPLE_SIMULATION_H +#define RIPPLE_SIMULATION_H + +#include +#include +#include + +namespace Ogre +{ + class RenderTexture; + class Camera; + class SceneManager; + class Rectangle2D; +} + +namespace MWRender +{ + +class RippleSimulation +{ +public: + RippleSimulation(Ogre::SceneManager* mainSceneManager); + ~RippleSimulation(); + + void update(float dt, Ogre::Vector2 position); + + void addImpulse (Ogre::Vector2 position); + +private: + Ogre::RenderTexture* mRenderTargets[4]; + Ogre::TexturePtr mTextures[4]; + + int mTextureSize; + float mRippleAreaLength; + float mImpulseSize; + + Ogre::Camera* mCamera; + + // own scenemanager to render our simulation + Ogre::SceneManager* mSceneMgr; + Ogre::Rectangle2D* mRectangle; + + // 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; + + std::queue mImpulses; + + void addImpulses(); + void heightMapToNormalMap(); + void waterSimulation(); + void swapHeightMaps(); + + float mTime; + + Ogre::Vector2 mRippleCenter; + + Ogre::Vector2 mTexelOffset; + + Ogre::Vector2 mCurrentFrameOffset; + Ogre::Vector2 mPreviousFrameOffset; +}; + +} + +#endif diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 27b9fc679..6ee3890dd 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -12,6 +12,7 @@ #include "sky.hpp" #include "renderingmanager.hpp" #include "compositors.hpp" +#include "ripplesimulation.hpp" #include #include @@ -180,8 +181,11 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel mActive(1), mToggled(1), mRendering(rend), mWaterTimer(0.f), - mReflection(NULL) + mReflection(NULL), + mSimulation(NULL) { + mSimulation = new RippleSimulation(mSceneMgr); + mSky = rend->getSkyManager(); mMaterial = MaterialManager::getSingleton().getByName("Water"); @@ -375,7 +379,7 @@ void Water::updateVisible() } } -void Water::update(float dt) +void Water::update(float dt, Ogre::Vector3 player) { /* Ogre::Vector3 pos = mCamera->getDerivedPosition (); @@ -387,6 +391,12 @@ void Water::update(float dt) sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(mWaterTimer))); mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); + + //if (player.y <= mTop) + { + mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); + } + mSimulation->update(dt, Ogre::Vector2(player.x, player.z)); } void Water::applyRTT() diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index de78542b7..97eb590b3 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -29,6 +29,7 @@ namespace MWRender { class SkyManager; class RenderingManager; + class RippleSimulation; class Reflection { @@ -110,6 +111,8 @@ namespace MWRender { float mWaterTimer; + RippleSimulation* mSimulation; + Ogre::Vector3 getSceneNodeCoordinates(int gridX, int gridY); protected: @@ -137,7 +140,7 @@ namespace MWRender { void setActive(bool active); void toggle(); - void update(float dt); + void update(float dt, Ogre::Vector3 player); void assignTextures(); diff --git a/extern/shiny/Main/Factory.cpp b/extern/shiny/Main/Factory.cpp index 82d664811..6e87800e5 100644 --- a/extern/shiny/Main/Factory.cpp +++ b/extern/shiny/Main/Factory.cpp @@ -219,6 +219,8 @@ namespace sh break; } + std::cout << "loading " << it->first << std::endl; + MaterialInstance newInstance(it->first, this); newInstance.create(mPlatform); if (!mShadersEnabled) diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index e8426afb7..65ebc31a2 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -3,6 +3,7 @@ project(resources) set(WATER_FILES underwater_dome.mesh water_nm.png + circle.png ) set(GBUFFER_FILES @@ -43,6 +44,12 @@ set(MATERIAL_FILES selection.mat selection.shader selection.shaderset + watersim_heightmap.shader + watersim_addimpulse.shader + watersim_heighttonormal.shader + watersim_common.h + watersim.mat + watersim.shaderset ) copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}") diff --git a/files/materials/core.h b/files/materials/core.h index 0e46369ef..e498a3809 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -28,6 +28,8 @@ #define shNormalInput(type) , in type normal : NORMAL #define shColourInput(type) , in type colour : COLOR + + #define shFract(val) frac(val) #ifdef SH_VERTEX_SHADER @@ -64,6 +66,8 @@ #if SH_GLSL == 1 + #define shFract(val) fract(val) + @version 120 #define float2 vec2 diff --git a/files/materials/quad.mat b/files/materials/quad.mat index afb7f5111..a484d7f28 100644 --- a/files/materials/quad.mat +++ b/files/materials/quad.mat @@ -4,7 +4,7 @@ material quad pass { - vertex_program quad_vertex + vertex_program transform_vertex fragment_program quad_fragment depth_write $depth_write diff --git a/files/materials/quad.shaderset b/files/materials/quad.shaderset index c61497503..ee230a303 100644 --- a/files/materials/quad.shaderset +++ b/files/materials/quad.shaderset @@ -1,4 +1,4 @@ -shader_set quad_vertex +shader_set transform_vertex { source quad.shader type vertex diff --git a/files/materials/water.mat b/files/materials/water.mat index a5f9f2ec9..c427447d2 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -34,7 +34,13 @@ material Water { direct_texture water_nm.png } - + + texture_unit rippleNormalMap + { + direct_texture RippleNormal + tex_address_mode border + tex_border_colour 0.5 0.5 1.0 + } // for simple_water texture_unit animatedTexture diff --git a/files/materials/water.shader b/files/materials/water.shader index 9ebea0f00..1e14dd596 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -61,7 +61,7 @@ // Inspired by Blender GLSL Water by martinsh ( http://devlog-martinsh.blogspot.de/2012/07/waterundewater-shader-wip.html ) - +#define RIPPLES 1 #ifdef SH_VERTEX_SHADER @@ -119,8 +119,8 @@ #define WAVE_SCALE 75 // overall wave scale #define BUMP 1.5 // overall water surface bumpiness - #define REFL_BUMP 0.08 // reflection distortion amount - #define REFR_BUMP 0.06 // refraction distortion amount + #define REFL_BUMP 0.16 // reflection distortion amount + #define REFR_BUMP 0.12 // refraction distortion amount #define SCATTER_AMOUNT 3.0 // amount of sunlight scattering #define SCATTER_COLOUR gammaCorrectRead(float3(0.0,1.0,0.95)) // colour of sunlight scattering @@ -159,6 +159,11 @@ shInput(float3, screenCoordsPassthrough) shInput(float4, position) shInput(float, depthPassthrough) + + #if RIPPLES + shUniform(float3, rippleCenter) @shSharedParameter(rippleCenter, rippleCenter) + shUniform(float, rippleAreaLength) @shSharedParameter(rippleAreaLength, rippleAreaLength) + #endif shUniform(float, far) @shAutoConstant(far, far_clip_distance) @@ -166,6 +171,11 @@ shSampler2D(refractionMap) shSampler2D(depthMap) shSampler2D(normalMap) + + #if RIPPLES + shSampler2D(rippleNormalMap) + shUniform(float4x4, wMat) @shAutoConstant(wMat, world_matrix) + #endif shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed) #define WIND_SPEED windDir_windSpeed.z @@ -220,8 +230,14 @@ float3 normal = (normal0 * BIG_WAVES_X + normal1 * BIG_WAVES_Y + normal2 * MID_WAVES_X + normal3 * MID_WAVES_Y + normal4 * SMALL_WAVES_X + normal5 * SMALL_WAVES_Y).xzy; - - normal = normalize(float3(normal.x * BUMP, normal.y, normal.z * BUMP)); + + float4 worldPosition = shMatrixMult(wMat, float4(position.xyz, 1)); + float2 relPos = (worldPosition.xz - rippleCenter.xy) / rippleAreaLength + 0.5; + float3 normal_ripple = normalize(shSample(rippleNormalMap, relPos.xy).xyz * 2 - 1); + normal_ripple = normal_ripple.xzy; + + normal = normalize(normal + normal_ripple); + // normal for sunlight scattering float3 lNormal = (normal0 * BIG_WAVES_X*0.5 + normal1 * BIG_WAVES_Y*0.5 + @@ -303,7 +319,7 @@ } shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - + //shOutputColour(0).xyz = float3(relPos.x, relPos.y, 0); shOutputColour(0).w = 1; } diff --git a/files/materials/watersim.mat b/files/materials/watersim.mat new file mode 100644 index 000000000..b58b1a851 --- /dev/null +++ b/files/materials/watersim.mat @@ -0,0 +1,59 @@ +material HeightmapSimulation +{ + allow_fixed_function false + pass + { + depth_check off + depth_write off + vertex_program transform_vertex + fragment_program watersim_fragment + + texture_unit heightPrevSampler + { + tex_address_mode border + tex_border_colour 0 0 0 + texture_alias Heightmap0 + } + texture_unit heightCurrentSampler + { + tex_address_mode border + tex_border_colour 0 0 0 + texture_alias Heightmap1 + } + } +} + +material HeightToNormalMap +{ + allow_fixed_function false + pass + { + depth_check off + depth_write off + vertex_program transform_vertex + fragment_program height_to_normal_fragment + + texture_unit heightCurrentSampler + { + texture_alias Heightmap2 + } + } +} + +material AddImpulse +{ + allow_fixed_function false + pass + { + depth_check off + depth_write off + scene_blend alpha_blend + vertex_program transform_vertex + fragment_program add_impulse_fragment + + texture_unit alphaMap + { + texture circle.png + } + } +} diff --git a/files/materials/watersim.shaderset b/files/materials/watersim.shaderset new file mode 100644 index 000000000..ea512e25f --- /dev/null +++ b/files/materials/watersim.shaderset @@ -0,0 +1,31 @@ +shader_set transform_vertex +{ + source quad.shader + type vertex + profiles_cg vs_2_0 vp40 arbvp1 + profiles_hlsl vs_2_0 +} + +shader_set watersim_fragment +{ + source watersim_heightmap.shader + type fragment + profiles_cg ps_3_0 ps_2_x ps_2_0 fp40 arbfp1 + profiles_hlsl ps_3_0 ps_2_0 +} + +shader_set height_to_normal_fragment +{ + source watersim_heighttonormal.shader + type fragment + profiles_cg ps_3_0 ps_2_x ps_2_0 fp40 arbfp1 + profiles_hlsl ps_3_0 ps_2_0 +} + +shader_set add_impulse_fragment +{ + source watersim_addimpulse.shader + type fragment + profiles_cg ps_3_0 ps_2_x ps_2_0 fp40 arbfp1 + profiles_hlsl ps_3_0 ps_2_0 +} diff --git a/files/materials/watersim_addimpulse.shader b/files/materials/watersim_addimpulse.shader new file mode 100644 index 000000000..3ca4192cd --- /dev/null +++ b/files/materials/watersim_addimpulse.shader @@ -0,0 +1,12 @@ +#include "core.h" +#include "watersim_common.h" + + SH_BEGIN_PROGRAM + shInput(float2, UV) + shSampler2D(alphaMap) + + SH_START_PROGRAM + { + shOutputColour(0) = EncodeHeightmap(1.0); + shOutputColour(0).a = shSample (alphaMap, UV.xy).a; + } diff --git a/files/materials/watersim_common.h b/files/materials/watersim_common.h new file mode 100644 index 000000000..aa7a636a0 --- /dev/null +++ b/files/materials/watersim_common.h @@ -0,0 +1,25 @@ +float DecodeHeightmap(float4 heightmap) +{ + float4 table = float4(1.0, -1.0, 0.0, 0.0); + return dot(heightmap, table); +} + +float DecodeHeightmap(shTexture2D HeightmapSampler, float2 texcoord) +{ + float4 heightmap = shSample(HeightmapSampler, texcoord); + return DecodeHeightmap(heightmap); +} + +float4 EncodeHeightmap(float fHeight) +{ + float h = fHeight; + float positive = fHeight > 0.0 ? fHeight : 0.0; + float negative = fHeight < 0.0 ? -fHeight : 0.0; + + float4 color = float4(0,0,0,0); + + color.r = positive; + color.g = negative; + + return color; +} diff --git a/files/materials/watersim_heightmap.shader b/files/materials/watersim_heightmap.shader new file mode 100644 index 000000000..e19270d39 --- /dev/null +++ b/files/materials/watersim_heightmap.shader @@ -0,0 +1,42 @@ +#include "core.h" + +#define DAMPING 0.92 + +#include "watersim_common.h" + + SH_BEGIN_PROGRAM + shInput(float2, UV) + shSampler2D(heightPrevSampler) + shSampler2D(heightCurrentSampler) + shUniform(float3, previousFrameOffset) @shSharedParameter(previousFrameOffset, previousFrameOffset) + shUniform(float3, currentFrameOffset) @shSharedParameter(currentFrameOffset, currentFrameOffset) + shUniform(float4, rippleTextureSize) @shSharedParameter(rippleTextureSize, rippleTextureSize) + + SH_START_PROGRAM + { + const float3 offset[4] = float3[4]( + float3(-1.0, 0.0, 0.25), + float3( 1.0, 0.0, 0.25), + float3( 0.0,-1.0, 0.25), + float3( 0.0, 1.0, 0.25) + ); + + float fHeightPrev = DecodeHeightmap(heightPrevSampler, UV.xy + previousFrameOffset.xy + currentFrameOffset.xy); + + float fNeighCurrent = 0; + for ( int i=0; i<4; i++ ) + { + float2 vTexcoord = UV + currentFrameOffset.xy + offset[i].xy * rippleTextureSize.xy; + fNeighCurrent += (DecodeHeightmap(heightCurrentSampler, vTexcoord) * offset[i].z); + } + + float fHeight = fNeighCurrent * 2.0 - fHeightPrev; + + fHeight *= DAMPING; + + shOutputColour(0) = EncodeHeightmap(fHeight); + } + + + + diff --git a/files/materials/watersim_heighttonormal.shader b/files/materials/watersim_heighttonormal.shader new file mode 100644 index 000000000..5402b6bb5 --- /dev/null +++ b/files/materials/watersim_heighttonormal.shader @@ -0,0 +1,27 @@ +#include "core.h" +#include "watersim_common.h" + + SH_BEGIN_PROGRAM + shInput(float2, UV) + shSampler2D(heightCurrentSampler) + shUniform(float4, rippleTextureSize) @shSharedParameter(rippleTextureSize, rippleTextureSize) + + SH_START_PROGRAM + { + float2 offset[4] = float2[4] ( + vec2(-1.0, 0.0), + vec2( 1.0, 0.0), + vec2( 0.0,-1.0), + vec2( 0.0, 1.0) + ); + + float fHeightL = DecodeHeightmap(heightCurrentSampler, UV.xy + offset[0]*rippleTextureSize.xy); + float fHeightR = DecodeHeightmap(heightCurrentSampler, UV.xy + offset[1]*rippleTextureSize.xy); + float fHeightT = DecodeHeightmap(heightCurrentSampler, UV.xy + offset[2]*rippleTextureSize.xy); + float fHeightB = DecodeHeightmap(heightCurrentSampler, UV.xy + offset[3]*rippleTextureSize.xy); + + float3 n = float3(fHeightB - fHeightT, fHeightR - fHeightL, 1.0); + float3 normal = (n + 1.0) * 0.5; + + shOutputColour(0) = float4(normal.rgb, 1.0); + } diff --git a/files/water/circle.png b/files/water/circle.png new file mode 100644 index 0000000000000000000000000000000000000000..9a1cf268c0be2cdae27fe04ee7f7c0aa6de12c11 GIT binary patch literal 753 zcmVPx#32;bRa{vGf6951U69E94oEQKA00(qQO+^RY0s#yODLP_H6#xJL8FWQhbVF}# zZDnqB07G(RVRU6=Aa`kWXdp*PO;A^X4i^9b0$xc(K~#9!?VG<&8$l4pf3r}yK~51x zqM)L&3(GXPrAgYOr>3Lk4JgeU@D%ooAf>PicNCFA3Q(Fz0Zj_eDdq^q=iI@0XFq8g z%YXL!d^@wd^R1{VbwWh8fL)*q99VRLJ>Vno0NepLzy!Fqm;m2Y^|96gs%qr{w1Es5 z0s5aYvhQlwGS&)73oxjN^fEC9fHXz`BmM=rt&w;!ZtXYaT?GL8!0Zi)7h?wW-&_Eo z1q|Pjcrk`RYaK39whD+y2lxtX(=0pyJyo5S`A{fHKC|-FH1gP(CN{?E%OG&pphy0- zIIA=V0OuP-K9BQC1lX{DzVwsu8u@I4$>))+B>>QgfP5aEQe{v?TENeSX8UzZkrykKL0jHxq|slR18ie6i&%hJaRXJH0-u3>;>Esk{G0FcBq$;Re794Y znDGPnq(*%42{?2>9^-iUED6?plGC&pJy{2cNZSr3J>i3@-se-`2!A+Q%mJqk1vt&? z{+2BjJz_gp)50rugLP@Vq8qGLfHVc>U0Sc$6X17bhaaU*iUQ6N9PR-YaTl07 zGrZy^Fz@ww#UwEI<9Nk&62SWuNZVoa;f)=VAFJwPz7V={D8Lnv4n+fis@^-B24my= zq%SbQPhVj0%pc&sHD)iIIC%U|bkP;!y*-``5-%8}h7pn{vCMkPkFQUZP`xp5a z1uzk&z;OiRkC!^glT|jErITI0j0l@xp3c&hnGz`78L}VP0WKRv{?h9Flr;#YYjf%1 jWV$-*_wuxOzdrv5<*cfu_Ri)S00000NkvXXu0mjfBzZwt literal 0 HcmV?d00001 From 15e51b76de89c8366d6573700f63f6f6290c7e3d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Feb 2013 15:46:23 +0100 Subject: [PATCH 14/61] 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. From 5334934612d49b065f71c78717c27c08d1e5ae2f Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Feb 2013 18:03:09 +0100 Subject: [PATCH 15/61] Listen to render window updates and properly activate/deactivate occlusion queries pre/post update. --- apps/openmw/mwrender/refraction.cpp | 5 +++-- apps/openmw/mwrender/renderingmanager.cpp | 19 ++++++++++++++----- apps/openmw/mwrender/renderingmanager.hpp | 8 +++++++- apps/openmw/mwrender/water.cpp | 3 ++- libs/openengine/ogre/renderer.cpp | 1 - 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index 175b85223..88ad70b7f 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -31,9 +31,9 @@ namespace MWRender Refraction::~Refraction() { + mRenderTarget->removeListener(this); Ogre::TextureManager::getSingleton().remove("WaterRefraction"); mParentCamera->getSceneManager()->destroyCamera(mCamera); - mRenderTarget->removeListener(this); } void Refraction::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) @@ -56,7 +56,8 @@ namespace MWRender void Refraction::setWaterPlane(Ogre::Plane plane) { - mNearClipPlane = Ogre::Plane(-plane.normal, - (plane.d + 5) ); + /// \todo + mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,1,0), 0); } } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 18337c7d7..b2e18f1e8 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -62,6 +62,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); mRendering.setWindowEventListener(this); + mRendering.getWindow()->addListener(this); + mCompositors = new Compositors(mRendering.getViewport()); mWater = 0; @@ -174,6 +176,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const RenderingManager::~RenderingManager () { + mRendering.getWindow()->removeListener(this); mRendering.removeWindowEventListener(this); delete mPlayer; @@ -337,10 +340,6 @@ void RenderingManager::update (float duration, bool paused) 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); @@ -396,10 +395,20 @@ void RenderingManager::update (float duration, bool paused) orig = Ogre::Vector3(orig.x, orig.z, -orig.y); mWater->update(duration, orig); } +} +void RenderingManager::preRenderTargetUpdate(const RenderTargetEvent &evt) +{ mOcclusionQuery->setActive(true); } +void RenderingManager::postRenderTargetUpdate(const RenderTargetEvent &evt) +{ + // 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); +} + void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store) { const MWWorld::Store &lands = @@ -886,7 +895,7 @@ void RenderingManager::applyCompositors() mCompositors->addCompositor("gbufferFinalizer", 2); mCompositors->setCompositorEnabled("gbufferFinalizer", true); */ -} + } //if (mWater) //mWater->assignTextures(); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 0a92bb2ea..71ac742c2 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -11,6 +11,8 @@ #include +#include + #include "renderinginterface.hpp" #include "objects.hpp" @@ -47,7 +49,7 @@ namespace MWRender class GlobalMap; class VideoPlayer; -class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener { +class RenderingManager: private RenderingInterface, public Ogre::WindowEventListener, public Ogre::RenderTargetListener { private: @@ -137,6 +139,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void disableLights(bool sun); ///< @param sun whether or not to really disable the sunlight (otherwise just set diffuse to 0) void enableLights(bool sun); + + void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + bool occlusionQuerySupported() { return mOcclusionQuery->supported(); } OcclusionQuery* getOcclusionQuery() { return mOcclusionQuery; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 0533388bc..4ef2aea66 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -185,6 +185,7 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel mRendering(rend), mWaterTimer(0.f), mReflection(NULL), + mRefraction(NULL), mSimulation(NULL) { mSimulation = new RippleSimulation(mSceneMgr); @@ -317,7 +318,7 @@ void Water::setHeight(const float height) { mTop = height; - mWaterPlane = Plane(Vector3::UNIT_Y, height); + mWaterPlane = Plane(Vector3::UNIT_Y, -height); if (mReflection) mReflection->setWaterPlane(mWaterPlane); diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index e6e1d46b8..039aba226 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -211,7 +211,6 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& 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)); From 979a874220267be05b290314846ce34bd054f4d6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Feb 2013 19:01:59 +0100 Subject: [PATCH 16/61] Fixed the custom near clip planes --- apps/openmw/mwrender/refraction.cpp | 6 +++--- apps/openmw/mwrender/refraction.hpp | 2 +- apps/openmw/mwrender/water.cpp | 13 +++++++------ apps/openmw/mwrender/water.hpp | 4 ++-- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index 88ad70b7f..85642bc08 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -25,6 +25,7 @@ namespace MWRender vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain); + vp->setMaterialScheme("water_reflection"); mRenderTarget->setAutoUpdated(true); mRenderTarget->addListener(this); } @@ -54,10 +55,9 @@ namespace MWRender } - void Refraction::setWaterPlane(Ogre::Plane plane) + void Refraction::setHeight(float height) { - /// \todo - mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,1,0), 0); + mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,1,0), -(height + 5)); } } diff --git a/apps/openmw/mwrender/refraction.hpp b/apps/openmw/mwrender/refraction.hpp index 01ec86521..e3777d9cf 100644 --- a/apps/openmw/mwrender/refraction.hpp +++ b/apps/openmw/mwrender/refraction.hpp @@ -20,7 +20,7 @@ namespace MWRender Refraction(Ogre::Camera* parentCamera); ~Refraction(); - void setWaterPlane (Ogre::Plane plane); + void setHeight (float height); void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 4ef2aea66..877a9a953 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -155,10 +155,10 @@ void PlaneReflection::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) mRenderActive = false; } -void PlaneReflection::setWaterPlane (Plane plane) +void PlaneReflection::setHeight (float height) { - mWaterPlane = plane; - mErrorPlane = Plane(plane.normal, mWaterPlane.d - 5); + mWaterPlane = Plane(Ogre::Vector3(0,1,0), height); + mErrorPlane = Plane(Ogre::Vector3(0,1,0), height - 5); } void PlaneReflection::setActive (bool active) @@ -321,9 +321,9 @@ void Water::setHeight(const float height) mWaterPlane = Plane(Vector3::UNIT_Y, -height); if (mReflection) - mReflection->setWaterPlane(mWaterPlane); + mReflection->setHeight(height); if (mRefraction) - mRefraction->setWaterPlane(mWaterPlane); + mRefraction->setHeight(height); mWaterNode->setPosition(0, height, 0); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty(new sh::FloatValue(height))); @@ -423,7 +423,7 @@ void Water::applyRTT() { mReflection = new PlaneReflection(mSceneMgr, mSky); mReflection->setParentCamera (mCamera); - mReflection->setWaterPlane(mWaterPlane); + mReflection->setHeight(mTop); mWater->setRenderQueueGroup(RQG_Water); } else @@ -434,6 +434,7 @@ void Water::applyRTT() mRefraction = NULL; mRefraction = new Refraction(mCamera); + mRefraction->setHeight(mTop); } void Water::applyVisibilityMask() diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 67c788c81..cf181674a 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -39,7 +39,7 @@ namespace MWRender { : mSceneMgr(sceneManager) {} virtual ~Reflection() {} - virtual void setWaterPlane (Ogre::Plane plane) {} + virtual void setHeight (float height) {} virtual void setParentCamera (Ogre::Camera* parent) { mParentCamera = parent; } void setUnderwater(bool underwater) { mIsUnderwater = underwater; } virtual void setActive (bool active) {} @@ -72,7 +72,7 @@ namespace MWRender { PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky); virtual ~PlaneReflection(); - virtual void setWaterPlane (Ogre::Plane plane); + virtual void setHeight (float height); virtual void setActive (bool active); virtual void setVisibilityMask (int flags); From a44dfcd2acaf65ea657a14545b718718957e4872 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Feb 2013 19:28:31 +0100 Subject: [PATCH 17/61] Now that refraction is separated out, we don't have to worry about rendering order. Should fix transparency blending issues around water (eg waterfalls) for good. --- apps/openmw/mwrender/renderingmanager.cpp | 10 +++++----- apps/openmw/mwrender/water.cpp | 5 +---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index b2e18f1e8..aa73bc49b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -867,8 +867,8 @@ void RenderingManager::windowResized(Ogre::RenderWindow* rw) mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight()); const Settings::CategorySettingVector& changed = Settings::Manager::apply(); - MWBase::Environment::get().getInputManager()->processChangedSettings(changed); //FIXME - MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); // FIXME + MWBase::Environment::get().getInputManager()->processChangedSettings(changed); + MWBase::Environment::get().getWindowManager()->processChangedSettings(changed); } void RenderingManager::windowClosed(Ogre::RenderWindow* rw) @@ -878,9 +878,9 @@ void RenderingManager::windowClosed(Ogre::RenderWindow* rw) bool RenderingManager::waterShaderSupported() { - const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); - if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects")) - return false; + //const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); + //if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects")) + //return false; return true; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 877a9a953..0eb35323d 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -424,11 +424,8 @@ void Water::applyRTT() mReflection = new PlaneReflection(mSceneMgr, mSky); mReflection->setParentCamera (mCamera); mReflection->setHeight(mTop); - mWater->setRenderQueueGroup(RQG_Water); } - else - mWater->setRenderQueueGroup(RQG_Alpha); - + mWater->setRenderQueueGroup(RQG_Alpha); delete mRefraction; mRefraction = NULL; From 5cc8af0f14ff975899f2bfbc4e5801311e9191db Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Feb 2013 20:06:03 +0100 Subject: [PATCH 18/61] fix map positions --- apps/openmw/mwgui/loadingscreen.cpp | 2 +- apps/openmw/mwrender/localmap.cpp | 27 +++++++++++++++------------ apps/openmw/mwrender/localmap.hpp | 8 ++++++++ apps/openmw/mwrender/water.cpp | 2 +- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 8fecf4c34..dd5289edb 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/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 1d338df12..3a906138b 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -187,15 +187,6 @@ 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 (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_NONE); - - // make everything visible - mCameraNode->setPosition(Vector3(x, zhigh+100000, y)); //mCellCamera->setFarClipDistance( (zhigh-zlow) * 1.1 ); mCellCamera->setFarClipDistance(0); // infinite @@ -224,6 +215,9 @@ void LocalMap::render(const float x, const float y, TU_RENDERTARGET); RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); + + mCameraSettings[rtt] = Vector3(x, zhigh+100000, y); + rtt->setAutoUpdated(false); Viewport* vp = rtt->addViewport(mCellCamera); vp->setOverlaysEnabled(false); @@ -266,13 +260,19 @@ void LocalMap::render(const float x, const float y, //rtt->writeContentsToFile("./" + texture + ".jpg"); } } - - // re-enable fog - mRendering->getScene()->setFog(FOG_LINEAR, clr, 0, fStart, fEnd); } void LocalMap::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) { + // disable fog (only necessary for fixed function, the shader based + // materials already do this through local_map material configuration) + mOldFogStart = mRendering->getScene()->getFogStart(); + mOldFogEnd = mRendering->getScene()->getFogEnd(); + mOldFogClr = mRendering->getScene()->getFogColour(); + mRendering->getScene()->setFog(FOG_NONE); + + mCellCamera->setPosition(mCameraSettings[evt.source]); + mRenderingManager->disableLights(true); mLight->setVisible(true); evt.source->setAutoUpdated(false); @@ -283,6 +283,9 @@ void LocalMap::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) mRenderingManager->enableLights(true); mLight->setVisible(false); evt.source->removeListener(this); + + // re-enable fog + mRendering->getScene()->setFog(FOG_LINEAR, mOldFogClr, 0, mOldFogStart, mOldFogEnd); } void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 2b1aa3f62..1f528f138 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace MWWorld @@ -120,6 +121,13 @@ namespace MWRender int mCellX, mCellY; Ogre::AxisAlignedBox mBounds; std::string mInteriorName; + + Ogre::ColourValue mOldFogClr; + float mOldFogStart; + float mOldFogEnd; + + // maps texture name to according camera settings + std::map mCameraSettings; }; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 0eb35323d..f2854c879 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -401,7 +401,7 @@ void Water::update(float dt, Ogre::Vector3 player) mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); - //if (player.y <= mTop) + if (player.y <= mTop) { mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); } From fa07288b151d8c6addd9d42177737f29f9b82d78 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Feb 2013 20:29:50 +0100 Subject: [PATCH 19/61] tweaked map light color --- apps/openmw/mwrender/localmap.cpp | 4 ++++ apps/openmw/mwrender/localmap.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 3a906138b..ccad0a5e8 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -271,6 +271,9 @@ void LocalMap::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) mOldFogClr = mRendering->getScene()->getFogColour(); mRendering->getScene()->setFog(FOG_NONE); + mOldAmbient = mRendering->getScene()->getAmbientLight(); + mRendering->getScene()->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.3)); + mCellCamera->setPosition(mCameraSettings[evt.source]); mRenderingManager->disableLights(true); @@ -286,6 +289,7 @@ void LocalMap::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) // re-enable fog mRendering->getScene()->setFog(FOG_LINEAR, mOldFogClr, 0, mOldFogStart, mOldFogEnd); + mRendering->getScene()->setAmbientLight(mOldAmbient); } void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 1f528f138..afdf4b6e5 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -123,6 +123,7 @@ namespace MWRender std::string mInteriorName; Ogre::ColourValue mOldFogClr; + Ogre::ColourValue mOldAmbient; float mOldFogStart; float mOldFogEnd; From a29919d02dd08a58114c22750bc49185e7fe704a Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 Feb 2013 00:39:56 +0100 Subject: [PATCH 20/61] restored global map --- apps/openmw/mwrender/localmap.cpp | 47 +++++++++++-------------------- apps/openmw/mwrender/localmap.hpp | 11 +------- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index ccad0a5e8..e0b7d9a11 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -191,6 +191,20 @@ void LocalMap::render(const float x, const float y, mCellCamera->setFarClipDistance(0); // infinite mCellCamera->setOrthoWindow(xw, yw); + mCellCamera->setPosition(Vector3(x, zhigh+100000, y)); + + // disable fog (only necessary for fixed function, the shader based + // materials already do this through local_map material configuration) + float oldFogStart = mRendering->getScene()->getFogStart(); + float oldFogEnd = mRendering->getScene()->getFogEnd(); + Ogre::ColourValue oldFogColour = mRendering->getScene()->getFogColour(); + mRendering->getScene()->setFog(FOG_NONE); + + // set up lighting + Ogre::ColourValue oldAmbient = mRendering->getScene()->getAmbientLight(); + mRendering->getScene()->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.3)); + mRenderingManager->disableLights(true); + mLight->setVisible(true); TexturePtr tex; // try loading from memory @@ -216,8 +230,6 @@ void LocalMap::render(const float x, const float y, RenderTarget* rtt = tex->getBuffer()->getRenderTarget(); - mCameraSettings[rtt] = Vector3(x, zhigh+100000, y); - rtt->setAutoUpdated(false); Viewport* vp = rtt->addViewport(mCellCamera); vp->setOverlaysEnabled(false); @@ -228,8 +240,7 @@ void LocalMap::render(const float x, const float y, // use fallback techniques without shadows and without mrt vp->setMaterialScheme("local_map"); - rtt->setAutoUpdated(true); - rtt->addListener(this); + rtt->update(); // create "fog of war" texture TexturePtr tex2 = TextureManager::getSingleton().createManual( @@ -260,36 +271,12 @@ void LocalMap::render(const float x, const float y, //rtt->writeContentsToFile("./" + texture + ".jpg"); } } -} - -void LocalMap::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) -{ - // disable fog (only necessary for fixed function, the shader based - // materials already do this through local_map material configuration) - mOldFogStart = mRendering->getScene()->getFogStart(); - mOldFogEnd = mRendering->getScene()->getFogEnd(); - mOldFogClr = mRendering->getScene()->getFogColour(); - mRendering->getScene()->setFog(FOG_NONE); - - mOldAmbient = mRendering->getScene()->getAmbientLight(); - mRendering->getScene()->setAmbientLight(Ogre::ColourValue(0.3, 0.3, 0.3)); - - mCellCamera->setPosition(mCameraSettings[evt.source]); - - 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); // re-enable fog - mRendering->getScene()->setFog(FOG_LINEAR, mOldFogClr, 0, mOldFogStart, mOldFogEnd); - mRendering->getScene()->setAmbientLight(mOldAmbient); + mRendering->getScene()->setFog(FOG_LINEAR, oldFogColour, 0, oldFogStart, oldFogEnd); + mRendering->getScene()->setAmbientLight(oldAmbient); } void LocalMap::getInteriorMapPosition (Ogre::Vector2 pos, float& nX, float& nY, int& x, int& y) diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index afdf4b6e5..9c82258f9 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -5,7 +5,6 @@ #include #include -#include namespace MWWorld { @@ -19,7 +18,7 @@ namespace MWRender /// /// \brief Local map rendering /// - class LocalMap : public Ogre::RenderTargetListener + class LocalMap { public: LocalMap(OEngine::Render::OgreRenderer*, MWRender::RenderingManager* rendering); @@ -71,9 +70,6 @@ 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; @@ -122,11 +118,6 @@ namespace MWRender Ogre::AxisAlignedBox mBounds; std::string mInteriorName; - Ogre::ColourValue mOldFogClr; - Ogre::ColourValue mOldAmbient; - float mOldFogStart; - float mOldFogEnd; - // maps texture name to according camera settings std::map mCameraSettings; }; From 3772cd9257cf127fdbb476d169e831536852572a Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 Feb 2013 14:29:46 +0100 Subject: [PATCH 21/61] Refraction can be disabled separately now --- apps/openmw/mwgui/settingswindow.cpp | 6 ++++ apps/openmw/mwgui/settingswindow.hpp | 1 + apps/openmw/mwrender/renderingmanager.cpp | 22 +++++++++----- apps/openmw/mwrender/water.cpp | 10 ++++-- files/materials/core.h | 6 ---- files/materials/objects.shader | 11 ++----- files/materials/terrain.shader | 16 ++++------ files/materials/water.mat | 3 ++ files/materials/water.shader | 37 ++++++++++++++--------- files/mygui/openmw_settings_window.layout | 7 +++++ files/settings-default.cfg | 6 ++-- 11 files changed, 72 insertions(+), 53 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index c5c6eada2..343c96cec 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -123,6 +123,7 @@ namespace MWGui getWidget(mInvertYButton, "InvertYButton"); getWidget(mUISensitivitySlider, "UISensitivitySlider"); getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); + getWidget(mRefractionButton, "RefractionButton"); mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -133,6 +134,7 @@ namespace MWGui mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled); mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); + mRefractionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -248,6 +250,8 @@ namespace MWGui mShadersButton->setCaption (Settings::Manager::getBool("shaders", "Objects") ? "on" : "off"); mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General")); + mRefractionButton->setCaption (Settings::Manager::getBool("refraction", "Water") ? "on" : "off"); + if (!MWRender::RenderingManager::waterShaderSupported()) { mWaterShaderButton->setEnabled(false); @@ -376,6 +380,8 @@ namespace MWGui { if (_sender == mWaterShaderButton) Settings::Manager::setBool("shader", "Water", newState); + else if (_sender == mRefractionButton) + Settings::Manager::setBool("refraction", "Water", newState); else if (_sender == mUnderwaterButton) { Settings::Manager::setBool("underwater effect", "Water", newState); diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 8ca3ad758..55cc0a870 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -51,6 +51,7 @@ namespace MWGui MyGUI::Button* mShadersButton; MyGUI::Button* mShaderModeButton; MyGUI::Button* mUnderwaterButton; + MyGUI::Button* mRefractionButton; MyGUI::Button* mShadowsEnabledButton; MyGUI::Button* mShadowsLargeDistance; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index aa73bc49b..69f3914e5 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -135,8 +135,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty(new sh::Vector2(1, 0.6))); - sh::Factory::getInstance ().setSharedParameter ("gammaCorrection", sh::makeProperty(new sh::FloatValue( - 1.f))); + sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false"); applyCompositors(); @@ -757,6 +756,7 @@ Compositors* RenderingManager::getCompositors() void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { bool changeRes = false; + bool rebuild = false; // rebuild static geometry (necessary after any material changes) for (Settings::CategorySettingVector::const_iterator it=settings.begin(); it != settings.end(); ++it) { @@ -794,18 +794,23 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec applyCompositors(); sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); - mObjects.rebuildStaticGeometry (); + rebuild = true; mRendering.getViewport ()->setClearEveryFrame (true); } + else if (it->second == "refraction" && it->first == "Water") + { + sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false"); + rebuild = true; + } else if (it->second == "underwater effect" && it->first == "Water") { sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); - mObjects.rebuildStaticGeometry (); + rebuild = true; } else if (it->second == "shaders" && it->first == "Objects") { sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); - mObjects.rebuildStaticGeometry (); + rebuild = true; } else if (it->second == "shader mode" && it->first == "General") { @@ -818,13 +823,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec else lang = sh::Language_CG; sh::Factory::getInstance ().setCurrentLanguage (lang); - mObjects.rebuildStaticGeometry (); + rebuild = true; } else if (it->first == "Shadows") { mShadows->recreate (); - mObjects.rebuildStaticGeometry (); + rebuild = true; } } @@ -842,6 +847,9 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec if (mWater) mWater->processChangedSettings(settings); + + if (rebuild) + mObjects.rebuildStaticGeometry(); } void RenderingManager::setMenuTransparency(float val) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index f2854c879..433aa8af8 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -430,8 +430,11 @@ void Water::applyRTT() delete mRefraction; mRefraction = NULL; - mRefraction = new Refraction(mCamera); - mRefraction->setHeight(mTop); + if (Settings::Manager::getBool("refraction", "Water")) + { + mRefraction = new Refraction(mCamera); + mRefraction->setHeight(mTop); + } } void Water::applyVisibilityMask() @@ -455,7 +458,8 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin it != settings.end(); ++it) { if ( it->first == "Water" && ( - it->second == "shader" + it->second == "shader" + || it->second == "refraction" || it->second == "rtt size")) applyRT = true; diff --git a/files/materials/core.h b/files/materials/core.h index e498a3809..3385e5fac 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -1,9 +1,3 @@ -//#define gammaCorrectRead(v) pow(max(v, 0.00001f), float3(gammaCorrection,gammaCorrection,gammaCorrection)) -//#define gammaCorrectOutput(v) pow(max(v, 0.00001f), float3(1.f/gammaCorrection,1.f/gammaCorrection,1.f/gammaCorrection)) - -#define gammaCorrectRead(v) v -#define gammaCorrectOutput(v) v - #if SH_HLSL == 1 || SH_CG == 1 #define shTexture2D sampler2D diff --git a/files/materials/objects.shader b/files/materials/objects.shader index c68705c42..1e9c4a334 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -112,8 +112,6 @@ shUniform(float, far) @shAutoConstant(far, far_clip_distance) #endif - //shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) - #if LIGHTING shInput(float3, normalPassthrough) shInput(float3, objSpacePositionPassthrough) @@ -180,7 +178,6 @@ SH_START_PROGRAM { shOutputColour(0) = shSample(diffuseMap, UV); - shOutputColour(0).xyz = gammaCorrectRead(shOutputColour(0).xyz); #if LIGHTING float3 normal = normalize(normalPassthrough); @@ -271,7 +268,7 @@ // regular fog only if fragment is above water if (worldPos.y > waterLevel || waterEnabled != 1.f) #endif - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); #endif // prevent negative colour output (for example with negative lights) @@ -286,11 +283,11 @@ float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85)) *waterSunGradient * 0.5; + float3 waterSunColour = float3(0.0,1.0,0.85) *waterSunGradient * 0.5; float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = ( gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; + float3 watercolour = ( float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; @@ -303,8 +300,6 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled); #endif - shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - #if MRT shOutputColour(1) = float4(depthPassthrough / far,1,1,1); #endif diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index dfe998210..9b891e1e8 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -137,8 +137,6 @@ shSampler2D(normalMap) // global normal map - //shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) - @shForeach(@shPropertyString(num_blendmaps)) shSampler2D(blendMap@shIterator) @@ -254,9 +252,9 @@ #if IS_FIRST_PASS == 1 && @shIterator == 0 // first layer of first pass doesn't need a blend map - albedo = gammaCorrectRead(shSample(diffuseMap0, UV * 10).rgb); + albedo = shSample(diffuseMap0, UV * 10).rgb; #else - albedo = shLerp(albedo, gammaCorrectRead(shSample(diffuseMap@shIterator, UV * 10).rgb), blendValues@shPropertyString(blendmap_component_@shIterator)); + albedo = shLerp(albedo, shSample(diffuseMap@shIterator, UV * 10).rgb, blendValues@shPropertyString(blendmap_component_@shIterator)); #endif @shEndForeach @@ -343,7 +341,7 @@ // regular fog only if fragment is above water if (worldPos.y > waterLevel) #endif - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColour), fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); #endif // prevent negative colour output (for example with negative lights) @@ -358,12 +356,12 @@ float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5; + float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; - float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction + float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; + float3 waterext = float3(0.6, 0.9, 1.0);//water extinction watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); watercolour = (cameraPos.y <= waterLevel) ? watercolour : watercolour*0.3; @@ -376,8 +374,6 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater); #endif - shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); - #if MRT shOutputColour(1) = float4(depth / far,1,1,1); #endif diff --git a/files/materials/water.mat b/files/materials/water.mat index 2717f26fc..7546606fc 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -11,6 +11,9 @@ material Water fragment_program water_fragment cull_hardware none + + scene_blend alpha_blend + depth_write off texture_unit reflectionMap { diff --git a/files/materials/water.shader b/files/materials/water.shader index dbe36a91c..b02b4761c 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -62,6 +62,7 @@ // Inspired by Blender GLSL Water by martinsh ( http://devlog-martinsh.blogspot.de/2012/07/waterundewater-shader-wip.html ) #define RIPPLES 1 +#define REFRACTION @shGlobalSettingBool(refraction) #ifdef SH_VERTEX_SHADER @@ -123,9 +124,9 @@ #define REFR_BUMP 0.12 // refraction distortion amount #define SCATTER_AMOUNT 3.0 // amount of sunlight scattering - #define SCATTER_COLOUR gammaCorrectRead(float3(0.0,1.0,0.95)) // colour of sunlight scattering + #define SCATTER_COLOUR float3(0.0,1.0,0.95) // colour of sunlight scattering - #define SUN_EXT gammaCorrectRead(float3(0.45, 0.55, 0.68)) //sunlight extinction + #define SUN_EXT float3(0.45, 0.55, 0.68) //sunlight extinction #define SPEC_HARDNESS 256 // specular highlights hardness @@ -168,7 +169,9 @@ shUniform(float, far) @shAutoConstant(far, far_clip_distance) shSampler2D(reflectionMap) +#if REFRACTION shSampler2D(refractionMap) +#endif shSampler2D(depthMap) shSampler2D(normalMap) @@ -186,9 +189,6 @@ shUniform(float4, sunPosition) @shAutoConstant(sunPosition, light_position, 0) shUniform(float4, sunSpecular) @shAutoConstant(sunSpecular, light_specular_colour, 0) - - shUniform(float, gammaCorrection) @shSharedParameter(gammaCorrection, gammaCorrection) - shUniform(float, renderTargetFlipping) @shAutoConstant(renderTargetFlipping, render_target_flipping) @@ -255,7 +255,7 @@ float s = shSaturate(dot(lR, vVec)*2.0-1.2); float lightScatter = shSaturate(dot(-lVec,lNormal)*0.7+0.3) * s * SCATTER_AMOUNT * waterSunFade_sunHeight.x * shSaturate(1.0-exp(-waterSunFade_sunHeight.y)); - float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*gammaCorrectRead(float3(1.0,0.4,0.0)), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); + float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*float3(1.0,0.4,0.0), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); // fresnel float ior = (cameraPos.y>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air @@ -264,32 +264,36 @@ fresnel = shSaturate(fresnel); // reflection - float3 reflection = gammaCorrectRead(shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb); + float3 reflection = shSample(reflectionMap, screenCoords+(normal.xz*REFL_BUMP)).rgb; // refraction float3 R = reflect(vVec, normal); - float3 refraction = gammaCorrectRead(shSample(refractionMap, (screenCoords-(normal.xz*REFR_BUMP))*1.0).rgb); +#if REFRACTION + float3 refraction = shSample(refractionMap, (screenCoords-(normal.xz*REFR_BUMP))*1.0).rgb; // brighten up the refraction underwater refraction = (cameraPos.y < 0) ? shSaturate(refraction * 1.5) : refraction; - +#endif // specular float specular = pow(max(dot(R, lVec), 0.0),SPEC_HARDNESS); +#if REFRACTION shOutputColour(0).xyz = shLerp( shLerp(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * sunSpecular.xyz; - +#else + shOutputColour(0).xyz = reflection + specular * sunSpecular.xyz; +#endif // fog if (isUnderwater == 1) { float waterSunGradient = dot(-vVec, -lVec); waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = gammaCorrectRead(float3(0.0,1.0,0.85))*waterSunGradient * 0.5; + float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; float waterGradient = dot(-vVec, float3(0.0,-1.0,0.0)); waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = (gammaCorrectRead(float3(0.0078, 0.5176, 0.700))+waterSunColour)*waterGradient*2.0; - float3 waterext = gammaCorrectRead(float3(0.6, 0.9, 1.0));//water extinction + float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; + float3 waterext = float3(0.6, 0.9, 1.0);//water extinction watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); float darkness = VISIBILITY*2.0; @@ -302,11 +306,14 @@ else { float fogValue = shSaturate((length(cameraPos.xyz-position.xyz) - fogParams.y) * fogParams.w); - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, gammaCorrectRead(fogColor), fogValue); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); } - shOutputColour(0).xyz = gammaCorrectOutput(shOutputColour(0).xyz); +#if REFRACTION shOutputColour(0).w = 1; +#else + shOutputColour(0).w = shSaturate(fresnel + specular); +#endif } #endif diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index f03305ae7..5b7f106f3 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -285,6 +285,13 @@ + + + + + + + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 31aa60c42..044cc3406 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -127,11 +127,10 @@ fog end factor = 1.0 num lights = 8 [Water] -# Enable this to get fancy-looking water with reflections and refractions -# Only available if object shaders are on -# All the settings below have no effect if this is false shader = false +refraction = false + rtt size = 512 reflect terrain = true reflect statics = false @@ -139,7 +138,6 @@ reflect small statics = false reflect actors = false reflect misc = false -# Enable underwater effect. It is not resource intensive, so only disable it if you have problems. underwater effect = false [Sound] From 499f3ac0d18165cdf0079fa5c711aa390993fd42 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 Feb 2013 16:40:41 +0100 Subject: [PATCH 22/61] Slightly better ripple normal blending. Not physically accurate at all, but looks good. --- apps/openmw/mwrender/ripplesimulation.cpp | 10 +++++++--- apps/openmw/mwrender/ripplesimulation.hpp | 2 ++ apps/openmw/mwrender/water.cpp | 3 ++- files/materials/water.shader | 7 ++++--- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index 043757e88..249397005 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -20,7 +20,8 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) mTextureSize(512), mRippleAreaLength(1000), mImpulseSize(20), - mTexelOffset(0,0) + mTexelOffset(0,0), + mFirstUpdate(true) { Ogre::AxisAlignedBox aabInf; aabInf.setInfinite(); @@ -106,7 +107,7 @@ void RippleSimulation::update(float dt, Ogre::Vector2 position) // try to keep 20 fps mTime += dt; - while (mTime >= 1/20.0) + while (mTime >= 1/20.0 || mFirstUpdate) { mPreviousFrameOffset = mCurrentFrameOffset; @@ -130,7 +131,10 @@ void RippleSimulation::update(float dt, Ogre::Vector2 position) heightMapToNormalMap(); swapHeightMaps(); - mTime -= 1/20.0; + if (!mFirstUpdate) + mTime -= 1/20.0; + else + mFirstUpdate = false; } sh::Factory::getInstance().setSharedParameter("rippleCenter", sh::makeProperty( diff --git a/apps/openmw/mwrender/ripplesimulation.hpp b/apps/openmw/mwrender/ripplesimulation.hpp index 72ff3dbd8..c792a3214 100644 --- a/apps/openmw/mwrender/ripplesimulation.hpp +++ b/apps/openmw/mwrender/ripplesimulation.hpp @@ -34,6 +34,8 @@ private: float mRippleAreaLength; float mImpulseSize; + bool mFirstUpdate; + Ogre::Camera* mCamera; // own scenemanager to render our simulation diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 433aa8af8..4ff8945ac 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -401,7 +401,8 @@ void Water::update(float dt, Ogre::Vector3 player) mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); - if (player.y <= mTop) + /// \todo player.y is the scene node position (which is above the head) and not the feet position + //if (player.y <= mTop) { mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); } diff --git a/files/materials/water.shader b/files/materials/water.shader index b02b4761c..400fbefb2 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -120,8 +120,8 @@ #define WAVE_SCALE 75 // overall wave scale #define BUMP 1.5 // overall water surface bumpiness - #define REFL_BUMP 0.16 // reflection distortion amount - #define REFR_BUMP 0.12 // refraction distortion amount + #define REFL_BUMP 0.08 // reflection distortion amount + #define REFR_BUMP 0.06 // refraction distortion amount #define SCATTER_AMOUNT 3.0 // amount of sunlight scattering #define SCATTER_COLOUR float3(0.0,1.0,0.95) // colour of sunlight scattering @@ -232,7 +232,8 @@ float3 normal_ripple = normalize(shSample(rippleNormalMap, relPos.xy).xyz * 2 - 1); normal_ripple = normal_ripple.xzy; - normal = normalize(normal + normal_ripple); + //normal = normalize(normal + normal_ripple); + normal = normalize(float3(normal.x + normal_ripple.x, normal.y, normal.z + normal_ripple.z)); // normal for sunlight scattering From c4d518132f83cb0697361fa98e69e3b1bd6a8b88 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 Feb 2013 19:22:08 +0100 Subject: [PATCH 23/61] With the 1x1 background window trick, we can apply VSync without restart. Some issues left though. --- apps/openmw/mwbase/inputmanager.hpp | 3 +++ apps/openmw/mwgui/settingswindow.cpp | 8 ++----- apps/openmw/mwinput/inputmanagerimp.cpp | 28 ++++++++++++++++++---- apps/openmw/mwinput/inputmanagerimp.hpp | 8 +++++++ apps/openmw/mwrender/renderingmanager.cpp | 29 ++++++++++++++++++++++- apps/openmw/mwrender/renderingmanager.hpp | 2 ++ libs/openengine/ogre/renderer.cpp | 25 +++++++++++++++---- libs/openengine/ogre/renderer.hpp | 3 +++ 8 files changed, 90 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 8293cbfa7..f69e1a152 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -39,6 +39,9 @@ namespace MWBase virtual int getNumActions() = 0; virtual void enableDetectingBindingMode (int action) = 0; virtual void resetToDefaultBindings() = 0; + + virtual void create () = 0; + virtual void destroy () = 0; }; } diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 343c96cec..75fc2b7a2 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -370,14 +370,10 @@ namespace MWGui apply(); } } - else if (_sender == mVSyncButton) - { - Settings::Manager::setBool("vsync", "Video", newState); - MWBase::Environment::get().getWindowManager()-> - messageBox("VSync will be applied after a restart", std::vector()); - } else { + if (_sender == mVSyncButton) + Settings::Manager::setBool("vsync", "Video", newState); if (_sender == mWaterShaderButton) Settings::Manager::setBool("shader", "Water", newState); else if (_sender == mRefractionButton) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 1f270df8b..95d221933 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -41,9 +41,11 @@ namespace MWInput , mMouseX(ogre.getWindow()->getWidth ()/2.f) , mMouseY(ogre.getWindow()->getHeight ()/2.f) , mMouseWheel(0) - , mUserFile(userFile) , mDragDrop(false) , mGuiCursorEnabled(false) + , mDebug(debug) + , mUserFile(userFile) + , mUserFileExists(userFileExists) , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mUISensitivity (Settings::Manager::getFloat("ui sensitivity", "Input")) @@ -51,8 +53,15 @@ namespace MWInput , mUIYMultiplier (Settings::Manager::getFloat("ui y multiplier", "Input")) , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) + , mCreated(false) + { + create(); + } + + + void InputManager::create() { - Ogre::RenderWindow* window = ogre.getWindow (); + Ogre::RenderWindow* window = mOgre.getWindow (); size_t windowHnd; resetIdleTime(); @@ -67,7 +76,7 @@ namespace MWInput // Set non-exclusive mouse and keyboard input if the user requested // it. - if (debug) + if (mDebug) { #if defined OIS_WIN32_PLATFORM pl.insert(std::make_pair(std::string("w32_mouse"), @@ -112,7 +121,7 @@ namespace MWInput MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs); - std::string file = userFileExists ? userFile : ""; + std::string file = mUserFileExists ? mUserFile : ""; mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); loadKeyDefaults(); @@ -131,9 +140,11 @@ namespace MWInput mControlSwitch["vanitymode"] = true; changeInputMode(false); + + mCreated = true; } - InputManager::~InputManager() + void InputManager::destroy() { mInputCtrl->save (mUserFile); @@ -142,6 +153,12 @@ namespace MWInput mInputManager->destroyInputObject(mKeyboard); mInputManager->destroyInputObject(mMouse); OIS::InputManager::destroyInputSystem(mInputManager); + mCreated = false; + } + + InputManager::~InputManager() + { + destroy(); } void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) @@ -239,6 +256,7 @@ namespace MWInput void InputManager::update(float dt, bool loading) { + if (!mCreated) return; // Tell OIS to handle all input events mKeyboard->capture(); mMouse->capture(); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 9deed1f28..100bba4fb 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -131,6 +131,8 @@ namespace MWInput std::string mUserFile; + bool mCreated; + bool mDragDrop; bool mInvertY; @@ -148,9 +150,15 @@ namespace MWInput float mMouseX; float mMouseY; int mMouseWheel; + bool mDebug; + bool mUserFileExists; std::map mControlSwitch; + public: + virtual void create(); + virtual void destroy(); + private: void adjustMouseRegion(int width, int height); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 69f3914e5..9e50b2bce 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -46,7 +46,8 @@ namespace MWRender { RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) - : mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine) + : mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine), + mRecreateWindowInNextFrame(false) { // select best shader mode bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); @@ -323,6 +324,22 @@ RenderingManager::moveObjectToCell( void RenderingManager::update (float duration, bool paused) { + if (mRecreateWindowInNextFrame) + { + MWBase::Environment::get().getInputManager()->destroy(); + + OEngine::Render::WindowSettings windowSettings; + windowSettings.fullscreen = Settings::Manager::getBool("fullscreen", "Video"); + windowSettings.window_x = Settings::Manager::getInt("resolution x", "Video"); + windowSettings.window_y = Settings::Manager::getInt("resolution y", "Video"); + windowSettings.vsync = Settings::Manager::getBool("vsync", "Video"); + std::string aa = Settings::Manager::getString("antialiasing", "Video"); + windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0"; + mRendering.recreateWindow("OpenMW", windowSettings); + + MWBase::Environment::get().getInputManager()->create(); + mRecreateWindowInNextFrame = false; + } Ogre::Vector3 orig, dest; mPlayer->setCameraDistance(); if (!mPlayer->getPosition(orig, dest)) { @@ -756,6 +773,7 @@ Compositors* RenderingManager::getCompositors() void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { bool changeRes = false; + bool recreateWindow = false; bool rebuild = false; // rebuild static geometry (necessary after any material changes) for (Settings::CategorySettingVector::const_iterator it=settings.begin(); it != settings.end(); ++it) @@ -774,6 +792,8 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec || it->second == "resolution y" || it->second == "fullscreen")) changeRes = true; + else if (it->first == "Video" && it->second == "vsync") + recreateWindow = true; else if (it->second == "field of view" && it->first == "General") mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); else if ((it->second == "texture filtering" && it->first == "General") @@ -845,6 +865,13 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } + if (recreateWindow) + { + mRecreateWindowInNextFrame = true; + // We can not do this now, because this might get triggered from the input listener + // and destroying/recreating the input system at that point would cause a crash + } + if (mWater) mWater->processChangedSettings(settings); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 71ac742c2..670f3dc85 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -260,6 +260,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList MWRender::Compositors* mCompositors; VideoPlayer* mVideoPlayer; + + bool mRecreateWindowInNextFrame; }; } diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index 039aba226..e0abf420e 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -205,13 +205,31 @@ void OgreRenderer::configure(const std::string &logPath, rs->setConfigOption ("RTT Preferred Mode", rttMode); } +void OgreRenderer::recreateWindow(const std::string &title, const WindowSettings &settings) +{ + Ogre::ColourValue viewportBG = mView->getBackgroundColour(); + + mRoot->destroyRenderTarget(mWindow); + 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 one viewport, entire window + mView = mWindow->addViewport(mCamera); + mView->setBackgroundColour(viewportBG); + + adjustViewport(); +} + void OgreRenderer::createWindow(const std::string &title, const WindowSettings& settings) { assert(mRoot); mRoot->initialise(false); // create a hidden 1x1 background window to keep resources when recreating the secondary (real) window - /* NameValuePairList params_; params_.insert(std::make_pair("title", title)); params_.insert(std::make_pair("FSAA", "0")); @@ -219,7 +237,6 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& 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)); @@ -271,12 +288,12 @@ void OgreRenderer::adjustViewport() void OgreRenderer::setWindowEventListener(Ogre::WindowEventListener* listener) { - Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener); + //Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener); } void OgreRenderer::removeWindowEventListener(Ogre::WindowEventListener* listener) { - Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, listener); + //Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, listener); } void OgreRenderer::setFov(float fov) diff --git a/libs/openengine/ogre/renderer.hpp b/libs/openengine/ogre/renderer.hpp index a8788dfca..251dc9c54 100644 --- a/libs/openengine/ogre/renderer.hpp +++ b/libs/openengine/ogre/renderer.hpp @@ -66,6 +66,7 @@ namespace OEngine #endif class Fader; + class OgreRenderer { #if defined(__APPLE__) && !defined(__LP64__) @@ -138,6 +139,8 @@ namespace OEngine /// Create a window with the given title void createWindow(const std::string &title, const WindowSettings& settings); + void recreateWindow (const std::string &title, const WindowSettings& settings); + /// Set up the scene manager, camera and viewport void createScene(const std::string& camName="Camera",// Camera name float fov=55, // Field of view angle From 31f760cccec9a1bab571181e38699f8357b8b285 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 Feb 2013 20:26:13 +0100 Subject: [PATCH 24/61] Fixing issues from last commit: restored input and occlusion queries --- apps/openmw/mwinput/inputmanagerimp.cpp | 11 +++-------- apps/openmw/mwinput/inputmanagerimp.hpp | 2 -- apps/openmw/mwrender/occlusionquery.cpp | 13 ++++++++++++- apps/openmw/mwrender/occlusionquery.hpp | 1 - apps/openmw/mwrender/renderingmanager.cpp | 13 ++++++++++++- apps/openmw/mwrender/water.cpp | 2 +- libs/openengine/ogre/renderer.cpp | 4 ++-- 7 files changed, 30 insertions(+), 16 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 95d221933..00849503c 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -53,9 +53,10 @@ namespace MWInput , mUIYMultiplier (Settings::Manager::getFloat("ui y multiplier", "Input")) , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) - , mCreated(false) { create(); + + changeInputMode(false); } @@ -138,10 +139,6 @@ namespace MWInput mControlSwitch["playermagic"] = true; mControlSwitch["playerviewswitch"] = true; mControlSwitch["vanitymode"] = true; - - changeInputMode(false); - - mCreated = true; } void InputManager::destroy() @@ -153,7 +150,6 @@ namespace MWInput mInputManager->destroyInputObject(mKeyboard); mInputManager->destroyInputObject(mMouse); OIS::InputManager::destroyInputSystem(mInputManager); - mCreated = false; } InputManager::~InputManager() @@ -250,13 +246,12 @@ namespace MWInput case A_ToggleHUD: mWindows.toggleHud(); break; - } + } } } void InputManager::update(float dt, bool loading) { - if (!mCreated) return; // Tell OIS to handle all input events mKeyboard->capture(); mMouse->capture(); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 100bba4fb..7be35ee0b 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -131,8 +131,6 @@ namespace MWInput std::string mUserFile; - bool mCreated; - bool mDragDrop; bool mInvertY; diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index c9e649fe6..8d16d7b7d 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -15,7 +15,7 @@ using namespace Ogre; OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0), mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), - mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false), + mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mBBNode(0), mActive(false) { mRendering = renderer; @@ -94,6 +94,9 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod OcclusionQuery::~OcclusionQuery() { + mRendering->getScene()->removeRenderObjectListener (this); + mRendering->getScene()->removeRenderQueueListener(this); + RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); if (mSunTotalAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunTotalAreaQuery); if (mSunVisibleAreaQuery) renderSystem->destroyHardwareOcclusionQuery(mSunVisibleAreaQuery); @@ -109,6 +112,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass 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 the intended meshes @@ -116,6 +120,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass // Each occlusion query should only last a single rendering if (mActiveQuery != NULL) { + std::cout << "ending query (notifyRenderSingleObject)" << std::endl; mActiveQuery->endOcclusionQuery(); mActiveQuery = NULL; } @@ -123,6 +128,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass // Open a new occlusion query if (mDoQuery == true) { + std::cout << "opening new query" << std::endl; if (rend == mBBQueryTotal) { mActiveQuery = mSunTotalAreaQuery; @@ -208,6 +214,7 @@ void OcclusionQuery::update(float duration) && !mSunVisibleAreaQuery->isStillOutstanding() && !mSingleObjectQuery->isStillOutstanding()) { + std::cout << "update(), nothing is outstanding"<< std::endl; unsigned int totalPixels; unsigned int visiblePixels; @@ -243,6 +250,8 @@ void OcclusionQuery::occlusionTest(const Ogre::Vector3& position, Ogre::SceneNod assert( !occlusionTestPending() && "Occlusion test still pending"); + std::cout << "Occlusion test called " << std::endl; + mBBQuerySingleObject->setVisible(true); mObjectNode->setPosition(position); @@ -250,6 +259,8 @@ void OcclusionQuery::occlusionTest(const Ogre::Vector3& position, Ogre::SceneNod mObjectNode->setScale( Vector3(1,1,1)*(position - mRendering->getCamera()->getRealPosition()).length() ); mQuerySingleObjectRequested = true; + + mDoQuery = true; } bool OcclusionQuery::occlusionTestPending() diff --git a/apps/openmw/mwrender/occlusionquery.hpp b/apps/openmw/mwrender/occlusionquery.hpp index af6f668c1..c7a5757d3 100644 --- a/apps/openmw/mwrender/occlusionquery.hpp +++ b/apps/openmw/mwrender/occlusionquery.hpp @@ -95,7 +95,6 @@ namespace MWRender bool mSupported; bool mDoQuery; - bool mDoQuery2; bool mQuerySingleObjectRequested; bool mQuerySingleObjectStarted; diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 9e50b2bce..afbdbb06f 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -326,6 +326,10 @@ void RenderingManager::update (float duration, bool paused) { if (mRecreateWindowInNextFrame) { + mRecreateWindowInNextFrame = false; + + mRendering.removeWindowEventListener(this); + mRendering.getWindow()->removeListener(this); MWBase::Environment::get().getInputManager()->destroy(); OEngine::Render::WindowSettings windowSettings; @@ -338,8 +342,15 @@ void RenderingManager::update (float duration, bool paused) mRendering.recreateWindow("OpenMW", windowSettings); MWBase::Environment::get().getInputManager()->create(); - mRecreateWindowInNextFrame = false; + mRendering.setWindowEventListener (this); + mRendering.getWindow()->addListener(this); + + // this is necessary, otherwise it would just endlessly wait for the last query and it would never return + delete mOcclusionQuery; + mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); } + + Ogre::Vector3 orig, dest; mPlayer->setCameraDistance(); if (!mPlayer->getPosition(orig, dest)) { diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 4ff8945ac..867829564 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -418,7 +418,7 @@ void Water::applyRTT() mReflection = NULL; // Create rendertarget for reflection - int rttsize = Settings::Manager::getInt("rtt size", "Water"); + //int rttsize = Settings::Manager::getInt("rtt size", "Water"); if (Settings::Manager::getBool("shader", "Water")) { diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index e0abf420e..c4f35e087 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -288,12 +288,12 @@ void OgreRenderer::adjustViewport() void OgreRenderer::setWindowEventListener(Ogre::WindowEventListener* listener) { - //Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener); + Ogre::WindowEventUtilities::addWindowEventListener(mWindow, listener); } void OgreRenderer::removeWindowEventListener(Ogre::WindowEventListener* listener) { - //Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, listener); + Ogre::WindowEventUtilities::removeWindowEventListener(mWindow, listener); } void OgreRenderer::setFov(float fov) From 608c112f34461760264240ded5f5140d2a24c7c2 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 Feb 2013 20:48:25 +0100 Subject: [PATCH 25/61] Supply the new render window to mygui --- apps/openmw/mwgui/loadingscreen.hpp | 2 ++ apps/openmw/mwgui/windowmanagerimp.cpp | 15 ++++++++++++--- apps/openmw/mwgui/windowmanagerimp.hpp | 1 + apps/openmw/mwrender/occlusionquery.cpp | 5 ----- libs/openengine/gui/manager.cpp | 6 ++++++ libs/openengine/gui/manager.hpp | 2 ++ 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/loadingscreen.hpp b/apps/openmw/mwgui/loadingscreen.hpp index c14087a3b..24b385071 100644 --- a/apps/openmw/mwgui/loadingscreen.hpp +++ b/apps/openmw/mwgui/loadingscreen.hpp @@ -19,6 +19,8 @@ namespace MWGui void onResChange(int w, int h); + void updateWindow(Ogre::RenderWindow* rw) { mWindow = rw; } + private: bool mFirstLoad; diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index a1f915ac9..3ae0f37c5 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -56,10 +56,11 @@ using namespace MWGui; WindowManager::WindowManager( - const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *mOgre, + const Compiler::Extensions& extensions, int fpsLevel, bool newGame, OEngine::Render::OgreRenderer *ogre, const std::string& logpath, const std::string& cacheDir, bool consoleOnlyScripts, Translation::Storage& translationDataStorage) : mGuiManager(NULL) + , mRendering(ogre) , mHud(NULL) , mMap(NULL) , mMenu(NULL) @@ -111,7 +112,7 @@ WindowManager::WindowManager( { // Set up the GUI system - mGuiManager = new OEngine::GUI::MyGUIManager(mOgre->getWindow(), mOgre->getScene(), false, logpath); + mGuiManager = new OEngine::GUI::MyGUIManager(mRendering->getWindow(), mRendering->getScene(), false, logpath); mGui = mGuiManager->getGui(); //Register own widgets with MyGUI @@ -172,7 +173,7 @@ WindowManager::WindowManager( mEnchantingDialog = new EnchantingDialog(*this); mTrainingWindow = new TrainingWindow(*this); - mLoadingScreen = new LoadingScreen(mOgre->getScene (), mOgre->getWindow (), *this); + mLoadingScreen = new LoadingScreen(mRendering->getScene (), mRendering->getWindow (), *this); mLoadingScreen->onResChange (w,h); mInputBlocker = mGui->createWidget("",0,0,w,h,MyGUI::Align::Default,"Windows",""); @@ -763,6 +764,7 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector mToolTips->setDelay(Settings::Manager::getFloat("tooltip delay", "GUI")); bool changeRes = false; + bool windowRecreated = false; for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) { @@ -772,6 +774,8 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector { changeRes = true; } + else if (it->first == "Video" && it->second == "vsync") + windowRecreated = true; else if (it->first == "HUD" && it->second == "crosshair") mCrosshairEnabled = Settings::Manager::getBool ("crosshair", "HUD"); else if (it->first == "GUI" && it->second == "subtitles") @@ -795,6 +799,11 @@ void WindowManager::processChangedSettings(const Settings::CategorySettingVector mDragAndDrop->mDragAndDropWidget->setSize(MyGUI::IntSize(x, y)); mInputBlocker->setSize(MyGUI::IntSize(x,y)); } + if (windowRecreated) + { + mGuiManager->updateWindow (mRendering->getWindow ()); + mLoadingScreen->updateWindow (mRendering->getWindow ()); + } } void WindowManager::pushGuiMode(GuiMode mode) diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index 8bcb88e22..bae195669 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -229,6 +229,7 @@ namespace MWGui private: OEngine::GUI::MyGUIManager *mGuiManager; + OEngine::Render::OgreRenderer *mRendering; HUD *mHud; MapWindow *mMap; MainMenu *mMenu; diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 8d16d7b7d..81a3f4327 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -120,7 +120,6 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass // Each occlusion query should only last a single rendering if (mActiveQuery != NULL) { - std::cout << "ending query (notifyRenderSingleObject)" << std::endl; mActiveQuery->endOcclusionQuery(); mActiveQuery = NULL; } @@ -128,7 +127,6 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass // Open a new occlusion query if (mDoQuery == true) { - std::cout << "opening new query" << std::endl; if (rend == mBBQueryTotal) { mActiveQuery = mSunTotalAreaQuery; @@ -214,7 +212,6 @@ void OcclusionQuery::update(float duration) && !mSunVisibleAreaQuery->isStillOutstanding() && !mSingleObjectQuery->isStillOutstanding()) { - std::cout << "update(), nothing is outstanding"<< std::endl; unsigned int totalPixels; unsigned int visiblePixels; @@ -250,8 +247,6 @@ void OcclusionQuery::occlusionTest(const Ogre::Vector3& position, Ogre::SceneNod assert( !occlusionTestPending() && "Occlusion test still pending"); - std::cout << "Occlusion test called " << std::endl; - mBBQuerySingleObject->setVisible(true); mObjectNode->setPosition(position); diff --git a/libs/openengine/gui/manager.cpp b/libs/openengine/gui/manager.cpp index 925891e1b..9cc2bf381 100644 --- a/libs/openengine/gui/manager.cpp +++ b/libs/openengine/gui/manager.cpp @@ -56,6 +56,12 @@ void MyGUIManager::setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool mGui->initialise("core.xml"); } +void MyGUIManager::updateWindow (Ogre::RenderWindow *wnd) +{ + mRenderManager->setRenderWindow (wnd); + mRenderManager->setActiveViewport(0); +} + void MyGUIManager::shutdown() { mGui->shutdown (); diff --git a/libs/openengine/gui/manager.hpp b/libs/openengine/gui/manager.hpp index c0f98da88..39948a829 100644 --- a/libs/openengine/gui/manager.hpp +++ b/libs/openengine/gui/manager.hpp @@ -38,6 +38,8 @@ namespace GUI shutdown(); } + void updateWindow (Ogre::RenderWindow* wnd); + void setup(Ogre::RenderWindow *wnd, Ogre::SceneManager *mgr, bool logging=false, const std::string& logDir = std::string("")); void shutdown(); From 86d65519e370041b7b9422bb85a188eadba96c56 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 5 Feb 2013 23:57:30 +0100 Subject: [PATCH 26/61] Settings window fix --- apps/openmw/mwgui/settingswindow.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 75fc2b7a2..eaea022c0 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -247,10 +247,10 @@ namespace MWGui mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}"); - mShadersButton->setCaption (Settings::Manager::getBool("shaders", "Objects") ? "on" : "off"); + mShadersButton->setCaptionWithReplacing (Settings::Manager::getBool("shaders", "Objects") ? "#{sOn}" : "#{sOff}"); mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General")); - mRefractionButton->setCaption (Settings::Manager::getBool("refraction", "Water") ? "on" : "off"); + mRefractionButton->setCaptionWithReplacing (Settings::Manager::getBool("refraction", "Water") ? "#{sOn}" : "#{sOff}"); if (!MWRender::RenderingManager::waterShaderSupported()) { @@ -434,14 +434,17 @@ namespace MWGui void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender) { + std::string on = mWindowManager.getGameSettingString("sOn", "On"); + std::string off = mWindowManager.getGameSettingString("sOff", "On"); + std::string val = static_cast(_sender)->getCaption(); - if (val == "off") - val = "on"; + if (val == off) + val = on; else - val = "off"; - static_cast(_sender)->setCaption (val); + val = off; + static_cast(_sender)->setCaptionWithReplacing (val); - if (val == "off") + if (val == off) { Settings::Manager::setBool("shaders", "Objects", false); From d213ff680ff5e71874ef33065d38f1285d68e67a Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 12 Feb 2013 20:55:45 +0100 Subject: [PATCH 27/61] Disabled terrain LOD --- apps/openmw/mwrender/terrain.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 2c2e9e6fc..df8d34e74 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -40,9 +40,9 @@ namespace MWRender ->getActiveProfile(); mActiveProfile = static_cast(activeProfile); - //The pixel error should be as high as possible without it being noticed - //as it governs how fast mesh quality decreases. - mTerrainGlobals->setMaxPixelError(8); + // We don't want any pixel error at all. Really, LOD makes no sense here - morrowind uses 65x65 verts in one cell, + // so applying LOD is most certainly slower than doing no LOD at all. + mTerrainGlobals->setMaxPixelError(0); mTerrainGlobals->setLayerBlendMapSize(32); From de90b911c9d729fc4abe856fed525d565beb1c71 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 12 Feb 2013 20:56:00 +0100 Subject: [PATCH 28/61] Near clip plane corrections --- apps/openmw/mwrender/refraction.cpp | 36 ++++++++++++++++++++++++++--- apps/openmw/mwrender/refraction.hpp | 11 ++++++++- apps/openmw/mwrender/water.cpp | 9 ++++++-- apps/openmw/mwrender/water.hpp | 1 + 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index 85642bc08..05229da1d 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "renderconst.hpp" @@ -14,9 +15,13 @@ namespace MWRender Refraction::Refraction(Ogre::Camera *parentCamera) : mParentCamera(parentCamera) + , mRenderActive(false) + , mIsUnderwater(false) { mCamera = mParentCamera->getSceneManager()->createCamera("RefractionCamera"); + mParentCamera->getSceneManager()->addRenderQueueListener(this); + 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); @@ -24,7 +29,7 @@ namespace MWRender Ogre::Viewport* vp = mRenderTarget->addViewport(mCamera); vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); - vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain); + vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky); vp->setMaterialScheme("water_reflection"); mRenderTarget->setAutoUpdated(true); mRenderTarget->addListener(this); @@ -47,17 +52,42 @@ namespace MWRender mCamera->setAspectRatio(mParentCamera->getAspectRatio()); mCamera->setFOVy(mParentCamera->getFOVy()); - mCamera->enableCustomNearClipPlane(mNearClipPlane); + mRenderActive = true; } void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) { - + mRenderActive = false; } void Refraction::setHeight(float height) { mNearClipPlane = Ogre::Plane( -Ogre::Vector3(0,1,0), -(height + 5)); + mNearClipPlaneUnderwater = Ogre::Plane( Ogre::Vector3(0,1,0), height - 5); + } + + void Refraction::setViewportBackground (Ogre::ColourValue colour) + { + mRenderTarget->getViewport (0)->setBackgroundColour (colour); + } + + void Refraction::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) + { + // We don't want the sky to get clipped by custom near clip plane (the water plane) + if (queueGroupId < 20 && mRenderActive) + { + mCamera->disableCustomNearClipPlane(); + Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); + } + } + + void Refraction::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation) + { + if (queueGroupId < 20 && mRenderActive) + { + mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane); + Ogre::Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); + } } } diff --git a/apps/openmw/mwrender/refraction.hpp b/apps/openmw/mwrender/refraction.hpp index e3777d9cf..6b3c487c1 100644 --- a/apps/openmw/mwrender/refraction.hpp +++ b/apps/openmw/mwrender/refraction.hpp @@ -3,6 +3,7 @@ #include #include +#include namespace Ogre { @@ -13,7 +14,7 @@ namespace Ogre namespace MWRender { - class Refraction : public Ogre::RenderTargetListener + class Refraction : public Ogre::RenderTargetListener, public Ogre::RenderQueueListener { public: @@ -23,12 +24,20 @@ namespace MWRender void setHeight (float height); void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); + void setViewportBackground(Ogre::ColourValue colour); + void setUnderwater(bool underwater) {mIsUnderwater = underwater;} + + void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); + void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); private: Ogre::Camera* mParentCamera; Ogre::Camera* mCamera; Ogre::RenderTarget* mRenderTarget; Ogre::Plane mNearClipPlane; + Ogre::Plane mNearClipPlaneUnderwater; + bool mRenderActive; + bool mIsUnderwater; }; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 867829564..f31dca08c 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -124,8 +124,8 @@ void PlaneReflection::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::St { if (queueGroupId < 20 && mRenderActive) { - if (!mIsUnderwater) - mCamera->enableCustomNearClipPlane(mErrorPlane); + // this trick does not seem to work well for extreme angles + mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane); Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); } } @@ -159,6 +159,7 @@ void PlaneReflection::setHeight (float height) { mWaterPlane = Plane(Ogre::Vector3(0,1,0), height); mErrorPlane = Plane(Ogre::Vector3(0,1,0), height - 5); + mErrorPlaneUnderwater = Plane(Ogre::Vector3(0,-1,0), -height - 5); } void PlaneReflection::setActive (bool active) @@ -348,6 +349,8 @@ Water::updateUnderwater(bool underwater) if (mReflection) mReflection->setUnderwater (mIsUnderwater); + if (mRefraction) + mRefraction->setUnderwater (mIsUnderwater); updateVisible(); } @@ -377,6 +380,8 @@ void Water::setViewportBackground(const ColourValue& bg) { if (mReflection) mReflection->setViewportBackground(bg); + if (mRefraction) + mRefraction->setViewportBackground(bg); } void Water::updateVisible() diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index cf181674a..9aa18f008 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -89,6 +89,7 @@ namespace MWRender { SkyManager* mSky; Ogre::Plane mWaterPlane; Ogre::Plane mErrorPlane; + Ogre::Plane mErrorPlaneUnderwater; bool mRenderActive; }; From 6a49ea9b4fd5726f07c17db95c620a1059f78d1f Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 13 Feb 2013 18:39:36 +0100 Subject: [PATCH 29/61] Cleaning out some old bits --- apps/openmw/mwbase/inputmanager.hpp | 3 -- apps/openmw/mwgui/settingswindow.cpp | 6 +++ apps/openmw/mwinput/inputmanagerimp.cpp | 17 ++------- apps/openmw/mwinput/inputmanagerimp.hpp | 4 -- apps/openmw/mwrender/refraction.cpp | 6 +-- apps/openmw/mwrender/refraction.hpp | 1 - apps/openmw/mwrender/renderingmanager.cpp | 45 +++-------------------- apps/openmw/mwrender/renderingmanager.hpp | 2 - apps/openmw/mwrender/water.cpp | 2 - 9 files changed, 16 insertions(+), 70 deletions(-) diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index f69e1a152..8293cbfa7 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -39,9 +39,6 @@ namespace MWBase virtual int getNumActions() = 0; virtual void enableDetectingBindingMode (int action) = 0; virtual void resetToDefaultBindings() = 0; - - virtual void create () = 0; - virtual void destroy () = 0; }; } diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index eaea022c0..73f2f6c8a 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -370,6 +370,12 @@ namespace MWGui apply(); } } + else if (_sender == mVSyncButton) + { + Settings::Manager::setBool("vsync", "Video", newState); + MWBase::Environment::get().getWindowManager()-> + messageBox("VSync will be applied after a restart", std::vector()); + } else { if (_sender == mVSyncButton) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 00849503c..0934d8763 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -53,14 +53,6 @@ namespace MWInput , mUIYMultiplier (Settings::Manager::getFloat("ui y multiplier", "Input")) , mPreviewPOVDelay(0.f) , mTimeIdle(0.f) - { - create(); - - changeInputMode(false); - } - - - void InputManager::create() { Ogre::RenderWindow* window = mOgre.getWindow (); size_t windowHnd; @@ -139,9 +131,11 @@ namespace MWInput mControlSwitch["playermagic"] = true; mControlSwitch["playerviewswitch"] = true; mControlSwitch["vanitymode"] = true; + + changeInputMode(false); } - void InputManager::destroy() + InputManager::~InputManager() { mInputCtrl->save (mUserFile); @@ -152,11 +146,6 @@ namespace MWInput OIS::InputManager::destroyInputSystem(mInputManager); } - InputManager::~InputManager() - { - destroy(); - } - void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) { if (mDragDrop) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 7be35ee0b..3be669621 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -153,10 +153,6 @@ namespace MWInput std::map mControlSwitch; - public: - virtual void create(); - virtual void destroy(); - private: void adjustMouseRegion(int width, int height); diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index 05229da1d..e6b6e3baa 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -31,6 +31,7 @@ namespace MWRender vp->setShadowsEnabled(false); vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky); vp->setMaterialScheme("water_reflection"); + vp->setBackgroundColour (Ogre::ColourValue(0.0078, 0.0576, 0.150)); mRenderTarget->setAutoUpdated(true); mRenderTarget->addListener(this); } @@ -66,11 +67,6 @@ namespace MWRender mNearClipPlaneUnderwater = Ogre::Plane( Ogre::Vector3(0,1,0), height - 5); } - void Refraction::setViewportBackground (Ogre::ColourValue colour) - { - mRenderTarget->getViewport (0)->setBackgroundColour (colour); - } - void Refraction::renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation) { // We don't want the sky to get clipped by custom near clip plane (the water plane) diff --git a/apps/openmw/mwrender/refraction.hpp b/apps/openmw/mwrender/refraction.hpp index 6b3c487c1..de47d6e43 100644 --- a/apps/openmw/mwrender/refraction.hpp +++ b/apps/openmw/mwrender/refraction.hpp @@ -24,7 +24,6 @@ namespace MWRender void setHeight (float height); void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); - void setViewportBackground(Ogre::ColourValue colour); void setUnderwater(bool underwater) {mIsUnderwater = underwater;} void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index afbdbb06f..ce48284e0 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -46,8 +46,12 @@ namespace MWRender { RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) - : mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0), mPhysicsEngine(engine), - mRecreateWindowInNextFrame(false) + : mRendering(_rend) + , mObjects(mRendering) + , mActors(mRendering) + , mAmbientMode(0) + , mSunEnabled(0) + , mPhysicsEngine(engine) { // select best shader mode bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); @@ -324,33 +328,6 @@ RenderingManager::moveObjectToCell( void RenderingManager::update (float duration, bool paused) { - if (mRecreateWindowInNextFrame) - { - mRecreateWindowInNextFrame = false; - - mRendering.removeWindowEventListener(this); - mRendering.getWindow()->removeListener(this); - MWBase::Environment::get().getInputManager()->destroy(); - - OEngine::Render::WindowSettings windowSettings; - windowSettings.fullscreen = Settings::Manager::getBool("fullscreen", "Video"); - windowSettings.window_x = Settings::Manager::getInt("resolution x", "Video"); - windowSettings.window_y = Settings::Manager::getInt("resolution y", "Video"); - windowSettings.vsync = Settings::Manager::getBool("vsync", "Video"); - std::string aa = Settings::Manager::getString("antialiasing", "Video"); - windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0"; - mRendering.recreateWindow("OpenMW", windowSettings); - - MWBase::Environment::get().getInputManager()->create(); - mRendering.setWindowEventListener (this); - mRendering.getWindow()->addListener(this); - - // this is necessary, otherwise it would just endlessly wait for the last query and it would never return - delete mOcclusionQuery; - mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); - } - - Ogre::Vector3 orig, dest; mPlayer->setCameraDistance(); if (!mPlayer->getPosition(orig, dest)) { @@ -784,7 +761,6 @@ Compositors* RenderingManager::getCompositors() void RenderingManager::processChangedSettings(const Settings::CategorySettingVector& settings) { bool changeRes = false; - bool recreateWindow = false; bool rebuild = false; // rebuild static geometry (necessary after any material changes) for (Settings::CategorySettingVector::const_iterator it=settings.begin(); it != settings.end(); ++it) @@ -803,8 +779,6 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec || it->second == "resolution y" || it->second == "fullscreen")) changeRes = true; - else if (it->first == "Video" && it->second == "vsync") - recreateWindow = true; else if (it->second == "field of view" && it->first == "General") mRendering.setFov(Settings::Manager::getFloat("field of view", "General")); else if ((it->second == "texture filtering" && it->first == "General") @@ -876,13 +850,6 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } - if (recreateWindow) - { - mRecreateWindowInNextFrame = true; - // We can not do this now, because this might get triggered from the input listener - // and destroying/recreating the input system at that point would cause a crash - } - if (mWater) mWater->processChangedSettings(settings); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 670f3dc85..71ac742c2 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -260,8 +260,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList MWRender::Compositors* mCompositors; VideoPlayer* mVideoPlayer; - - bool mRecreateWindowInNextFrame; }; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index f31dca08c..3b8705ac5 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -380,8 +380,6 @@ void Water::setViewportBackground(const ColourValue& bg) { if (mReflection) mReflection->setViewportBackground(bg); - if (mRefraction) - mRefraction->setViewportBackground(bg); } void Water::updateVisible() From 492e0f2ccfbf9b069346e738f9145359a036335e Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 14 Feb 2013 19:45:07 +0100 Subject: [PATCH 30/61] Switched objects shaders to vertex lighting, to accomodate badly placed lights in morrowind. Fixed a very obvious land <-> water seam. --- files/materials/objects.shader | 83 +++++++++++++++++++++++++++++++--- files/materials/terrain.shader | 13 ++---- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 1e9c4a334..af596b779 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -22,6 +22,8 @@ #define HAS_VERTEXCOLOR @shPropertyBool(has_vertex_colour) +#define VERTEX_LIGHTING 1 + #ifdef SH_VERTEX_SHADER // ------------------------------------- VERTEX --------------------------------------- @@ -42,8 +44,24 @@ #if HAS_VERTEXCOLOR shColourInput(float4) +#if !VERTEX_LIGHTING shOutput(float4, colourPassthrough) #endif +#endif + +#if VERTEX_LIGHTING + shUniform(float, lightCount) @shAutoConstant(lightCount, light_count) + shUniform(float4, lightPosition[8]) @shAutoConstant(lightPosition, light_position_object_space_array, 8) + shUniform(float4, lightDiffuse[8]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, 8) + shUniform(float4, lightAttenuation[8]) @shAutoConstant(lightAttenuation, light_attenuation_array, 8) + shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) +#if !HAS_VERTEXCOLOUR + shUniform(float4, materialAmbient) @shAutoConstant(materialAmbient, surface_ambient_colour) +#endif + shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour) + shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour) + +#endif #if SHADOWS shOutput(float4, lightSpacePos0) @@ -58,6 +76,11 @@ @shEndForeach shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) #endif + +#if VERTEX_LIGHTING + shOutput(float3, lightResult) + shOutput(float3, directionalResult) +#endif SH_START_PROGRAM { shOutputPosition = shMatrixMult(wvp, shInputPosition); @@ -74,7 +97,7 @@ objSpacePositionPassthrough = shInputPosition.xyz; #endif -#if HAS_VERTEXCOLOR +#if HAS_VERTEXCOLOR && !VERTEX_LIGHTING colourPassthrough = colour; #endif @@ -86,6 +109,36 @@ @shForeach(3) lightSpacePos@shIterator = shMatrixMult(texViewProjMatrix@shIterator, wPos); @shEndForeach +#endif + + +#if VERTEX_LIGHTING + float3 lightDir; + float d; + + @shForeach(@shGlobalSettingString(num_lights)) + lightDir = lightPosition[@shIterator].xyz - (shInputPosition.xyz * lightPosition[@shIterator].w); + d = length(lightDir); + lightDir = normalize(lightDir); + + lightResult += materialDiffuse.xyz * lightDiffuse[@shIterator].xyz + * (1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d))) + * max(dot(normalize(normal.xyz), normalize(lightDir)), 0); + +#if @shIterator == 0 + directionalResult = lightResult; +#endif + + @shEndForeach + +#if HAS_VERTEXCOLOR + // ambient vertex colour tracking, FFP behaviour + lightResult += lightAmbient.xyz * colour.xyz + materialEmissive.xyz; + +#else + lightResult += lightAmbient.xyz * materialAmbient.xyz + materialEmissive.xyz; +#endif + #endif } @@ -115,25 +168,29 @@ #if LIGHTING shInput(float3, normalPassthrough) shInput(float3, objSpacePositionPassthrough) - shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) #if !HAS_VERTEXCOLOR shUniform(float4, materialAmbient) @shAutoConstant(materialAmbient, surface_ambient_colour) #endif shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour) shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour) + shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) +#if !VERTEX_LIGHTING + @shForeach(@shGlobalSettingString(num_lights)) shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position_object_space, @shIterator) shUniform(float4, lightAttenuation@shIterator) @shAutoConstant(lightAttenuation@shIterator, light_attenuation, @shIterator) shUniform(float4, lightDiffuse@shIterator) @shAutoConstant(lightDiffuse@shIterator, light_diffuse_colour, @shIterator) @shEndForeach #endif + +#endif #if FOG shUniform(float3, fogColour) @shAutoConstant(fogColour, fog_colour) shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params) #endif -#if HAS_VERTEXCOLOR +#if HAS_VERTEXCOLOR && !VERTEX_LIGHTING shInput(float4, colourPassthrough) #endif @@ -175,6 +232,11 @@ shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed) #endif +#if VERTEX_LIGHTING + shInput(float3, lightResult) + shInput(float3, directionalResult) +#endif + SH_START_PROGRAM { shOutputColour(0) = shSample(diffuseMap, UV); @@ -187,9 +249,9 @@ #if HAS_VERTEXCOLOR // ambient vertex colour tracking, FFP behaviour - float3 ambient = colourPassthrough.xyz * lightAmbient.xyz; + //float3 ambient = colourPassthrough.xyz * lightAmbient.xyz; #else - float3 ambient = materialAmbient.xyz * lightAmbient.xyz; + //float3 ambient = materialAmbient.xyz * lightAmbient.xyz; #endif // shadows only for the first (directional) light @@ -228,6 +290,7 @@ caustics = float3(1,1,1); #endif +#if !VERTEX_LIGHTING @shForeach(@shGlobalSettingString(num_lights)) @@ -253,9 +316,16 @@ @shEndForeach - shOutputColour(0).xyz *= (ambient + diffuse + materialEmissive.xyz); + lightResult = (ambient + diffuse + materialEmissive.xyz); #endif +#if SHADOWS + shOutputColour(0).xyz *= (lightResult - directionalResult * (1.0-shadow)); +#else + shOutputColour(0).xyz *= (lightResult); +#endif + +#endif // IF LIGHTING #if HAS_VERTEXCOLOR && !LIGHTING shOutputColour(0).xyz *= colourPassthrough.xyz; @@ -303,7 +373,6 @@ #if MRT shOutputColour(1) = float4(depthPassthrough / far,1,1,1); #endif - } #endif diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 9b891e1e8..d62bb4035 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -32,7 +32,7 @@ @shAllocatePassthrough(2, UV) #if LIGHTING -@shAllocatePassthrough(3, objSpacePosition) +@shAllocatePassthrough(3, worldPos) #endif #if SHADOWS @@ -101,7 +101,7 @@ @shPassthroughAssign(UV, uv0); #if LIGHTING - @shPassthroughAssign(objSpacePosition, shInputPosition.xyz); + @shPassthroughAssign(worldPos, worldPos.xyz); #endif #if SHADOWS @@ -162,7 +162,7 @@ #if LIGHTING shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) @shForeach(@shGlobalSettingString(terrain_num_lights)) - shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position_object_space, @shIterator) + shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position, @shIterator) shUniform(float4, lightAttenuation@shIterator) @shAutoConstant(lightAttenuation@shIterator, light_attenuation, @shIterator) shUniform(float4, lightDiffuse@shIterator) @shAutoConstant(lightDiffuse@shIterator, light_diffuse_colour, @shIterator) @shEndForeach @@ -213,7 +213,7 @@ float2 UV = @shPassthroughReceive(UV); #if LIGHTING - float3 objSpacePosition = @shPassthroughReceive(objSpacePosition); + float3 worldPos = @shPassthroughReceive(worldPos); float3 normal = shSample(normalMap, UV).rgb * 2 - 1; normal = normalize(normal); @@ -222,9 +222,6 @@ float3 caustics = float3(1,1,1); -#if (UNDERWATER) || (FOG) - float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePosition,1)).xyz; -#endif #if UNDERWATER @@ -306,7 +303,7 @@ @shForeach(@shGlobalSettingString(terrain_num_lights)) - lightDir = lightPosObjSpace@shIterator.xyz - (objSpacePosition.xyz * lightPosObjSpace@shIterator.w); + lightDir = lightPosObjSpace@shIterator.xyz - (worldPos.xyz * lightPosObjSpace@shIterator.w); d = length(lightDir); From 7604fb51b66a63a1f9b0256447982b1e65024b81 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 14 Feb 2013 23:17:21 +0100 Subject: [PATCH 31/61] CG no longer listed in the settings if the plugin isn't loaded. --- apps/openmw/mwgui/settingswindow.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 73f2f6c8a..54c2ef197 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -77,6 +78,17 @@ namespace { return (Ogre::Root::getSingleton ().getRenderSystem ()->getName ().find("OpenGL") != std::string::npos) ? "glsl" : "hlsl"; } + + bool cgAvailable () + { + Ogre::Root::PluginInstanceList list = Ogre::Root::getSingleton ().getInstalledPlugins (); + for (Ogre::Root::PluginInstanceList::const_iterator it = list.begin(); it != list.end(); ++it) + { + if ((*it)->getName() == "Cg Program Manager") + return true; + } + return false; + } } namespace MWGui @@ -428,7 +440,7 @@ namespace MWGui { val = hlslGlsl(); } - else + else if (cgAvailable ()) val = "cg"; static_cast(_sender)->setCaption(val); From 7ffcfa36220cd3a53e168e12abab8b0afdeb6b8d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 17 Feb 2013 16:23:55 +0100 Subject: [PATCH 32/61] Water and clouds no longer depend on timescale. --- apps/openmw/mwrender/renderingmanager.cpp | 2 -- apps/openmw/mwrender/sky.cpp | 2 +- apps/openmw/mwrender/water.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index ce48284e0..fe8f3e99b 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -353,8 +353,6 @@ void RenderingManager::update (float duration, bool paused) Ogre::ControllerManager::getSingleton().setTimeFactor(0.f); return; } - Ogre::ControllerManager::getSingleton().setTimeFactor( - MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); mPlayer->update(duration); diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index ce8d82632..be989724a 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -361,7 +361,7 @@ void SkyManager::update(float duration) mRootNode->setPosition(mCamera->getDerivedPosition()); // UV Scroll the clouds - mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f); + mCloudAnimationTimer += duration * mCloudSpeed; sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer", sh::makeProperty(new sh::FloatValue(mCloudAnimationTimer))); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 3b8705ac5..33159024e 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -399,7 +399,7 @@ void Water::update(float dt, Ogre::Vector3 player) mUnderwaterDome->setPosition (pos); */ - mWaterTimer += dt / 30.0 * MWBase::Environment::get().getWorld()->getTimeScaleFactor(); + mWaterTimer += dt; sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(mWaterTimer))); mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); From 791d16bbdb6ff95c1b4be0adfe04ab945601e4b4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 17 Feb 2013 18:12:38 +0100 Subject: [PATCH 33/61] Use infinite AAB for sky meshes to fix them from disappearing from underwater refraction, while still taking advantage of CPU culling for other meshes --- apps/openmw/mwrender/refraction.cpp | 4 ++++ apps/openmw/mwrender/sky.cpp | 6 ++++++ apps/openmw/mwrender/water.cpp | 4 +++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index e6b6e3baa..a924be7d7 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -41,6 +41,7 @@ namespace MWRender mRenderTarget->removeListener(this); Ogre::TextureManager::getSingleton().remove("WaterRefraction"); mParentCamera->getSceneManager()->destroyCamera(mCamera); + mParentCamera->getSceneManager()->removeRenderQueueListener(this); } void Refraction::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) @@ -53,6 +54,9 @@ namespace MWRender mCamera->setAspectRatio(mParentCamera->getAspectRatio()); mCamera->setFOVy(mParentCamera->getFOVy()); + // enable clip plane here to take advantage of CPU culling for overwater or underwater objects + mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane); + mRenderActive = true; } diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index be989724a..3b02ca412 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -280,6 +280,9 @@ void SkyManager::create() mSunGlare->setRenderQueue(RQG_SkiesLate); mSunGlare->setVisibilityFlags(RV_NoReflection); + Ogre::AxisAlignedBox aabInf; + aabInf.setInfinite (); + // Stars mAtmosphereNight = mRootNode->createChildSceneNode(); NifOgre::EntityList entities = NifOgre::NIFLoader::createEntities(mAtmosphereNight, NULL, "meshes\\sky_night_01.nif"); @@ -289,6 +292,7 @@ void SkyManager::create() night1_ent->setRenderQueueGroup(RQG_SkiesEarly+1); night1_ent->setVisibilityFlags(RV_Sky); night1_ent->setCastShadows(false); + night1_ent->getMesh()->_setBounds (aabInf); for (unsigned int j=0; jgetNumSubEntities(); ++j) { @@ -315,6 +319,7 @@ void SkyManager::create() atmosphere_ent->setRenderQueueGroup(RQG_SkiesEarly); atmosphere_ent->setVisibilityFlags(RV_Sky); atmosphere_ent->getSubEntity (0)->setMaterialName ("openmw_atmosphere"); + atmosphere_ent->getMesh()->_setBounds (aabInf); } @@ -328,6 +333,7 @@ void SkyManager::create() clouds_ent->setRenderQueueGroup(RQG_SkiesEarly+5); clouds_ent->getSubEntity(0)->setMaterialName ("openmw_clouds"); clouds_ent->setCastShadows(false); + clouds_ent->getMesh()->_setBounds (aabInf); } mCreated = true; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 33159024e..b006059a9 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -124,7 +124,6 @@ void PlaneReflection::renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::St { if (queueGroupId < 20 && mRenderActive) { - // this trick does not seem to work well for extreme angles mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane); Root::getSingleton().getRenderSystem()->_setProjectionMatrix(mCamera->getProjectionMatrixRS()); } @@ -145,6 +144,9 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) pos.y = (mWaterPlane).d*2 - pos.y; mSky->setSkyPosition(pos); mCamera->enableReflection(mWaterPlane); + + // enable clip plane here to take advantage of CPU culling for overwater or underwater objects + mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane); } void PlaneReflection::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) From 42883ec64bdfbabb32735757230ad79790bc4ed7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 18 Feb 2013 02:33:53 +0100 Subject: [PATCH 34/61] cleanup --- apps/openmw/engine.cpp | 1 - apps/openmw/mwrender/localmap.cpp | 2 - apps/openmw/mwrender/renderingmanager.cpp | 21 ------ apps/openmw/mwrender/renderingmanager.hpp | 2 - apps/openmw/mwrender/water.cpp | 20 ----- apps/openmw/mwrender/water.hpp | 2 - files/CMakeLists.txt | 7 -- files/gbuffer/gbuffer.compositor | 91 ----------------------- files/materials/atmosphere.shader | 9 --- files/materials/clouds.shader | 9 --- files/materials/moon.shader | 10 --- files/materials/objects.shader | 20 +---- files/materials/openmw.configuration | 2 - files/materials/quad.mat | 13 ---- files/materials/quad.shaderset | 16 ---- files/materials/quad2.shader | 23 ------ files/materials/stars.shader | 10 --- files/materials/sun.shader | 10 --- files/materials/terrain.shader | 12 +-- files/materials/water.shader | 13 +--- 20 files changed, 6 insertions(+), 287 deletions(-) delete mode 100644 files/gbuffer/gbuffer.compositor delete mode 100644 files/materials/quad2.shader diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 340e1d381..d65a5a78c 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -319,7 +319,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) addResourcesDirectory(mResDir / "mygui"); addResourcesDirectory(mResDir / "water"); - addResourcesDirectory(mResDir / "gbuffer"); addResourcesDirectory(mResDir / "shadows"); addZipResource(mResDir / "mygui" / "Obliviontt.zip"); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index e0b7d9a11..de36dcbbf 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -236,8 +236,6 @@ void LocalMap::render(const float x, const float y, vp->setShadowsEnabled(false); vp->setBackgroundColour(ColourValue(0, 0, 0)); vp->setVisibilityMask(RV_Map); - - // use fallback techniques without shadows and without mrt vp->setMaterialScheme("local_map"); rtt->update(); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index fe8f3e99b..6c6c47417 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -126,7 +126,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); - sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("fog", "true"); sh::Factory::getInstance ().setGlobalSetting ("lighting", "true"); sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects")); @@ -690,11 +689,6 @@ void RenderingManager::enableLights(bool sun) sunEnable(sun); } -const bool RenderingManager::useMRT() -{ - return Settings::Manager::getBool("shader", "Water"); -} - Shadows* RenderingManager::getShadows() { return mShadows; @@ -795,7 +789,6 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec else if (it->second == "shader" && it->first == "Water") { applyCompositors(); - sh::Factory::getInstance ().setGlobalSetting ("mrt_output", useMRT() ? "true" : "false"); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); rebuild = true; mRendering.getViewport ()->setClearEveryFrame (true); @@ -873,7 +866,6 @@ void RenderingManager::windowResized(Ogre::RenderWindow* rw) mRendering.adjustViewport(); mCompositors->recreate(); - mWater->assignTextures(); mVideoPlayer->setResolution (rw->getWidth(), rw->getHeight()); @@ -897,19 +889,6 @@ bool RenderingManager::waterShaderSupported() 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(); } void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned int &batches) diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 71ac742c2..e42c6e06f 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -104,8 +104,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void removeWater(); - static const bool useMRT(); - void preCellChange (MWWorld::CellStore* store); ///< this event is fired immediately before changing cell diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index b006059a9..f71431a27 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -93,7 +93,6 @@ PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* s vp->setOverlaysEnabled(false); vp->setBackgroundColour(ColourValue(0.8f, 0.9f, 1.0f)); vp->setShadowsEnabled(false); - // use fallback techniques without shadows and without mrt vp->setMaterialScheme("water_reflection"); mRenderTarget->addListener(this); mRenderTarget->setActive(true); @@ -232,8 +231,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel underwaterDome->setMaterialName("Underwater_Dome"); */ - assignTextures(); - setHeight(mTop); sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water"); @@ -362,22 +359,6 @@ Vector3 Water::getSceneNodeCoordinates(int gridX, int gridY) return Vector3(gridX * CELL_SIZE + (CELL_SIZE / 2), mTop, -gridY * CELL_SIZE - (CELL_SIZE / 2)); } -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); - sh::Factory::getInstance ().setTextureAlias ("WaterRefraction", colorTexture->getName()); - - TexturePtr depthTexture = compositor->getTextureInstance("mrt_output", 1); - sh::Factory::getInstance ().setTextureAlias ("SceneDepth", depthTexture->getName()); - */ - } -} - void Water::setViewportBackground(const ColourValue& bg) { if (mReflection) @@ -483,7 +464,6 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin applyRTT(); applyVisibilityMask(); mWater->setMaterial(mMaterial); - assignTextures(); } if (applyVisMask) applyVisibilityMask(); diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 9aa18f008..6100b7cfd 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -146,8 +146,6 @@ namespace MWRender { void toggle(); void update(float dt, Ogre::Vector3 player); - void assignTextures(); - void setViewportBackground(const Ogre::ColourValue& bg); void processChangedSettings(const Settings::CategorySettingVector& settings); diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index 65ebc31a2..c29d917b8 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -6,10 +6,6 @@ set(WATER_FILES circle.png ) -set(GBUFFER_FILES - gbuffer.compositor -) - set(MATERIAL_FILES atmosphere.shader atmosphere.shaderset @@ -22,7 +18,6 @@ set(MATERIAL_FILES objects.shader objects.shaderset openmw.configuration - quad2.shader quad.mat quad.shader quad.shaderset @@ -54,6 +49,4 @@ set(MATERIAL_FILES copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}") -copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/gbuffer "${OpenMW_BINARY_DIR}/resources/gbuffer/" "${GBUFFER_FILES}") - copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/materials "${OpenMW_BINARY_DIR}/resources/materials/" "${MATERIAL_FILES}") diff --git a/files/gbuffer/gbuffer.compositor b/files/gbuffer/gbuffer.compositor deleted file mode 100644 index 0a0675fa0..000000000 --- a/files/gbuffer/gbuffer.compositor +++ /dev/null @@ -1,91 +0,0 @@ -// Compositor that just controls output to the MRT textures -compositor gbuffer -{ - technique - { - // MRT output. Currently this is a color texture plus a depth texture - texture mrt_output target_width target_height PF_FLOAT16_RGBA PF_FLOAT16_RGBA chain_scope depth_pool 2 - - target mrt_output - { - input none - - pass clear - { - colour_value 0 0 0 1 - } - pass render_quad - { - // this makes sure the depth for background is set to 1 - material openmw_viewport_init - } - pass render_scene - { - // Renders everything except water - first_render_queue 0 - last_render_queue 50 - } - - } - - target_output - { - input none - - pass render_quad - { - material quad - input 0 mrt_output 0 - } - } - } -} - -// Finalizer compositor to render objects that we don't want in the MRT textures (ex. water) -// NB the water has to be rendered in a seperate compositor anyway, because it -// accesses the MRT textures which can't be done while they are still being rendered to. -compositor gbufferFinalizer -{ - technique - { - texture no_mrt_output target_width target_height PF_R8G8B8A8 depth_pool 2 no_fsaa - texture previousscene target_width target_height PF_R8G8B8A8 - - target previousscene - { - input previous - } - target no_mrt_output - { - input none - shadows off - pass clear - { - buffers colour - colour_value 0 0 0 0 - } - pass render_quad - { - material quad_noDepthWrite - input 0 previousscene - } - pass render_scene - { - first_render_queue 51 - last_render_queue 105 - } - } - target_output - { - input none - pass clear - { - } - pass render_quad - { - material quad_noDepthWrite - input 0 no_mrt_output - } - } - } -} diff --git a/files/materials/atmosphere.shader b/files/materials/atmosphere.shader index 16edc78c5..5d71d7c32 100644 --- a/files/materials/atmosphere.shader +++ b/files/materials/atmosphere.shader @@ -1,7 +1,5 @@ #include "core.h" -#define MRT @shGlobalSettingBool(mrt_output) - #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM @@ -19,18 +17,11 @@ SH_BEGIN_PROGRAM shInput(float, alphaFade) -#if MRT - shDeclareMrtOutput(1) -#endif shUniform(float4, atmosphereColour) @shSharedParameter(atmosphereColour) SH_START_PROGRAM { shOutputColour(0) = atmosphereColour * float4(1,1,1,alphaFade); - -#if MRT - shOutputColour(1) = float4(1,1,1,1); -#endif } #endif diff --git a/files/materials/clouds.shader b/files/materials/clouds.shader index 4b1868fb4..e60026d3b 100644 --- a/files/materials/clouds.shader +++ b/files/materials/clouds.shader @@ -1,7 +1,5 @@ #include "core.h" -#define MRT @shGlobalSettingBool(mrt_output) - #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM @@ -22,9 +20,6 @@ SH_BEGIN_PROGRAM shInput(float2, UV) shInput(float, alphaFade) -#if MRT - shDeclareMrtOutput(1) -#endif shSampler2D(diffuseMap1) shSampler2D(diffuseMap2) @@ -42,10 +37,6 @@ float4 albedo = shSample(diffuseMap1, scrolledUV) * (1-cloudBlendFactor) + shSample(diffuseMap2, scrolledUV) * cloudBlendFactor; shOutputColour(0) = float4(cloudColour, 1) * albedo * float4(1,1,1, cloudOpacity * alphaFade); - -#if MRT - shOutputColour(1) = float4(1,1,1,1); -#endif } #endif diff --git a/files/materials/moon.shader b/files/materials/moon.shader index 02f3d8001..231f60ba0 100644 --- a/files/materials/moon.shader +++ b/files/materials/moon.shader @@ -1,8 +1,5 @@ #include "core.h" -#define MRT @shGlobalSettingBool(mrt_output) - - #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM @@ -22,9 +19,6 @@ shSampler2D(diffuseMap) shSampler2D(alphaMap) shInput(float2, UV) -#if MRT - shDeclareMrtOutput(1) -#endif shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour) shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour) @@ -42,10 +36,6 @@ shOutputColour(0).rgb += (1-tex.a) * shOutputColour(0).a * atmosphereColour.rgb; //fill dark side of moon with atmosphereColour shOutputColour(0).rgb += (1-materialDiffuse.a) * atmosphereColour.rgb; //fade bump -#if MRT - shOutputColour(1) = float4(1,1,1,1); -#endif - } #endif diff --git a/files/materials/objects.shader b/files/materials/objects.shader index af596b779..3f5aa418f 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -2,7 +2,6 @@ #define FOG @shGlobalSettingBool(fog) -#define MRT @shPropertyNotBool(is_transparent) && @shGlobalSettingBool(mrt_output) #define LIGHTING @shGlobalSettingBool(lighting) #define SHADOWS_PSSM LIGHTING && @shGlobalSettingBool(shadows_pssm) @@ -12,7 +11,7 @@ #include "shadows.h" #endif -#if FOG || MRT || SHADOWS_PSSM +#if FOG || SHADOWS_PSSM #define NEED_DEPTH #endif @@ -51,9 +50,9 @@ #if VERTEX_LIGHTING shUniform(float, lightCount) @shAutoConstant(lightCount, light_count) - shUniform(float4, lightPosition[8]) @shAutoConstant(lightPosition, light_position_object_space_array, 8) - shUniform(float4, lightDiffuse[8]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, 8) - shUniform(float4, lightAttenuation[8]) @shAutoConstant(lightAttenuation, light_attenuation_array, 8) + shUniform(float4, lightPosition[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightPosition, light_position_object_space_array, @shGlobalSettingString(num_lights)) + shUniform(float4, lightDiffuse[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, @shGlobalSettingString(num_lights)) + shUniform(float4, lightAttenuation[@shGlobalSettingString(num_lights)]) @shAutoConstant(lightAttenuation, light_attenuation_array, @shGlobalSettingString(num_lights)) shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) #if !HAS_VERTEXCOLOUR shUniform(float4, materialAmbient) @shAutoConstant(materialAmbient, surface_ambient_colour) @@ -153,18 +152,11 @@ SH_BEGIN_PROGRAM shSampler2D(diffuseMap) shInput(float2, UV) -#if MRT - shDeclareMrtOutput(1) -#endif #ifdef NEED_DEPTH shInput(float, depthPassthrough) #endif -#if MRT - shUniform(float, far) @shAutoConstant(far, far_clip_distance) -#endif - #if LIGHTING shInput(float3, normalPassthrough) shInput(float3, objSpacePositionPassthrough) @@ -369,10 +361,6 @@ float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0; shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled); #endif - -#if MRT - shOutputColour(1) = float4(depthPassthrough / far,1,1,1); -#endif } #endif diff --git a/files/materials/openmw.configuration b/files/materials/openmw.configuration index db3693dd6..870c96728 100644 --- a/files/materials/openmw.configuration +++ b/files/materials/openmw.configuration @@ -3,13 +3,11 @@ configuration water_reflection fog false shadows false shadows_pssm false - mrt_output false } configuration local_map { fog false - mrt_output false shadows false shadows_pssm false simple_water true diff --git a/files/materials/quad.mat b/files/materials/quad.mat index a484d7f28..77a2c0c34 100644 --- a/files/materials/quad.mat +++ b/files/materials/quad.mat @@ -20,16 +20,3 @@ material quad_noDepthWrite parent quad depth_write off } - -material openmw_viewport_init -{ - pass - { - vertex_program viewport_init_vertex - fragment_program viewport_init_fragment - - depth_write off - depth_check off - scene_blend add - } -} diff --git a/files/materials/quad.shaderset b/files/materials/quad.shaderset index ee230a303..71fd82da4 100644 --- a/files/materials/quad.shaderset +++ b/files/materials/quad.shaderset @@ -13,19 +13,3 @@ shader_set quad_fragment profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1 profiles_hlsl ps_2_0 } - -shader_set viewport_init_vertex -{ - source quad2.shader - type vertex - profiles_cg vs_2_0 vp40 arbvp1 - profiles_hlsl vs_2_0 -} - -shader_set viewport_init_fragment -{ - source quad2.shader - type fragment - profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1 - profiles_hlsl ps_2_0 -} diff --git a/files/materials/quad2.shader b/files/materials/quad2.shader deleted file mode 100644 index e54d83ef4..000000000 --- a/files/materials/quad2.shader +++ /dev/null @@ -1,23 +0,0 @@ -#include "core.h" - -#ifdef SH_VERTEX_SHADER - - SH_BEGIN_PROGRAM - shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) - SH_START_PROGRAM - { - shOutputPosition = shMatrixMult(wvp, shInputPosition); - } - -#else - - SH_BEGIN_PROGRAM - shUniform(float3, viewportBackground) @shSharedParameter(viewportBackground) - shDeclareMrtOutput(1) - SH_START_PROGRAM - { - shOutputColour(0) = float4(viewportBackground, 1); - shOutputColour(1) = float4(1,1,1,1); - } - -#endif diff --git a/files/materials/stars.shader b/files/materials/stars.shader index 5a55d171e..fea007424 100644 --- a/files/materials/stars.shader +++ b/files/materials/stars.shader @@ -1,7 +1,5 @@ #include "core.h" -#define MRT @shGlobalSettingBool(mrt_output) - #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM @@ -22,9 +20,6 @@ #else SH_BEGIN_PROGRAM -#if MRT - shDeclareMrtOutput(1) -#endif shInput(float2, UV) shInput(float, fade) @@ -36,11 +31,6 @@ SH_START_PROGRAM { shOutputColour(0) = shSample(diffuseMap, UV) * float4(1,1,1, nightFade * fade); - - -#if MRT - shOutputColour(1) = float4(1,1,1,1); -#endif } #endif diff --git a/files/materials/sun.shader b/files/materials/sun.shader index 45cd2f24b..7954f417c 100644 --- a/files/materials/sun.shader +++ b/files/materials/sun.shader @@ -1,8 +1,5 @@ #include "core.h" -#define MRT @shGlobalSettingBool(mrt_output) - - #ifdef SH_VERTEX_SHADER SH_BEGIN_PROGRAM @@ -21,19 +18,12 @@ SH_BEGIN_PROGRAM shSampler2D(diffuseMap) shInput(float2, UV) -#if MRT - shDeclareMrtOutput(1) -#endif shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour) //shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour) SH_START_PROGRAM { shOutputColour(0) = float4(1,1,1,materialDiffuse.a) * shSample(diffuseMap, UV); - -#if MRT - shOutputColour(1) = float4(1,1,1,1); -#endif } #endif diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index d62bb4035..497463f8e 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -3,7 +3,6 @@ #define IS_FIRST_PASS 1 #define FOG @shGlobalSettingBool(fog) -#define MRT @shGlobalSettingBool(mrt_output) #define LIGHTING @shGlobalSettingBool(lighting) @@ -18,7 +17,7 @@ #define NUM_LAYERS @shPropertyString(num_layers) -#if MRT || FOG || SHADOWS_PSSM +#if FOG || SHADOWS_PSSM #define NEED_DEPTH 1 #endif @@ -152,11 +151,6 @@ #endif @shPassthroughFragmentInputs - -#if MRT - shDeclareMrtOutput(1) - shUniform(float, far) @shAutoConstant(far, far_clip_distance) -#endif #if LIGHTING @@ -370,10 +364,6 @@ float isUnderwater = (worldPos.y < waterLevel) ? 1.0 : 0.0; shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater); #endif - -#if MRT - shOutputColour(1) = float4(depth / far,1,1,1); -#endif } #endif diff --git a/files/materials/water.shader b/files/materials/water.shader index 400fbefb2..ac6b81240 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -5,11 +5,7 @@ #if SIMPLE_WATER - // --------------------------------------- SIMPLE WATER --------------------------------------------------- - - - #define MRT @shGlobalSettingBool(mrt_output) - + // --------------------------------------- SIMPLE WATER --------------------------------------------------- #ifdef SH_VERTEX_SHADER @@ -32,9 +28,6 @@ shSampler2D(animatedTexture) shInput(float2, UV) shInput(float, depth) -#if MRT - shDeclareMrtOutput(1) -#endif shUniform(float3, fogColor) @shAutoConstant(fogColor, fog_colour) shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params) @@ -47,10 +40,6 @@ float fogValue = shSaturate((depth - fogParams.y) * fogParams.w); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); - -#if MRT - shOutputColour(1) = float4(1,1,1,1); -#endif } #endif From 6cceb04adf93e3328c478127a635d13b3b605e93 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 19 Feb 2013 03:08:00 +0100 Subject: [PATCH 35/61] When a custom near clip plane is used, we need to fix up a second viewproj matrix manually to get proper depth values in the vertex shader. This fixes fog on reflections. --- apps/openmw/mwrender/refraction.cpp | 11 +++++++- apps/openmw/mwrender/renderingmanager.cpp | 2 ++ apps/openmw/mwrender/water.cpp | 6 +++++ files/materials/objects.shader | 33 +++++++++++++++++++++-- files/materials/openmw.configuration | 7 ++++- files/materials/terrain.shader | 24 +++++++++++++++++ 6 files changed, 79 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index a924be7d7..67fe9e340 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include "renderconst.hpp" namespace MWRender @@ -30,7 +32,7 @@ namespace MWRender vp->setOverlaysEnabled(false); vp->setShadowsEnabled(false); vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky); - vp->setMaterialScheme("water_reflection"); + vp->setMaterialScheme("water_refraction"); vp->setBackgroundColour (Ogre::ColourValue(0.0078, 0.0576, 0.150)); mRenderTarget->setAutoUpdated(true); mRenderTarget->addListener(this); @@ -54,6 +56,12 @@ namespace MWRender mCamera->setAspectRatio(mParentCamera->getAspectRatio()); mCamera->setFOVy(mParentCamera->getFOVy()); + // for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane. + // since all we are interested in is depth, we only need the third row of the matrix. + Ogre::Matrix4 projMatrix = mCamera->getProjectionMatrixWithRSDepth () * mCamera->getViewMatrix (); + sh::Vector4* row3 = new sh::Vector4(projMatrix[2][0], projMatrix[2][1], projMatrix[2][2], projMatrix[2][3]); + sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty (row3)); + // enable clip plane here to take advantage of CPU culling for overwater or underwater objects mCamera->enableCustomNearClipPlane(mIsUnderwater ? mNearClipPlaneUnderwater : mNearClipPlane); @@ -62,6 +70,7 @@ namespace MWRender void Refraction::postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) { + mCamera->disableCustomNearClipPlane (); mRenderActive = false; } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 6c6c47417..c4f2d99cb 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -140,6 +140,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setSharedParameter ("windDir_windSpeed", sh::makeProperty(new sh::Vector3(0.5, -0.8, 0.2))); sh::Factory::getInstance ().setSharedParameter ("waterSunFade_sunHeight", sh::makeProperty(new sh::Vector2(1, 0.6))); sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false"); + sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false"); + sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty (new sh::Vector4(0,0,0,0))); applyCompositors(); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index f71431a27..a76b0d1d3 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -144,6 +144,12 @@ void PlaneReflection::preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt) mSky->setSkyPosition(pos); mCamera->enableReflection(mWaterPlane); + // for depth calculation, we want the original viewproj matrix _without_ the custom near clip plane. + // since all we are interested in is depth, we only need the third row of the matrix. + Ogre::Matrix4 projMatrix = mCamera->getProjectionMatrixWithRSDepth () * mCamera->getViewMatrix (); + sh::Vector4* row3 = new sh::Vector4(projMatrix[2][0], projMatrix[2][1], projMatrix[2][2], projMatrix[2][3]); + sh::Factory::getInstance ().setSharedParameter ("vpRow2Fix", sh::makeProperty (row3)); + // enable clip plane here to take advantage of CPU culling for overwater or underwater objects mCamera->enableCustomNearClipPlane(mIsUnderwater ? mErrorPlaneUnderwater : mErrorPlane); } diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 3f5aa418f..fad8c1ac8 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -23,12 +23,21 @@ #define VERTEX_LIGHTING 1 +#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix) + #ifdef SH_VERTEX_SHADER // ------------------------------------- VERTEX --------------------------------------- SH_BEGIN_PROGRAM shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) + +#if VIEWPROJ_FIX + shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) + shUniform(float4, vpRow2Fix) @shSharedParameter(vpRow2Fix, vpRow2Fix) + shUniform(float4x4, vpMatrix) @shAutoConstant(vpMatrix, viewproj_matrix) +#endif + shVertexInput(float2, uv0) shOutput(float2, UV) shNormalInput(float4) @@ -65,7 +74,6 @@ #if SHADOWS shOutput(float4, lightSpacePos0) shUniform(float4x4, texViewProjMatrix0) @shAutoConstant(texViewProjMatrix0, texture_viewproj_matrix) - shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) #endif #if SHADOWS_PSSM @@ -73,7 +81,9 @@ shOutput(float4, lightSpacePos@shIterator) shUniform(float4x4, texViewProjMatrix@shIterator) @shAutoConstant(texViewProjMatrix@shIterator, texture_viewproj_matrix, @shIterator) @shEndForeach - shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) +#if !VIEWPROJ_FIX + shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) +#endif #endif #if VERTEX_LIGHTING @@ -89,9 +99,28 @@ #endif #ifdef NEED_DEPTH + + +#if VIEWPROJ_FIX + float4x4 vpFixed = vpMatrix; +#if !SH_GLSL + vpFixed[2] = vpRow2Fix; +#else + vpFixed[0][2] = vpRow2Fix.x; + vpFixed[1][2] = vpRow2Fix.y; + vpFixed[2][2] = vpRow2Fix.z; + vpFixed[3][2] = vpRow2Fix.w; +#endif + + float4x4 fixedWVP = shMatrixMult(vpFixed, worldMatrix); + + depthPassthrough = shMatrixMult(fixedWVP, shInputPosition).z; +#else depthPassthrough = shOutputPosition.z; #endif +#endif + #if LIGHTING objSpacePositionPassthrough = shInputPosition.xyz; #endif diff --git a/files/materials/openmw.configuration b/files/materials/openmw.configuration index 870c96728..21ac9416b 100644 --- a/files/materials/openmw.configuration +++ b/files/materials/openmw.configuration @@ -1,8 +1,13 @@ configuration water_reflection { - fog false shadows false shadows_pssm false + viewproj_fix true +} + +configuration water_refraction +{ + viewproj_fix true } configuration local_map diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 497463f8e..b7ee15e8d 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -23,6 +23,8 @@ #define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING +#define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix) + #if NEED_DEPTH @shAllocatePassthrough(1, depth) @@ -51,6 +53,10 @@ shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) shUniform(float4x4, viewProjMatrix) @shAutoConstant(viewProjMatrix, viewproj_matrix) +#if VIEWPROJ_FIX + shUniform(float4, vpRow2Fix) @shSharedParameter(vpRow2Fix, vpRow2Fix) +#endif + shUniform(float2, lodMorph) @shAutoConstant(lodMorph, custom, 1001) shVertexInput(float2, uv0) @@ -94,7 +100,25 @@ shOutputPosition = shMatrixMult(viewProjMatrix, worldPos); #if NEED_DEPTH +#if VIEWPROJ_FIX + float4x4 vpFixed = viewProjMatrix; +#if !SH_GLSL + vpFixed[2] = vpRow2Fix; +#else + vpFixed[0][2] = vpRow2Fix.x; + vpFixed[1][2] = vpRow2Fix.y; + vpFixed[2][2] = vpRow2Fix.z; + vpFixed[3][2] = vpRow2Fix.w; +#endif + + float4x4 fixedWVP = shMatrixMult(vpFixed, worldMatrix); + + float depth = shMatrixMult(fixedWVP, shInputPosition).z; + @shPassthroughAssign(depth, depth); +#else @shPassthroughAssign(depth, shOutputPosition.z); +#endif + #endif @shPassthroughAssign(UV, uv0); From 427152c518aa9c4ffef873772dcc254a9fb44204 Mon Sep 17 00:00:00 2001 From: scrawl Date: Tue, 19 Feb 2013 03:15:31 +0100 Subject: [PATCH 36/61] Disabled ripples until we can properly trigger them from the new character controller. --- apps/openmw/mwrender/water.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index a76b0d1d3..f0680f208 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -393,10 +393,9 @@ void Water::update(float dt, Ogre::Vector3 player) mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); - /// \todo player.y is the scene node position (which is above the head) and not the feet position //if (player.y <= mTop) { - mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); + //mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); } mSimulation->update(dt, Ogre::Vector2(player.x, player.z)); From 5b099393faa2c3cfe4cd4df051f93b452b8a36c7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 23 Feb 2013 04:43:51 +0100 Subject: [PATCH 37/61] Fix time factor --- apps/openmw/mwrender/refraction.cpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index 67fe9e340..64234cc57 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -33,7 +33,7 @@ namespace MWRender vp->setShadowsEnabled(false); vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky); vp->setMaterialScheme("water_refraction"); - vp->setBackgroundColour (Ogre::ColourValue(0.0078, 0.0576, 0.150)); + vp->setBackgroundColour (Ogre::ColourValue(0.180, 0.235, 0.22352)); mRenderTarget->setAutoUpdated(true); mRenderTarget->addListener(this); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c4f2d99cb..5baa8e7cc 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -349,9 +349,10 @@ void RenderingManager::update (float duration, bool paused) mRendering.update(duration); + Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f); + if(paused) { - Ogre::ControllerManager::getSingleton().setTimeFactor(0.f); return; } @@ -520,8 +521,8 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell) configureFog(mCell.mCell->mAmbi.mFogDensity, color); - if (mWater) - mWater->setViewportBackground (Ogre::ColourValue(0.8f, 0.9f, 1.0f)); + //if (mWater) + // mWater->setViewportBackground (Ogre::ColourValue(0.8f, 0.9f, 1.0f)); } void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) From 01102f9c73b9e28e1fc23928f5123cd2409831f7 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 23 Feb 2013 05:53:20 +0100 Subject: [PATCH 38/61] Don't emit if there wasn't enough movement --- apps/openmw/mwrender/renderingmanager.cpp | 2 +- apps/openmw/mwrender/ripplesimulation.cpp | 13 +++++++++++-- apps/openmw/mwrender/ripplesimulation.hpp | 4 +++- apps/openmw/mwrender/water.cpp | 6 ++++++ apps/openmw/mwrender/water.hpp | 2 ++ files/materials/watersim_heightmap.shader | 2 +- 6 files changed, 24 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 5baa8e7cc..c9f7603be 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -376,7 +376,7 @@ void RenderingManager::update (float duration, bool paused) float *fpos = data.getPosition().pos; // only for LocalMap::updatePlayer() - Ogre::Vector3 pos(fpos[0], -fpos[2], -fpos[1]); + Ogre::Vector3 pos(fpos[0], fpos[2], -fpos[1]); Ogre::SceneNode *node = data.getBaseNode(); Ogre::Quaternion orient = diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index 249397005..6c9264b60 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -21,7 +21,8 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) mRippleAreaLength(1000), mImpulseSize(20), mTexelOffset(0,0), - mFirstUpdate(true) + mFirstUpdate(true), + mLastPos(0,0) { Ogre::AxisAlignedBox aabInf; aabInf.setInfinite(); @@ -141,8 +142,16 @@ void RippleSimulation::update(float dt, Ogre::Vector2 position) new sh::Vector3(mRippleCenter.x + mTexelOffset.x, mRippleCenter.y + mTexelOffset.y, 0))); } -void RippleSimulation::addImpulse(Ogre::Vector2 position) +void RippleSimulation::addImpulse(Ogre::Vector2 position, float scale, float force) { + // don't emit if there wasn't enough movement + /// \todo this should be done somewhere else, otherwise multiple emitters cannot be supported + if ((position - mLastPos).length () <= 2) + return; + + mLastPos = position; + + /// \todo scale, force mImpulses.push(position); } diff --git a/apps/openmw/mwrender/ripplesimulation.hpp b/apps/openmw/mwrender/ripplesimulation.hpp index c792a3214..2f8cae24f 100644 --- a/apps/openmw/mwrender/ripplesimulation.hpp +++ b/apps/openmw/mwrender/ripplesimulation.hpp @@ -24,7 +24,7 @@ public: void update(float dt, Ogre::Vector2 position); - void addImpulse (Ogre::Vector2 position); + void addImpulse (Ogre::Vector2 position, float scale = 1.f, float force = 1.f); private: Ogre::RenderTexture* mRenderTargets[4]; @@ -34,6 +34,8 @@ private: float mRippleAreaLength; float mImpulseSize; + Ogre::Vector2 mLastPos; + bool mFirstUpdate; Ogre::Camera* mCamera; diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index f0680f208..33b6733ba 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -499,4 +499,10 @@ void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& co } } +void Water::addImpulse (Vector2 position, float scale, float force) +{ + if (mSimulation) + mSimulation->addImpulse (position, scale, force); +} + } // namespace diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index 6100b7cfd..eb7d98f5d 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -146,6 +146,8 @@ namespace MWRender { void toggle(); void update(float dt, Ogre::Vector3 player); + void addImpulse (Ogre::Vector2 position, float scale = 1.f, float force = 1.f); + void setViewportBackground(const Ogre::ColourValue& bg); void processChangedSettings(const Settings::CategorySettingVector& settings); diff --git a/files/materials/watersim_heightmap.shader b/files/materials/watersim_heightmap.shader index e19270d39..50d375efe 100644 --- a/files/materials/watersim_heightmap.shader +++ b/files/materials/watersim_heightmap.shader @@ -1,6 +1,6 @@ #include "core.h" -#define DAMPING 0.92 +#define DAMPING 0.95 #include "watersim_common.h" From 7046e7ae3def07d41d314bbbdb034c45a3e12f64 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 23 Feb 2013 09:02:05 +0100 Subject: [PATCH 39/61] Water fog fix --- files/materials/water.shader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/materials/water.shader b/files/materials/water.shader index ac6b81240..09788d45b 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -295,7 +295,7 @@ } else { - float fogValue = shSaturate((length(cameraPos.xyz-position.xyz) - fogParams.y) * fogParams.w); + float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); } From 0d6a3367d3693adc7d760b77ec1766c7ee532fbd Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 24 Feb 2013 10:28:50 +0100 Subject: [PATCH 40/61] Water shader no longer depends on object shaders being enabled --- apps/openmw/mwgui/settingswindow.cpp | 35 +++++++++++----------------- files/materials/water.mat | 4 +++- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 54c2ef197..ebeb42ab2 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -264,16 +264,9 @@ namespace MWGui mRefractionButton->setCaptionWithReplacing (Settings::Manager::getBool("refraction", "Water") ? "#{sOn}" : "#{sOff}"); - if (!MWRender::RenderingManager::waterShaderSupported()) - { - mWaterShaderButton->setEnabled(false); - mReflectObjectsButton->setEnabled(false); - mReflectActorsButton->setEnabled(false); - mReflectTerrainButton->setEnabled(false); - } - if (!Settings::Manager::getBool("shaders", "Objects")) { + mRefractionButton->setEnabled(false); mUnderwaterButton->setEnabled (false); mShadowsEnabledButton->setEnabled(false); } @@ -466,15 +459,15 @@ namespace MWGui { Settings::Manager::setBool("shaders", "Objects", false); - // water shader not supported with object shaders off - mWaterShaderButton->setCaptionWithReplacing("#{sOff}"); mUnderwaterButton->setCaptionWithReplacing("#{sOff}"); - mWaterShaderButton->setEnabled(false); - mReflectObjectsButton->setEnabled(false); - mReflectActorsButton->setEnabled(false); - mReflectTerrainButton->setEnabled(false); + mUnderwaterButton->setEnabled(false); - Settings::Manager::setBool("shader", "Water", false); + + // refraction needs shaders to display underwater fog + mRefractionButton->setCaptionWithReplacing("#{sOff}"); + mRefractionButton->setEnabled(false); + + Settings::Manager::setBool("refraction", "Water", false); Settings::Manager::setBool("underwater effect", "Water", false); // shadows not supported @@ -487,13 +480,11 @@ namespace MWGui Settings::Manager::setBool("shaders", "Objects", true); // re-enable - if (MWRender::RenderingManager::waterShaderSupported()) - { - mWaterShaderButton->setEnabled(true); - mReflectObjectsButton->setEnabled(true); - mReflectActorsButton->setEnabled(true); - mReflectTerrainButton->setEnabled(true); - } + mReflectObjectsButton->setEnabled(true); + mReflectActorsButton->setEnabled(true); + mReflectTerrainButton->setEnabled(true); + mRefractionButton->setEnabled(true); + mUnderwaterButton->setEnabled(true); mShadowsEnabledButton->setEnabled(true); } diff --git a/files/materials/water.mat b/files/materials/water.mat index 7546606fc..372058f0a 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -1,5 +1,7 @@ material Water { + allow_fixed_function false + pass { emissive 1.0 1.0 1.0 @@ -44,7 +46,7 @@ material Water tex_address_mode border tex_border_colour 0.5 0.5 1.0 } - + // for simple_water texture_unit animatedTexture { From 2e6c63d9cd255f45a7e6ec8b1c78bc7a652954e1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 24 Feb 2013 17:18:22 +0100 Subject: [PATCH 41/61] Disable specular on NIF's --- components/nifogre/ogre_nif_loader.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogre_nif_loader.cpp index c3bbc141b..27926b7c4 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogre_nif_loader.cpp @@ -575,9 +575,17 @@ static Ogre::String getMaterial(const Nif::NiTriShape *shape, const Ogre::String { ambient = m->data.ambient; diffuse = m->data.diffuse; - specular = m->data.specular; emissive = m->data.emissive; - glossiness = m->data.glossiness; + + + // Vanilla does not handle specular. TODO: Add an engine (or ESX file) configuration option + // to re-enable specular for future mods. Will also need to specify light specular colors somewhere. + // Also, not sure if glossiness value here is actually correct. OGRE expects 0-255 value, not sure what range this one is. + //glossiness = m->data.glossiness; + //specular = m->data.specular; + glossiness = 0; + specular = Ogre::Vector3(0,0,0); + alpha = m->data.alpha; } From 8aff033a0cc8bc7921e681b7bc2bf5d2a7b30599 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 25 Feb 2013 18:29:11 +0100 Subject: [PATCH 42/61] Atmosphere no longer does "real" alpha blending to blend with the horizon, this is in preparation for proper underwater viewport BG / fog --- apps/openmw/mwrender/sky.cpp | 8 ++++++++ apps/openmw/mwrender/sky.hpp | 1 + files/materials/atmosphere.shader | 3 ++- files/materials/sky.mat | 1 - 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index ed34833e6..cda9ce6dd 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -255,6 +255,7 @@ void SkyManager::create() sh::Factory::getInstance().setSharedParameter ("nightFade", sh::makeProperty(new sh::FloatValue(0))); sh::Factory::getInstance().setSharedParameter ("atmosphereColour", sh::makeProperty(new sh::Vector4(0,0,0,1))); + sh::Factory::getInstance().setSharedParameter ("horizonColour", sh::makeProperty(new sh::Vector4(0,0,0,1))); sh::Factory::getInstance().setTextureAlias ("cloud_texture_1", ""); sh::Factory::getInstance().setTextureAlias ("cloud_texture_2", ""); @@ -488,6 +489,13 @@ void SkyManager::setWeather(const MWWorld::WeatherResult& weather) weather.mSkyColor.r, weather.mSkyColor.g, weather.mSkyColor.b, weather.mSkyColor.a))); } + if (mFogColour != weather.mFogColor) + { + mFogColour = weather.mFogColor; + sh::Factory::getInstance().setSharedParameter ("horizonColour", sh::makeProperty(new sh::Vector4( + weather.mFogColor.r, weather.mFogColor.g, weather.mFogColor.b, weather.mFogColor.a))); + } + mCloudSpeed = weather.mCloudSpeed; if (weather.mNight && mStarsOpacity != weather.mNightFade) diff --git a/apps/openmw/mwrender/sky.hpp b/apps/openmw/mwrender/sky.hpp index 017eb4223..5a12b7ade 100644 --- a/apps/openmw/mwrender/sky.hpp +++ b/apps/openmw/mwrender/sky.hpp @@ -211,6 +211,7 @@ namespace MWRender float mStarsOpacity; Ogre::ColourValue mCloudColour; Ogre::ColourValue mSkyColour; + Ogre::ColourValue mFogColour; Ogre::Light* mLightning; diff --git a/files/materials/atmosphere.shader b/files/materials/atmosphere.shader index 5d71d7c32..eb05c3e18 100644 --- a/files/materials/atmosphere.shader +++ b/files/materials/atmosphere.shader @@ -18,10 +18,11 @@ SH_BEGIN_PROGRAM shInput(float, alphaFade) shUniform(float4, atmosphereColour) @shSharedParameter(atmosphereColour) + shUniform(float4, horizonColour) @shSharedParameter(horizonColour, horizonColour) SH_START_PROGRAM { - shOutputColour(0) = atmosphereColour * float4(1,1,1,alphaFade); + shOutputColour(0) = alphaFade * atmosphereColour + (1.f - alphaFade) * horizonColour; } #endif diff --git a/files/materials/sky.mat b/files/materials/sky.mat index 4af90a170..e50aa51d8 100644 --- a/files/materials/sky.mat +++ b/files/materials/sky.mat @@ -59,7 +59,6 @@ material openmw_atmosphere polygon_mode_overrideable off - scene_blend alpha_blend depth_write off } } From 9b0ac4e2998facb18cd7b055d8371893c5588f89 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 27 Feb 2013 09:20:42 +0100 Subject: [PATCH 43/61] NPCs / creatures can now emit ripples --- apps/openmw/mwrender/actors.cpp | 9 ++ apps/openmw/mwrender/actors.hpp | 7 +- apps/openmw/mwrender/localmap.cpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 121 ++++++++++++---------- apps/openmw/mwrender/renderingmanager.hpp | 9 ++ apps/openmw/mwrender/ripplesimulation.cpp | 91 +++++++++++----- apps/openmw/mwrender/ripplesimulation.hpp | 22 +++- apps/openmw/mwrender/water.cpp | 26 +++-- apps/openmw/mwrender/water.hpp | 12 ++- 9 files changed, 203 insertions(+), 96 deletions(-) diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index 83c07737c..644d3613b 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -6,6 +6,8 @@ #include "../mwworld/ptr.hpp" #include "../mwworld/class.hpp" +#include "../mwrender/renderingmanager.hpp" + #include "animation.hpp" #include "activatoranimation.hpp" #include "creatureanimation.hpp" @@ -72,6 +74,7 @@ void Actors::insertNPC(const MWWorld::Ptr& ptr, MWWorld::InventoryStore& inv) NpcAnimation* anim = new NpcAnimation(ptr, ptr.getRefData().getBaseNode(), inv, RV_Actors); delete mAllActors[ptr]; mAllActors[ptr] = anim; + mRendering->addWaterRippleEmitter (ptr); } void Actors::insertCreature (const MWWorld::Ptr& ptr) { @@ -79,6 +82,7 @@ void Actors::insertCreature (const MWWorld::Ptr& ptr) CreatureAnimation* anim = new CreatureAnimation(ptr); delete mAllActors[ptr]; mAllActors[ptr] = anim; + mRendering->addWaterRippleEmitter (ptr); } void Actors::insertActivator (const MWWorld::Ptr& ptr) { @@ -90,6 +94,8 @@ void Actors::insertActivator (const MWWorld::Ptr& ptr) bool Actors::deleteObject (const MWWorld::Ptr& ptr) { + mRendering->removeWaterRippleEmitter (ptr); + delete mAllActors[ptr]; mAllActors.erase(ptr); @@ -120,6 +126,7 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store) { if(iter->first.getCell() == store) { + mRendering->removeWaterRippleEmitter (iter->first); delete iter->second; mAllActors.erase(iter++); } @@ -172,6 +179,8 @@ void Actors::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur) anim->updatePtr(cur); mAllActors[cur] = anim; } + + mRendering->updateWaterRippleEmitterPtr (old, cur); } } diff --git a/apps/openmw/mwrender/actors.hpp b/apps/openmw/mwrender/actors.hpp index 75a18ba91..bba2d945c 100644 --- a/apps/openmw/mwrender/actors.hpp +++ b/apps/openmw/mwrender/actors.hpp @@ -13,6 +13,7 @@ namespace MWWorld namespace MWRender { class Animation; + class RenderingManager; class Actors { @@ -20,13 +21,17 @@ namespace MWRender typedef std::map PtrAnimationMap; OEngine::Render::OgreRenderer &mRend; + MWRender::RenderingManager* mRendering; Ogre::SceneNode* mRootNode; CellSceneNodeMap mCellSceneNodes; PtrAnimationMap mAllActors; public: - Actors(OEngine::Render::OgreRenderer& _rend): mRend(_rend) {} + Actors(OEngine::Render::OgreRenderer& _rend, MWRender::RenderingManager* rendering) + : mRend(_rend) + , mRendering(rendering) + {} ~Actors(); void setRootNode(Ogre::SceneNode* root); diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 8cf4ff123..8460d67aa 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -32,7 +32,7 @@ LocalMap::LocalMap(OEngine::Render::OgreRenderer* rend, MWRender::RenderingManag mLight = mRendering->getScene()->createLight(); mLight->setType (Ogre::Light::LT_DIRECTIONAL); - mLight->setDirection (Ogre::Vector3(0.3, -0.7, 0.3)); + mLight->setDirection (Ogre::Vector3(0.3, 0.3, -0.7)); mLight->setVisible (false); mLight->setDiffuseColour (ColourValue(0.7,0.7,0.7)); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 9ef705fde..943208a66 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -51,7 +51,7 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const const boost::filesystem::path& cacheDir, OEngine::Physic::PhysicEngine* engine) : mRendering(_rend) , mObjects(mRendering) - , mActors(mRendering) + , mActors(mRendering, this) , mAmbientMode(0) , mSunEnabled(0) , mPhysicsEngine(engine) @@ -136,7 +136,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); - sh::Factory::getInstance ().setSharedParameter ("viewportBackground", sh::makeProperty (new sh::Vector3(0,0,0))); sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty (new sh::FloatValue(0.0))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty(new sh::FloatValue(0))); sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(0))); @@ -173,6 +172,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mDebugging = new Debugging(mRootNode, engine); mLocalMap = new MWRender::LocalMap(&mRendering, this); + mWater = new MWRender::Water(mRendering.getCamera(), this); + setMenuTransparency(Settings::Manager::getFloat("menu transparency", "GUI")); } @@ -222,15 +223,12 @@ void RenderingManager::removeCell (MWWorld::Ptr::CellStore *store) void RenderingManager::removeWater () { - if(mWater){ - mWater->setActive(false); - } + mWater->setActive(false); } void RenderingManager::toggleWater() { - if (mWater) - mWater->toggle(); + mWater->toggle(); } void RenderingManager::cellAdded (MWWorld::Ptr::CellStore *store) @@ -321,6 +319,20 @@ RenderingManager::updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr & void RenderingManager::update (float duration, bool paused) { + MWBase::World *world = MWBase::Environment::get().getWorld(); + + // player position + MWWorld::RefData &data = + MWBase::Environment::get() + .getWorld() + ->getPlayer() + .getPlayer() + .getRefData(); + float *_playerPos = data.getPosition().pos; + Ogre::Vector3 playerPos(_playerPos[0], _playerPos[1], _playerPos[2]); + + Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); + Ogre::Vector3 orig, dest; mPlayer->setCameraDistance(); if (!mPlayer->getPosition(orig, dest)) { @@ -343,6 +355,17 @@ void RenderingManager::update (float duration, bool paused) Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f); + /* + if (world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam)) + { + mFogColour = Ogre::ColourValue(0.18039, 0.23137, 0.25490); + mFogStart = 0; + mFogEnd = 1500; + } + */ + + applyFog(); + if(paused) { return; @@ -358,41 +381,21 @@ void RenderingManager::update (float duration, bool paused) mSkyManager->setGlare(mOcclusionQuery->getSunVisibility()); - MWWorld::RefData &data = - MWBase::Environment::get() - .getWorld() - ->getPlayer() - .getPlayer() - .getRefData(); - - float *fpos = data.getPosition().pos; - - // only for LocalMap::updatePlayer() - Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]); - Ogre::SceneNode *node = data.getBaseNode(); //Ogre::Quaternion orient = //node->convertLocalToWorldOrientation(node->_getDerivedOrientation()); Ogre::Quaternion orient = node->_getDerivedOrientation(); - mLocalMap->updatePlayer(pos, orient); - - if (mWater) { - Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); + mLocalMap->updatePlayer(playerPos, orient); - MWBase::World *world = MWBase::Environment::get().getWorld(); + mWater->updateUnderwater( + world->isUnderwater( + world->getPlayer().getPlayer().getCell(), + cam) + ); - mWater->updateUnderwater( - world->isUnderwater( - world->getPlayer().getPlayer().getCell(), - cam) - ); - - // MW to ogre coordinates - orig = Ogre::Vector3(orig.x, orig.z, -orig.y); - mWater->update(duration, orig); - } + mWater->update(duration, playerPos); } void RenderingManager::preRenderTargetUpdate(const RenderTargetEvent &evt) @@ -416,10 +419,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store) || ((store->mCell->isExterior()) && !lands.search(store->mCell->getGridX(),store->mCell->getGridY()) )) // always use water, if the cell does not have land. { - if(mWater == 0) - mWater = new MWRender::Water(mRendering.getCamera(), this, store->mCell); - else - mWater->changeCell(store->mCell); + mWater->changeCell(store->mCell); mWater->setActive(true); } else @@ -428,8 +428,7 @@ void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store) void RenderingManager::setWaterHeight(const float height) { - if (mWater) - mWater->setHeight(height); + mWater->setHeight(height); } void RenderingManager::skyEnable () @@ -521,25 +520,27 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell) void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) { + mFogColour = colour; float max = Settings::Manager::getFloat("max viewing distance", "Viewing distance"); - float low = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance"); - float high = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance"); + mFogStart = max / (density) * Settings::Manager::getFloat("fog start factor", "Viewing distance"); + mFogEnd = max / (density) * Settings::Manager::getFloat("fog end factor", "Viewing distance"); - mRendering.getScene()->setFog (FOG_LINEAR, colour, 0, low, high); + mRendering.getCamera()->setFarClipDistance ( Settings::Manager::getFloat("max viewing distance", "Viewing distance") / density ); +} - mRendering.getCamera()->setFarClipDistance ( max / density ); - mRendering.getViewport()->setBackgroundColour (colour); +void RenderingManager::applyFog () +{ + mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd); - if (mWater) - mWater->setViewportBackground (colour); + mRendering.getViewport()->setBackgroundColour (mFogColour); - sh::Factory::getInstance ().setSharedParameter ("viewportBackground", - sh::makeProperty (new sh::Vector3(colour.r, colour.g, colour.b))); + mWater->setViewportBackground (mFogColour); + sh::Factory::getInstance ().setSharedParameter ("viewportBackground", + sh::makeProperty (new sh::Vector3(mFogColour.r, mFogColour.g, mFogColour.b))); } - void RenderingManager::setAmbientMode() { switch (mAmbientMode) @@ -826,8 +827,7 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec mRendering.getWindow()->setFullscreen(Settings::Manager::getBool("fullscreen", "Video"), x, y); } - if (mWater) - mWater->processChangedSettings(settings); + mWater->processChangedSettings(settings); if (rebuild) mObjects.rebuildStaticGeometry(); @@ -902,6 +902,8 @@ void RenderingManager::renderPlayer(const MWWorld::Ptr &ptr) MWWorld::Class::get(ptr).getInventoryStore(ptr), RV_Actors ); mPlayer->setAnimation(anim); + mWater->removeEmitter (ptr); + mWater->addEmitter (ptr); } void RenderingManager::getPlayerData(Ogre::Vector3 &eyepos, float &pitch, float &yaw) @@ -945,4 +947,19 @@ void RenderingManager::stopVideo() mVideoPlayer->stopVideo (); } +void RenderingManager::addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale, float force) +{ + mWater->addEmitter (ptr, scale, force); +} + +void RenderingManager::removeWaterRippleEmitter (const MWWorld::Ptr& ptr) +{ + mWater->removeEmitter (ptr); +} + +void RenderingManager::updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) +{ + mWater->updateEmitterPtr(old, ptr); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 5d79f80aa..02d796fdd 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -163,6 +163,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void skySetMoonColour (bool red); void configureAmbient(MWWorld::CellStore &mCell); + void addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f); + void removeWaterRippleEmitter (const MWWorld::Ptr& ptr); + void updateWaterRippleEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr); + void requestMap (MWWorld::CellStore* cell); ///< request the local map for a cell @@ -204,6 +208,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList sh::Factory* mFactory; void setAmbientMode(); + void applyFog(); void setMenuTransparency(float val); @@ -234,6 +239,10 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList Ogre::SceneNode *mRootNode; + Ogre::ColourValue mFogColour; + float mFogStart; + float mFogEnd; + OEngine::Physic::PhysicEngine* mPhysicsEngine; MWRender::Player *mPlayer; diff --git a/apps/openmw/mwrender/ripplesimulation.cpp b/apps/openmw/mwrender/ripplesimulation.cpp index 6c9264b60..47fbc8ddf 100644 --- a/apps/openmw/mwrender/ripplesimulation.cpp +++ b/apps/openmw/mwrender/ripplesimulation.cpp @@ -7,6 +7,11 @@ #include +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + namespace MWRender { @@ -21,8 +26,7 @@ RippleSimulation::RippleSimulation(Ogre::SceneManager* mainSceneManager) mRippleAreaLength(1000), mImpulseSize(20), mTexelOffset(0,0), - mFirstUpdate(true), - mLastPos(0,0) + mFirstUpdate(true) { Ogre::AxisAlignedBox aabInf; aabInf.setInfinite(); @@ -142,34 +146,39 @@ void RippleSimulation::update(float dt, Ogre::Vector2 position) new sh::Vector3(mRippleCenter.x + mTexelOffset.x, mRippleCenter.y + mTexelOffset.y, 0))); } -void RippleSimulation::addImpulse(Ogre::Vector2 position, float scale, float force) -{ - // don't emit if there wasn't enough movement - /// \todo this should be done somewhere else, otherwise multiple emitters cannot be supported - if ((position - mLastPos).length () <= 2) - return; - - mLastPos = position; - - /// \todo scale, force - mImpulses.push(position); -} - void RippleSimulation::addImpulses() { mRectangle->setVisible(false); mImpulse->setVisible(true); - while (mImpulses.size()) + /// \todo it should be more efficient to render all emitters at once + for (std::vector::iterator it=mEmitters.begin(); it !=mEmitters.end(); ++it) { - Ogre::Vector2 pos = mImpulses.front(); - pos -= mRippleCenter; - pos /= mRippleAreaLength; - float size = mImpulseSize / mRippleAreaLength; - mImpulse->setCorners(pos.x-size, pos.y+size, pos.x+size, pos.y-size, false); - mImpulses.pop(); - - mRenderTargets[1]->update(); + if (it->mPtr == MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer ()) + { + // fetch a new ptr (to handle cell change etc) + // for non-player actors this is done in updateObjectCell + it->mPtr = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer (); + } + float* _currentPos = it->mPtr.getRefData().getPosition().pos; + Ogre::Vector3 currentPos (_currentPos[0], _currentPos[1], _currentPos[2]); + + if ( (currentPos - it->mLastEmitPosition).length() > 2 + && MWBase::Environment::get().getWorld ()->isUnderwater (it->mPtr.getCell(), currentPos)) + { + it->mLastEmitPosition = currentPos; + + Ogre::Vector2 pos (currentPos.x, currentPos.y); + pos -= mRippleCenter; + pos /= mRippleAreaLength; + float size = mImpulseSize / mRippleAreaLength; + mImpulse->setCorners(pos.x-size, pos.y+size, pos.x+size, pos.y-size, false); + + // don't render if we are offscreen + if (pos.x - size >= 1.0 || pos.y+size <= -1.0 || pos.x+size <= -1.0 || pos.y-size >= 1.0) + continue; + mRenderTargets[1]->update(); + } } mImpulse->setVisible(false); @@ -216,5 +225,39 @@ void RippleSimulation::swapHeightMaps() mTextures[2] = tmp2; } +void RippleSimulation::addEmitter(const MWWorld::Ptr& ptr, float scale, float force) +{ + Emitter newEmitter; + newEmitter.mPtr = ptr; + newEmitter.mScale = scale; + newEmitter.mForce = force; + newEmitter.mLastEmitPosition = Ogre::Vector3(0,0,0); + mEmitters.push_back (newEmitter); +} + +void RippleSimulation::removeEmitter (const MWWorld::Ptr& ptr) +{ + for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it) + { + if (it->mPtr == ptr) + { + mEmitters.erase(it); + return; + } + } +} + +void RippleSimulation::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) +{ + for (std::vector::iterator it = mEmitters.begin(); it != mEmitters.end(); ++it) + { + if (it->mPtr == old) + { + it->mPtr = ptr; + return; + } + } +} + } diff --git a/apps/openmw/mwrender/ripplesimulation.hpp b/apps/openmw/mwrender/ripplesimulation.hpp index 2f8cae24f..7e7eebc1c 100644 --- a/apps/openmw/mwrender/ripplesimulation.hpp +++ b/apps/openmw/mwrender/ripplesimulation.hpp @@ -4,6 +4,9 @@ #include #include #include +#include + +#include "../mwworld/ptr.hpp" namespace Ogre { @@ -16,6 +19,14 @@ namespace Ogre namespace MWRender { +struct Emitter +{ + MWWorld::Ptr mPtr; + Ogre::Vector3 mLastEmitPosition; + float mScale; + float mForce; +}; + class RippleSimulation { public: @@ -24,9 +35,14 @@ public: void update(float dt, Ogre::Vector2 position); - void addImpulse (Ogre::Vector2 position, float scale = 1.f, float force = 1.f); + /// adds an emitter, position will be tracked automatically + void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f); + void removeEmitter (const MWWorld::Ptr& ptr); + void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr); private: + std::vector mEmitters; + Ogre::RenderTexture* mRenderTargets[4]; Ogre::TexturePtr mTextures[4]; @@ -34,8 +50,6 @@ private: float mRippleAreaLength; float mImpulseSize; - Ogre::Vector2 mLastPos; - bool mFirstUpdate; Ogre::Camera* mCamera; @@ -51,8 +65,6 @@ private: Ogre::Rectangle2D* mImpulse; - std::queue mImpulses; - void addImpulses(); void heightMapToNormalMap(); void waterSimulation(); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 7d6ca1a0d..d112e17b2 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -81,6 +81,7 @@ void CubeReflection::update () PlaneReflection::PlaneReflection(Ogre::SceneManager* sceneManager, SkyManager* sky) : Reflection(sceneManager) , mSky(sky) + , mRenderActive(false) { mCamera = mSceneMgr->createCamera ("PlaneReflectionCamera"); mSceneMgr->addRenderQueueListener(this); @@ -186,7 +187,7 @@ void PlaneReflection::setVisibilityMask (int flags) // -------------------------------------------------------------------------------------------------------------------------------- -Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell) : +Water::Water (Ogre::Camera *camera, RenderingManager* rend) : mCamera (camera), mSceneMgr (camera->getSceneManager()), mIsUnderwater(false), mVisibilityFlags(0), mActive(1), mToggled(1), @@ -202,7 +203,7 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel mMaterial = MaterialManager::getSingleton().getByName("Water"); - mTop = cell->mWater; + mTop = 0; mIsUnderwater = false; @@ -216,10 +217,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cel mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); - if(!(cell->mData.mFlags & cell->Interior)) - { - mWaterNode->setPosition(getSceneNodeCoordinates(cell->mData.mX, cell->mData.mY)); - } mWaterNode->attachObject(mWater); applyRTT(); @@ -397,7 +394,7 @@ 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)); + mSimulation->update(dt, Ogre::Vector2(player.x, player.y)); if (mReflection) mReflection->update(); @@ -499,10 +496,19 @@ void Water::createdConfiguration (sh::MaterialInstance* m, const std::string& co } } -void Water::addImpulse (Vector2 position, float scale, float force) +void Water::addEmitter (const MWWorld::Ptr& ptr, float scale, float force) +{ + mSimulation->addEmitter (ptr, scale, force); +} + +void Water::removeEmitter (const MWWorld::Ptr& ptr) +{ + mSimulation->removeEmitter (ptr); +} + +void Water::updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr) { - if (mSimulation) - mSimulation->addImpulse (position, scale, force); + mSimulation->updateEmitterPtr(old, ptr); } } // namespace diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index eb7d98f5d..ddf6ef7ab 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -11,9 +11,12 @@ #include #include +#include + + #include "renderconst.hpp" -#include +#include "../mwworld/ptr.hpp" namespace Ogre { @@ -138,7 +141,7 @@ namespace MWRender { RippleSimulation* mSimulation; public: - Water (Ogre::Camera *camera, RenderingManager* rend, const ESM::Cell* cell); + Water (Ogre::Camera *camera, RenderingManager* rend); ~Water(); void setActive(bool active); @@ -146,7 +149,10 @@ namespace MWRender { void toggle(); void update(float dt, Ogre::Vector3 player); - void addImpulse (Ogre::Vector2 position, float scale = 1.f, float force = 1.f); + /// adds an emitter, position will be tracked automatically using its scene node + void addEmitter (const MWWorld::Ptr& ptr, float scale = 1.f, float force = 1.f); + void removeEmitter (const MWWorld::Ptr& ptr); + void updateEmitterPtr (const MWWorld::Ptr& old, const MWWorld::Ptr& ptr); void setViewportBackground(const Ogre::ColourValue& bg); From 8966e88050a167e1bd6f40bcfd1376bdabc13ba4 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 27 Feb 2013 16:07:15 +0100 Subject: [PATCH 44/61] Fix shadows --- files/materials/objects.shader | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index d8498b831..88ca2d152 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -32,8 +32,11 @@ SH_BEGIN_PROGRAM shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) +#if (VIEWPROJ_FIX) || (SHADOWS) + shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) +#endif + #if VIEWPROJ_FIX - shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) shUniform(float4, vpRow2Fix) @shSharedParameter(vpRow2Fix, vpRow2Fix) shUniform(float4x4, vpMatrix) @shAutoConstant(vpMatrix, viewproj_matrix) #endif From e1957e4ee900b31eabb2f3fb9e90fb89d38d1958 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 2 Mar 2013 13:34:26 +0100 Subject: [PATCH 45/61] Potion effects should be hidden until discovered --- apps/openmw/mwclass/potion.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index c3a6df211..0ac78a2e4 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -20,6 +20,8 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" +#include "../mwmechanics/npcstats.hpp" + namespace MWClass { void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -138,6 +140,23 @@ namespace MWClass text += MWGui::ToolTips::getValueString(ref->mBase->mData.mValue, "#{sValue}"); info.effects = MWGui::Widgets::MWEffectList::effectListFromESM(&ref->mBase->mEffects); + + // hide effects the player doesnt know about + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayer ().getPlayer(); + MWMechanics::NpcStats& npcStats = MWWorld::Class::get(player).getNpcStats (player); + int alchemySkill = npcStats.getSkill (ESM::Skill::Alchemy).getBase(); + int i=0; + for (MWGui::Widgets::SpellEffectList::iterator it = info.effects.begin(); it != info.effects.end(); ++it) + { + /// \todo this code is duplicated from mwclass/ingredient, put it in a helper function + it->mKnown = ( (i == 0 && alchemySkill >= 15) + || (i == 1 && alchemySkill >= 30) + || (i == 2 && alchemySkill >= 45) + || (i == 3 && alchemySkill >= 60)); + + ++i; + } + info.isPotion = true; if (MWBase::Environment::get().getWindowManager()->getFullHelp()) { From 6de6d9ff6eabc79236b206a09c710b85ec4135f9 Mon Sep 17 00:00:00 2001 From: Nathan Jeffords Date: Sat, 5 Jan 2013 13:03:05 -0800 Subject: [PATCH 46/61] Factored a NIFStream class out of the NIFFile class. Split NIFFile into two parts, NIFFile which is cached and is a container for a parsed NIF, and NIFStream which is a class specialized for parsing NIFs. This required a semi-sweeping change to make all record classes accept a NIFStream instead of a NIFFile as an agurment to their read functions. --- components/nif/controlled.hpp | 14 +-- components/nif/controller.hpp | 18 ++-- components/nif/data.hpp | 30 +++--- components/nif/effect.hpp | 6 +- components/nif/extra.hpp | 8 +- components/nif/nif_file.cpp | 15 ++- components/nif/nif_file.hpp | 154 ++---------------------------- components/nif/nif_stream.hpp | 175 ++++++++++++++++++++++++++++++++++ components/nif/node.hpp | 14 +-- components/nif/property.hpp | 16 ++-- components/nif/record.hpp | 3 +- components/nif/record_ptr.hpp | 4 +- 12 files changed, 249 insertions(+), 208 deletions(-) create mode 100644 components/nif/nif_stream.hpp diff --git a/components/nif/controlled.hpp b/components/nif/controlled.hpp index b9d84b58a..dac541b2d 100644 --- a/components/nif/controlled.hpp +++ b/components/nif/controlled.hpp @@ -36,7 +36,7 @@ class Controlled : public Extra public: ControllerPtr controller; - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); controller.read(nif); @@ -55,7 +55,7 @@ class Named : public Controlled public: std::string name; - void read(NIFFile *nif) + void read(NIFStream *nif) { name = nif->getString(); Controlled::read(nif); @@ -66,7 +66,7 @@ typedef Named NiSequenceStreamHelper; class NiParticleGrowFade : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); @@ -80,7 +80,7 @@ class NiParticleColorModifier : public Controlled public: NiColorDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); data.read(nif); @@ -96,7 +96,7 @@ public: class NiGravity : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); @@ -109,7 +109,7 @@ public: class NiPlanarCollider : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); @@ -121,7 +121,7 @@ public: class NiParticleRotation : public Controlled { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controlled::read(nif); diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index cbc19cd8f..4f7ef3c0f 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -40,7 +40,7 @@ public: float timeStart, timeStop; ControlledPtr target; - void read(NIFFile *nif) + void read(NIFStream *nif) { next.read(nif); @@ -65,7 +65,7 @@ public: class NiBSPArrayController : public Controller { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); @@ -82,7 +82,7 @@ class NiMaterialColorController : public Controller public: NiPosDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -101,7 +101,7 @@ public: NiPosDataPtr posData; NiFloatDataPtr floatData; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); @@ -129,7 +129,7 @@ class NiUVController : public Controller public: NiUVDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); @@ -149,7 +149,7 @@ class NiKeyframeController : public Controller public: NiKeyframeDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -167,7 +167,7 @@ class NiAlphaController : public Controller public: NiFloatDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -185,7 +185,7 @@ class NiGeomMorpherController : public Controller public: NiMorphDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); @@ -204,7 +204,7 @@ class NiVisController : public Controller public: NiVisDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Controller::read(nif); data.read(nif); diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 46b58da8f..5f18800f0 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -65,7 +65,7 @@ public: */ int alpha; - void read(NIFFile *nif) + void read(NIFStream *nif) { Named::read(nif); @@ -102,7 +102,7 @@ public: Ogre::Vector3 center; float radius; - void read(NIFFile *nif) + void read(NIFStream *nif) { int verts = nif->getUShort(); @@ -138,7 +138,7 @@ public: // Triangles, three vertex indices per triangle std::vector triangles; - void read(NIFFile *nif) + void read(NIFStream *nif) { ShapeData::read(nif); @@ -167,7 +167,7 @@ class NiAutoNormalParticlesData : public ShapeData public: int activeCount; - void read(NIFFile *nif) + void read(NIFStream *nif) { ShapeData::read(nif); @@ -189,7 +189,7 @@ public: class NiRotatingParticlesData : public NiAutoNormalParticlesData { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { NiAutoNormalParticlesData::read(nif); @@ -208,7 +208,7 @@ class NiPosData : public Record public: Vector3KeyList mKeyList; - void read(NIFFile *nif) + void read(NIFStream *nif) { mKeyList.read(nif); } @@ -219,7 +219,7 @@ class NiUVData : public Record public: FloatKeyList mKeyList[4]; - void read(NIFFile *nif) + void read(NIFStream *nif) { for(int i = 0;i < 4;i++) mKeyList[i].read(nif); @@ -231,7 +231,7 @@ class NiFloatData : public Record public: FloatKeyList mKeyList; - void read(NIFFile *nif) + void read(NIFStream *nif) { mKeyList.read(nif); } @@ -243,7 +243,7 @@ public: unsigned int rmask, gmask, bmask, amask; int bpp, mips; - void read(NIFFile *nif) + void read(NIFStream *nif) { nif->getInt(); // always 0 or 1 @@ -281,7 +281,7 @@ class NiColorData : public Record public: Vector4KeyList mKeyList; - void read(NIFFile *nif) + void read(NIFStream *nif) { mKeyList.read(nif); } @@ -295,7 +295,7 @@ public: char isSet; }; - void read(NIFFile *nif) + void read(NIFStream *nif) { int count = nif->getInt(); @@ -311,7 +311,7 @@ public: NodePtr root; NodeList bones; - void read(NIFFile *nif) + void read(NIFStream *nif) { data.read(nif); root.read(nif); @@ -347,7 +347,7 @@ public: BoneTrafo trafo; std::vector bones; - void read(NIFFile *nif) + void read(NIFStream *nif) { trafo.rotation = nif->getMatrix3(); trafo.trans = nif->getVector3(); @@ -385,7 +385,7 @@ struct NiMorphData : public Record }; std::vector mMorphs; - void read(NIFFile *nif) + void read(NIFStream *nif) { int morphCount = nif->getInt(); int vertCount = nif->getInt(); @@ -410,7 +410,7 @@ struct NiKeyframeData : public Record Vector3KeyList mTranslations; FloatKeyList mScales; - void read(NIFFile *nif) + void read(NIFStream *nif) { mRotations.read(nif); mTranslations.read(nif); diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index 850415dad..b07a39303 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -42,7 +42,7 @@ struct NiLight : Effect Ogre::Vector3 diffuse; Ogre::Vector3 specular; - void read(NIFFile *nif) + void read(NIFStream *nif) { dimmer = nif->getFloat(); ambient = nif->getVector3(); @@ -52,7 +52,7 @@ struct NiLight : Effect }; SLight light; - void read(NIFFile *nif) + void read(NIFStream *nif) { Effect::read(nif); @@ -66,7 +66,7 @@ struct NiTextureEffect : Effect { NiSourceTexturePtr texture; - void read(NIFFile *nif) + void read(NIFStream *nif) { Effect::read(nif); diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index 35781dbf5..b5335f987 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -40,14 +40,14 @@ class Extra : public Record public: ExtraPtr extra; - void read(NIFFile *nif) { extra.read(nif); } + void read(NIFStream *nif) { extra.read(nif); } void post(NIFFile *nif) { extra.post(nif); } }; class NiVertWeightsExtraData : public Extra { public: - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); @@ -70,7 +70,7 @@ public: }; std::vector list; - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); @@ -95,7 +95,7 @@ public: */ std::string string; - void read(NIFFile *nif) + void read(NIFStream *nif) { Extra::read(nif); diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index 6e806e7ec..f3faf563c 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -174,10 +174,7 @@ NIFFile::ptr NIFFile::create (const std::string &name) { return LoadedCache::cre NIFFile::NIFFile(const std::string &name, psudo_private_modifier) : filename(name) { - inp = Ogre::ResourceGroupManager::getSingleton().openResource(name); parse(); - // Make sure to close the file after it was loaded into memory - inp.setNull(); } NIFFile::~NIFFile() @@ -195,18 +192,20 @@ NIFFile::~NIFFile() void NIFFile::parse() { + NIFStream nif (this, Ogre::ResourceGroupManager::getSingleton().openResource(filename)); + // Check the header string - std::string head = getString(40); + std::string head = nif.getString(40); if(head.compare(0, 22, "NetImmerse File Format") != 0) fail("Invalid NIF header"); // Get BCD version - ver = getInt(); + ver = nif.getInt(); if(ver != VER_MW) fail("Unsupported NIF version"); // Number of records - size_t recNum = getInt(); + size_t recNum = nif.getInt(); records.resize(recNum); /* The format for 10.0.1.0 seems to be a bit different. After the @@ -222,7 +221,7 @@ void NIFFile::parse() { Record *r = NULL; - std::string rec = getString(); + std::string rec = nif.getString(); /* These are all the record types we know how to read. @@ -312,7 +311,7 @@ void NIFFile::parse() r->recName = rec; r->recIndex = i; records[i] = r; - r->read(this); + r->read(&nif); // Discard tranformations for the root node, otherwise some meshes // occasionally get wrong orientation. Only for NiNode-s for now, but diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 5e9694f4b..a406de4a0 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -46,6 +46,7 @@ #include "record.hpp" #include "nif_types.hpp" +#include "nif_stream.hpp" namespace Nif { @@ -59,9 +60,6 @@ class NIFFile /// Nif file version int ver; - /// Input stream - Ogre::DataStreamPtr inp; - /// File name, used for error messages std::string filename; @@ -71,33 +69,6 @@ class NIFFile /// Parse the file void parse(); - uint8_t read_byte() - { - uint8_t byte; - if(inp->read(&byte, 1) != 1) return 0; - return byte; - } - uint16_t read_le16() - { - uint8_t buffer[2]; - if(inp->read(buffer, 2) != 2) return 0; - return buffer[0] | (buffer[1]<<8); - } - uint32_t read_le32() - { - uint8_t buffer[4]; - if(inp->read(buffer, 4) != 4) return 0; - return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); - } - float read_le32f() - { - union { - uint32_t i; - float f; - } u = { read_le32() }; - return u.f; - } - class LoadedCache; friend class LoadedCache; @@ -117,8 +88,8 @@ public: void warn(const std::string &msg) { - std::cerr<< "NIFFile Warning: "< ptr; @@ -147,111 +118,6 @@ public: /// Number of records size_t numRecords() { return records.size(); } - - /************************************************* - Parser functions - ****************************************************/ - - void skip(size_t size) { inp->skip(size); } - - char getChar() { return read_byte(); } - short getShort() { return read_le16(); } - unsigned short getUShort() { return read_le16(); } - int getInt() { return read_le32(); } - unsigned int getUInt() { return read_le32(); } - float getFloat() { return read_le32f(); } - Ogre::Vector2 getVector2() - { - float a[2]; - for(size_t i = 0;i < 2;i++) - a[i] = getFloat(); - return Ogre::Vector2(a); - } - Ogre::Vector3 getVector3() - { - float a[3]; - for(size_t i = 0;i < 3;i++) - a[i] = getFloat(); - return Ogre::Vector3(a); - } - Ogre::Vector4 getVector4() - { - float a[4]; - for(size_t i = 0;i < 4;i++) - a[i] = getFloat(); - return Ogre::Vector4(a); - } - Ogre::Matrix3 getMatrix3() - { - Ogre::Real a[3][3]; - for(size_t i = 0;i < 3;i++) - { - for(size_t j = 0;j < 3;j++) - a[i][j] = Ogre::Real(getFloat()); - } - return Ogre::Matrix3(a); - } - Ogre::Quaternion getQuaternion() - { - float a[4]; - for(size_t i = 0;i < 4;i++) - a[i] = getFloat(); - return Ogre::Quaternion(a); - } - Transformation getTrafo() - { - Transformation t; - t.pos = getVector3(); - t.rotation = getMatrix3(); - t.scale = getFloat(); - return t; - } - - std::string getString(size_t length) - { - std::vector str (length+1, 0); - - if(inp->read(&str[0], length) != length) - throw std::runtime_error ("string length in NIF file does not match"); - - return &str[0]; - } - std::string getString() - { - size_t size = read_le32(); - return getString(size); - } - - void getShorts(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getShort(); - } - void getFloats(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getFloat(); - } - void getVector2s(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector2(); - } - void getVector3s(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector3(); - } - void getVector4s(std::vector &vec, size_t size) - { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector4(); - } }; @@ -270,7 +136,7 @@ typedef KeyT Vector3Key; typedef KeyT Vector4Key; typedef KeyT QuaternionKey; -template +template struct KeyListT { typedef std::vector< KeyT > VecType; @@ -281,7 +147,7 @@ struct KeyListT { int mInterpolationType; VecType mKeys; - void read(NIFFile *nif, bool force=false) + void read(NIFStream *nif, bool force=false) { size_t count = nif->getInt(); if(count == 0 && !force) @@ -322,13 +188,13 @@ struct KeyListT { } } else - nif->warn("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); + nif->file->warn("Unhandled interpolation type: "+Ogre::StringConverter::toString(mInterpolationType)); } }; -typedef KeyListT FloatKeyList; -typedef KeyListT Vector3KeyList; -typedef KeyListT Vector4KeyList; -typedef KeyListT QuaternionKeyList; +typedef KeyListT FloatKeyList; +typedef KeyListT Vector3KeyList; +typedef KeyListT Vector4KeyList; +typedef KeyListT QuaternionKeyList; } // Namespace #endif diff --git a/components/nif/nif_stream.hpp b/components/nif/nif_stream.hpp new file mode 100644 index 000000000..8fb98f3d6 --- /dev/null +++ b/components/nif/nif_stream.hpp @@ -0,0 +1,175 @@ +#ifndef _NIF_STREAM_HPP_ +#define _NIF_STREAM_HPP_ + +namespace Nif +{ + +class NIFFile; + +class NIFStream { + + /// Input stream + Ogre::DataStreamPtr inp; + + uint8_t read_byte() + { + uint8_t byte; + if(inp->read(&byte, 1) != 1) return 0; + return byte; + } + uint16_t read_le16() + { + uint8_t buffer[2]; + if(inp->read(buffer, 2) != 2) return 0; + return buffer[0] | (buffer[1]<<8); + } + uint32_t read_le32() + { + uint8_t buffer[4]; + if(inp->read(buffer, 4) != 4) return 0; + return buffer[0] | (buffer[1]<<8) | (buffer[2]<<16) | (buffer[3]<<24); + } + float read_le32f() + { + union { + uint32_t i; + float f; + } u = { read_le32() }; + return u.f; + } + +public: + + NIFFile * const file; + + NIFStream (NIFFile * file, Ogre::DataStreamPtr inp): file (file), inp (inp) {} + + /************************************************* + Parser functions + ****************************************************/ + + template + struct GetHandler + { + typedef T (NIFStream::*fn_t)(); + + static const fn_t sValue; // this is specialized per supported type in the .cpp file + + static T read (NIFStream* nif) + { + return (nif->*sValue) (); + } + }; + + template + void read (NIFStream* nif, T & Value) + { + Value = GetHandler ::read (nif); + } + + void skip(size_t size) { inp->skip(size); } + void read (void * data, size_t size) { inp->read (data, size); } + + char getChar() { return read_byte(); } + short getShort() { return read_le16(); } + unsigned short getUShort() { return read_le16(); } + int getInt() { return read_le32(); } + int getUInt() { return read_le32(); } + float getFloat() { return read_le32f(); } + Ogre::Vector2 getVector2() + { + float a[2]; + for(size_t i = 0;i < 2;i++) + a[i] = getFloat(); + return Ogre::Vector2(a); + } + Ogre::Vector3 getVector3() + { + float a[3]; + for(size_t i = 0;i < 3;i++) + a[i] = getFloat(); + return Ogre::Vector3(a); + } + Ogre::Vector4 getVector4() + { + float a[4]; + for(size_t i = 0;i < 4;i++) + a[i] = getFloat(); + return Ogre::Vector4(a); + } + Ogre::Matrix3 getMatrix3() + { + Ogre::Real a[3][3]; + for(size_t i = 0;i < 3;i++) + { + for(size_t j = 0;j < 3;j++) + a[i][j] = Ogre::Real(getFloat()); + } + return Ogre::Matrix3(a); + } + Ogre::Quaternion getQuaternion() + { + float a[4]; + for(size_t i = 0;i < 4;i++) + a[i] = getFloat(); + return Ogre::Quaternion(a); + } + Transformation getTrafo() + { + Transformation t; + t.pos = getVector3(); + t.rotation = getMatrix3(); + t.scale = getFloat(); + return t; + } + + std::string getString(size_t length) + { + std::vector str (length+1, 0); + + if(inp->read(&str[0], length) != length) + throw std::runtime_error ("string length in NIF file does not match"); + + return &str[0]; + } + std::string getString() + { + size_t size = read_le32(); + return getString(size); + } + + void getShorts(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getShort(); + } + void getFloats(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getFloat(); + } + void getVector2s(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector2(); + } + void getVector3s(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector3(); + } + void getVector4s(std::vector &vec, size_t size) + { + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector4(); + } +}; + +} + +#endif diff --git a/components/nif/node.hpp b/components/nif/node.hpp index 07e7868cc..e08703756 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -54,7 +54,7 @@ public: Ogre::Matrix3 boundRot; Ogre::Vector3 boundXYZ; // Box size - void read(NIFFile *nif) + void read(NIFStream *nif) { Named::read(nif); @@ -128,7 +128,7 @@ struct NiNode : Node 0x20, 0x40, 0x80 unknown */ - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); children.read(nif); @@ -162,7 +162,7 @@ struct NiTriShape : Node NiTriShapeDataPtr data; NiSkinInstancePtr skin; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); data.read(nif); @@ -190,7 +190,7 @@ struct NiCamera : Node // Level of detail modifier float LOD; - void read(NIFFile *nif) + void read(NIFStream *nif) { left = nif->getFloat(); right = nif->getFloat(); @@ -209,7 +209,7 @@ struct NiCamera : Node }; Camera cam; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); @@ -224,7 +224,7 @@ struct NiAutoNormalParticles : Node { NiAutoNormalParticlesDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); data.read(nif); @@ -242,7 +242,7 @@ struct NiRotatingParticles : Node { NiRotatingParticlesDataPtr data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Node::read(nif); data.read(nif); diff --git a/components/nif/property.hpp b/components/nif/property.hpp index 046fb0465..cdf97986c 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -35,7 +35,7 @@ public: // The meaning of these depends on the actual property type. int flags; - void read(NIFFile *nif) + void read(NIFStream *nif) { Named::read(nif); flags = nif->getUShort(); @@ -67,7 +67,7 @@ public: int clamp, set, filter; short unknown2; - void read(NIFFile *nif) + void read(NIFStream *nif) { inUse = !!nif->getInt(); if(!inUse) return; @@ -111,7 +111,7 @@ public: */ Texture textures[7]; - void read(NIFFile *nif) + void read(NIFStream *nif) { Property::read(nif); apply = nif->getInt(); @@ -157,7 +157,7 @@ struct StructPropT : Property { T data; - void read(NIFFile *nif) + void read(NIFStream *nif) { Property::read(nif); data.read(nif); @@ -170,7 +170,7 @@ struct S_MaterialProperty Ogre::Vector3 ambient, diffuse, specular, emissive; float glossiness, alpha; - void read(NIFFile *nif) + void read(NIFStream *nif) { ambient = nif->getVector3(); diffuse = nif->getVector3(); @@ -194,7 +194,7 @@ struct S_VertexColorProperty */ int vertmode, lightmode; - void read(NIFFile *nif) + void read(NIFStream *nif) { vertmode = nif->getInt(); lightmode = nif->getInt(); @@ -251,7 +251,7 @@ struct S_AlphaProperty // Tested against when certain flags are set (see above.) unsigned char threshold; - void read(NIFFile *nif) + void read(NIFStream *nif) { threshold = nif->getChar(); } @@ -300,7 +300,7 @@ struct S_StencilProperty */ int drawMode; - void read(NIFFile *nif) + void read(NIFStream *nif) { enabled = nif->getChar(); compareFunc = nif->getInt(); diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 073f4657c..9f0645dfd 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -30,6 +30,7 @@ namespace Nif { class NIFFile; +class NIFStream; enum RecordType { @@ -97,7 +98,7 @@ struct Record Record() : recType(RC_MISSING), recIndex(~(size_t)0) {} /// Parses the record from file - virtual void read(NIFFile *nif) = 0; + virtual void read(NIFStream *nif) = 0; /// Does post-processing, after the entire tree is loaded virtual void post(NIFFile *nif) {} diff --git a/components/nif/record_ptr.hpp b/components/nif/record_ptr.hpp index ef5bb1dee..855099a04 100644 --- a/components/nif/record_ptr.hpp +++ b/components/nif/record_ptr.hpp @@ -46,7 +46,7 @@ public: RecordPtrT() : index(-2) {} /// Read the index from the nif - void read(NIFFile *nif) + void read(NIFStream *nif) { // Can only read the index once assert(index == -2); @@ -99,7 +99,7 @@ class RecordListT std::vector list; public: - void read(NIFFile *nif) + void read(NIFStream *nif) { int len = nif->getInt(); list.resize(len); From 0ed2015319a0afa2c59a393e7e876572af419134 Mon Sep 17 00:00:00 2001 From: Nathan Jeffords Date: Thu, 3 Jan 2013 23:59:32 -0800 Subject: [PATCH 47/61] refactored NIFFile parse to get better code/data seperation --- components/nif/nif_file.cpp | 184 ++++++++++++++++++++---------------- 1 file changed, 103 insertions(+), 81 deletions(-) diff --git a/components/nif/nif_file.cpp b/components/nif/nif_file.cpp index f3faf563c..dc8670cba 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/nif_file.cpp @@ -185,6 +185,101 @@ NIFFile::~NIFFile() delete records[i]; } +template static Record* construct() { return new NodeType; } + +struct RecordFactoryEntry { + + typedef Record* (*create_t) (); + + char const * mName; + create_t mCreate; + RecordType mType; + +}; + +/* These are all the record types we know how to read. + + This can be heavily optimized later if needed. For example, a + hash table or a FSM-based parser could be used to look up + node names. +*/ + +static const RecordFactoryEntry recordFactories [] = { + + { "NiNode", &construct , RC_NiNode }, + { "AvoidNode", &construct , RC_NiNode }, + { "NiBSParticleNode", &construct , RC_NiNode }, + { "NiBSAnimationNode", &construct , RC_NiNode }, + { "NiBillboardNode", &construct , RC_NiNode }, + { "NiTriShape", &construct , RC_NiTriShape }, + { "NiRotatingParticles", &construct , RC_NiRotatingParticles }, + { "NiAutoNormalParticles", &construct , RC_NiAutoNormalParticles }, + { "NiCamera", &construct , RC_NiCamera }, + { "RootCollisionNode", &construct , RC_RootCollisionNode }, + { "NiTexturingProperty", &construct , RC_NiTexturingProperty }, + { "NiMaterialProperty", &construct , RC_NiMaterialProperty }, + { "NiZBufferProperty", &construct , RC_NiZBufferProperty }, + { "NiAlphaProperty", &construct , RC_NiAlphaProperty }, + { "NiVertexColorProperty", &construct , RC_NiVertexColorProperty }, + { "NiShadeProperty", &construct , RC_NiShadeProperty }, + { "NiDitherProperty", &construct , RC_NiDitherProperty }, + { "NiWireframeProperty", &construct , RC_NiWireframeProperty }, + { "NiSpecularProperty", &construct , RC_NiSpecularProperty }, + { "NiStencilProperty", &construct , RC_NiStencilProperty }, + { "NiVisController", &construct , RC_NiVisController }, + { "NiGeomMorpherController", &construct , RC_NiGeomMorpherController }, + { "NiKeyframeController", &construct , RC_NiKeyframeController }, + { "NiAlphaController", &construct , RC_NiAlphaController }, + { "NiUVController", &construct , RC_NiUVController }, + { "NiPathController", &construct , RC_NiPathController }, + { "NiMaterialColorController", &construct , RC_NiMaterialColorController }, + { "NiBSPArrayController", &construct , RC_NiBSPArrayController }, + { "NiParticleSystemController", &construct , RC_NiParticleSystemController }, + { "NiAmbientLight", &construct , RC_NiLight }, + { "NiDirectionalLight", &construct , RC_NiLight }, + { "NiTextureEffect", &construct , RC_NiTextureEffect }, + { "NiVertWeightsExtraData", &construct , RC_NiVertWeightsExtraData }, + { "NiTextKeyExtraData", &construct , RC_NiTextKeyExtraData }, + { "NiStringExtraData", &construct , RC_NiStringExtraData }, + { "NiGravity", &construct , RC_NiGravity }, + { "NiPlanarCollider", &construct , RC_NiPlanarCollider }, + { "NiParticleGrowFade", &construct , RC_NiParticleGrowFade }, + { "NiParticleColorModifier", &construct , RC_NiParticleColorModifier }, + { "NiParticleRotation", &construct , RC_NiParticleRotation }, + { "NiFloatData", &construct , RC_NiFloatData }, + { "NiTriShapeData", &construct , RC_NiTriShapeData }, + { "NiVisData", &construct , RC_NiVisData }, + { "NiColorData", &construct , RC_NiColorData }, + { "NiPixelData", &construct , RC_NiPixelData }, + { "NiMorphData", &construct , RC_NiMorphData }, + { "NiKeyframeData", &construct , RC_NiKeyframeData }, + { "NiSkinData", &construct , RC_NiSkinData }, + { "NiUVData", &construct , RC_NiUVData }, + { "NiPosData", &construct , RC_NiPosData }, + { "NiRotatingParticlesData", &construct , RC_NiRotatingParticlesData }, + { "NiAutoNormalParticlesData", &construct , RC_NiAutoNormalParticlesData }, + { "NiSequenceStreamHelper", &construct , RC_NiSequenceStreamHelper }, + { "NiSourceTexture", &construct , RC_NiSourceTexture }, + { "NiSkinInstance", &construct , RC_NiSkinInstance }, +}; + +static RecordFactoryEntry const * recordFactories_begin = &recordFactories [0]; +static RecordFactoryEntry const * recordFactories_end = &recordFactories [sizeof (recordFactories) / sizeof (recordFactories[0])]; + +RecordFactoryEntry const * lookupRecordFactory (char const * name) +{ + RecordFactoryEntry const * i; + + for (i = recordFactories_begin; i != recordFactories_end; ++i) + if (strcmp (name, i->mName) == 0) + break; + + if (i == recordFactories_end) + return NULL; + + return i; +} + /* This file implements functions from the NIFFile class. It is also where we stash all the functions we couldn't add as inline definitions in the record types. @@ -223,88 +318,15 @@ void NIFFile::parse() std::string rec = nif.getString(); - /* These are all the record types we know how to read. - - This can be heavily optimized later if needed. For example, a - hash table or a FSM-based parser could be used to look up - node names. - */ - - // NiNodes - if(rec == "NiNode" || rec == "AvoidNode" || - rec == "NiBSParticleNode" || - rec == "NiBSAnimationNode" || - rec == "NiBillboardNode") { r = new NiNode; r->recType = RC_NiNode; } - - // Other nodes - else if(rec == "NiTriShape") { r = new NiTriShape; r->recType = RC_NiTriShape; } - else if(rec == "NiRotatingParticles") { r = new NiRotatingParticles; r->recType = RC_NiRotatingParticles; } - else if(rec == "NiAutoNormalParticles") { r = new NiAutoNormalParticles; r->recType = RC_NiAutoNormalParticles; } - else if(rec == "NiCamera") { r = new NiCamera; r->recType = RC_NiCamera; } - else if(rec == "RootCollisionNode"){ r = new NiNode; r->recType = RC_RootCollisionNode; }// a root collision node is exactly like a node - //that's why there is no need to create a new type - - // Properties - else if(rec == "NiTexturingProperty") { r = new NiTexturingProperty; r->recType = RC_NiTexturingProperty; } - else if(rec == "NiMaterialProperty") { r = new NiMaterialProperty; r->recType = RC_NiMaterialProperty; } - else if(rec == "NiZBufferProperty") { r = new NiZBufferProperty; r->recType = RC_NiZBufferProperty; } - else if(rec == "NiAlphaProperty") { r = new NiAlphaProperty; r->recType = RC_NiAlphaProperty; } - else if(rec == "NiVertexColorProperty") { r = new NiVertexColorProperty; r->recType = RC_NiVertexColorProperty; } - else if(rec == "NiShadeProperty") { r = new NiShadeProperty; r->recType = RC_NiShadeProperty; } - else if(rec == "NiDitherProperty") { r = new NiDitherProperty; r->recType = RC_NiDitherProperty; } - else if(rec == "NiWireframeProperty") { r = new NiWireframeProperty; r->recType = RC_NiWireframeProperty; } - else if(rec == "NiSpecularProperty") { r = new NiSpecularProperty; r->recType = RC_NiSpecularProperty; } - else if(rec == "NiStencilProperty") { r = new NiStencilProperty; r->recType = RC_NiStencilProperty; } - - // Controllers - else if(rec == "NiVisController") { r = new NiVisController; r->recType = RC_NiVisController; } - else if(rec == "NiGeomMorpherController") { r = new NiGeomMorpherController; r->recType = RC_NiGeomMorpherController; } - else if(rec == "NiKeyframeController") { r = new NiKeyframeController; r->recType = RC_NiKeyframeController; } - else if(rec == "NiAlphaController") { r = new NiAlphaController; r->recType = RC_NiAlphaController; } - else if(rec == "NiUVController") { r = new NiUVController; r->recType = RC_NiUVController; } - else if(rec == "NiPathController") { r = new NiPathController; r->recType = RC_NiPathController; } - else if(rec == "NiMaterialColorController") { r = new NiMaterialColorController; r->recType = RC_NiMaterialColorController; } - else if(rec == "NiBSPArrayController") { r = new NiBSPArrayController; r->recType = RC_NiBSPArrayController; } - else if(rec == "NiParticleSystemController") { r = new NiParticleSystemController; r->recType = RC_NiParticleSystemController; } - - // Effects - else if(rec == "NiAmbientLight" || - rec == "NiDirectionalLight") { r = new NiLight; r->recType = RC_NiLight; } - else if(rec == "NiTextureEffect") { r = new NiTextureEffect; r->recType = RC_NiTextureEffect; } - - // Extra Data - else if(rec == "NiVertWeightsExtraData") { r = new NiVertWeightsExtraData; r->recType = RC_NiVertWeightsExtraData; } - else if(rec == "NiTextKeyExtraData") { r = new NiTextKeyExtraData; r->recType = RC_NiTextKeyExtraData; } - else if(rec == "NiStringExtraData") { r = new NiStringExtraData; r->recType = RC_NiStringExtraData; } - - else if(rec == "NiGravity") { r = new NiGravity; r->recType = RC_NiGravity; } - else if(rec == "NiPlanarCollider") { r = new NiPlanarCollider; r->recType = RC_NiPlanarCollider; } - else if(rec == "NiParticleGrowFade") { r = new NiParticleGrowFade; r->recType = RC_NiParticleGrowFade; } - else if(rec == "NiParticleColorModifier") { r = new NiParticleColorModifier; r->recType = RC_NiParticleColorModifier; } - else if(rec == "NiParticleRotation") { r = new NiParticleRotation; r->recType = RC_NiParticleRotation; } - - // Data - else if(rec == "NiFloatData") { r = new NiFloatData; r->recType = RC_NiFloatData; } - else if(rec == "NiTriShapeData") { r = new NiTriShapeData; r->recType = RC_NiTriShapeData; } - else if(rec == "NiVisData") { r = new NiVisData; r->recType = RC_NiVisData; } - else if(rec == "NiColorData") { r = new NiColorData; r->recType = RC_NiColorData; } - else if(rec == "NiPixelData") { r = new NiPixelData; r->recType = RC_NiPixelData; } - else if(rec == "NiMorphData") { r = new NiMorphData; r->recType = RC_NiMorphData; } - else if(rec == "NiKeyframeData") { r = new NiKeyframeData; r->recType = RC_NiKeyframeData; } - else if(rec == "NiSkinData") { r = new NiSkinData; r->recType = RC_NiSkinData; } - else if(rec == "NiUVData") { r = new NiUVData; r->recType = RC_NiUVData; } - else if(rec == "NiPosData") { r = new NiPosData; r->recType = RC_NiPosData; } - else if(rec == "NiRotatingParticlesData") { r = new NiRotatingParticlesData; r->recType = RC_NiRotatingParticlesData; } - else if(rec == "NiAutoNormalParticlesData") { r = new NiAutoNormalParticlesData; r->recType = RC_NiAutoNormalParticlesData; } - - // Other - else if(rec == "NiSequenceStreamHelper") { r = new NiSequenceStreamHelper; r->recType = RC_NiSequenceStreamHelper; } - else if(rec == "NiSourceTexture") { r = new NiSourceTexture; r->recType = RC_NiSourceTexture; } - else if(rec == "NiSkinInstance") { r = new NiSkinInstance; r->recType = RC_NiSkinInstance; } - - // Failure + RecordFactoryEntry const * entry = lookupRecordFactory (rec.c_str ()); + + if (entry != NULL) + { + r = entry->mCreate (); + r->recType = entry->mType; + } else - fail("Unknown record type " + rec); + fail("Unknown record type " + rec); assert(r != NULL); assert(r->recType != RC_MISSING); From d3c1f5e7b23bcfb30fb418b9f0acb18bcfa273a9 Mon Sep 17 00:00:00 2001 From: Nathan Jeffords Date: Sun, 24 Feb 2013 13:51:56 -0800 Subject: [PATCH 48/61] renamed low-level NIF related files and include guards to conform to naming convention --- apps/openmw/engine.cpp | 2 +- apps/openmw/mwworld/scene.cpp | 2 +- components/CMakeLists.txt | 2 +- components/nif/controlled.hpp | 4 ++-- components/nif/controller.hpp | 8 ++++---- components/nif/data.hpp | 4 ++-- components/nif/effect.hpp | 4 ++-- components/nif/extra.hpp | 8 ++++---- components/nif/{nif_file.cpp => niffile.cpp} | 2 +- components/nif/{nif_file.hpp => niffile.hpp} | 8 ++++---- components/nif/{nif_stream.hpp => nifstream.hpp} | 4 ++-- components/nif/{nif_types.hpp => niftypes.hpp} | 4 ++-- components/nif/node.hpp | 4 ++-- components/nif/property.hpp | 4 ++-- components/nif/record.hpp | 4 ++-- components/nif/{record_ptr.hpp => recordptr.hpp} | 6 +++--- components/nifbullet/bullet_nif_loader.cpp | 2 +- 17 files changed, 36 insertions(+), 36 deletions(-) rename components/nif/{nif_file.cpp => niffile.cpp} (99%) rename components/nif/{nif_file.hpp => niffile.hpp} (97%) rename components/nif/{nif_stream.hpp => nifstream.hpp} (97%) rename components/nif/{nif_types.hpp => niftypes.hpp} (93%) rename components/nif/{record_ptr.hpp => recordptr.hpp} (97%) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index d14696cdd..a69dc7402 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index ecf783d6c..35024b307 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -1,6 +1,6 @@ #include "scene.hpp" -#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" /// FIXME diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 00342e2ac..a80afdd6b 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -15,7 +15,7 @@ add_component_dir (bsa ) add_component_dir (nif - controlled effect nif_types record controller extra node record_ptr data nif_file property + controlled effect niftypes record controller extra node record_ptr data niffile property ) add_component_dir (nifogre diff --git a/components/nif/controlled.hpp b/components/nif/controlled.hpp index dac541b2d..36c9a82ac 100644 --- a/components/nif/controlled.hpp +++ b/components/nif/controlled.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_CONTROLLED_H_ -#define _NIF_CONTROLLED_H_ +#ifndef OPENMW_COMPONENTS_NIF_CONTROLLED_HPP +#define OPENMW_COMPONENTS_NIF_CONTROLLED_HPP #include "extra.hpp" #include "controller.hpp" diff --git a/components/nif/controller.hpp b/components/nif/controller.hpp index 4f7ef3c0f..8331b93b7 100644 --- a/components/nif/controller.hpp +++ b/components/nif/controller.hpp @@ -21,12 +21,12 @@ */ -#ifndef _NIF_CONTROLLER_H_ -#define _NIF_CONTROLLER_H_ +#ifndef OPENMW_COMPONENTS_NIF_CONTROLLER_HPP +#define OPENMW_COMPONENTS_NIF_CONTROLLER_HPP #include "record.hpp" -#include "nif_file.hpp" -#include "record_ptr.hpp" +#include "niffile.hpp" +#include "recordptr.hpp" namespace Nif { diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 5f18800f0..9bdba6396 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_DATA_H_ -#define _NIF_DATA_H_ +#ifndef OPENMW_COMPONENTS_NIF_DATA_HPP +#define OPENMW_COMPONENTS_NIF_DATA_HPP #include "controlled.hpp" diff --git a/components/nif/effect.hpp b/components/nif/effect.hpp index b07a39303..cc1b0f41c 100644 --- a/components/nif/effect.hpp +++ b/components/nif/effect.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_EFFECT_H_ -#define _NIF_EFFECT_H_ +#ifndef OPENMW_COMPONENTS_NIF_EFFECT_HPP +#define OPENMW_COMPONENTS_NIF_EFFECT_HPP #include "node.hpp" diff --git a/components/nif/extra.hpp b/components/nif/extra.hpp index b5335f987..45c4fefc6 100644 --- a/components/nif/extra.hpp +++ b/components/nif/extra.hpp @@ -21,12 +21,12 @@ */ -#ifndef _NIF_EXTRA_H_ -#define _NIF_EXTRA_H_ +#ifndef OPENMW_COMPONENTS_NIF_EXTRA_HPP +#define OPENMW_COMPONENTS_NIF_EXTRA_HPP #include "record.hpp" -#include "nif_file.hpp" -#include "record_ptr.hpp" +#include "niffile.hpp" +#include "recordptr.hpp" namespace Nif { diff --git a/components/nif/nif_file.cpp b/components/nif/niffile.cpp similarity index 99% rename from components/nif/nif_file.cpp rename to components/nif/niffile.cpp index dc8670cba..bf05e7576 100644 --- a/components/nif/nif_file.cpp +++ b/components/nif/niffile.cpp @@ -21,7 +21,7 @@ */ -#include "nif_file.hpp" +#include "niffile.hpp" #include "record.hpp" #include "components/misc/stringops.hpp" diff --git a/components/nif/nif_file.hpp b/components/nif/niffile.hpp similarity index 97% rename from components/nif/nif_file.hpp rename to components/nif/niffile.hpp index a406de4a0..ed11bdd7c 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/niffile.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_FILE_H_ -#define _NIF_FILE_H_ +#ifndef OPENMW_COMPONENTS_NIF_NIFFILE_HPP +#define OPENMW_COMPONENTS_NIF_NIFFILE_HPP #include #include @@ -45,8 +45,8 @@ #include #include "record.hpp" -#include "nif_types.hpp" -#include "nif_stream.hpp" +#include "niftypes.hpp" +#include "nifstream.hpp" namespace Nif { diff --git a/components/nif/nif_stream.hpp b/components/nif/nifstream.hpp similarity index 97% rename from components/nif/nif_stream.hpp rename to components/nif/nifstream.hpp index 8fb98f3d6..02b931b7e 100644 --- a/components/nif/nif_stream.hpp +++ b/components/nif/nifstream.hpp @@ -1,5 +1,5 @@ -#ifndef _NIF_STREAM_HPP_ -#define _NIF_STREAM_HPP_ +#ifndef OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP +#define OPENMW_COMPONENTS_NIF_NIFSTREAM_HPP namespace Nif { diff --git a/components/nif/nif_types.hpp b/components/nif/niftypes.hpp similarity index 93% rename from components/nif/nif_types.hpp rename to components/nif/niftypes.hpp index a5fb61361..786c48b65 100644 --- a/components/nif/nif_types.hpp +++ b/components/nif/niftypes.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_TYPES_H_ -#define _NIF_TYPES_H_ +#ifndef OPENMW_COMPONENTS_NIF_NIFTYPES_HPP +#define OPENMW_COMPONENTS_NIF_NIFTYPES_HPP #include #include diff --git a/components/nif/node.hpp b/components/nif/node.hpp index e08703756..ab92d74f8 100644 --- a/components/nif/node.hpp +++ b/components/nif/node.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_NODE_H_ -#define _NIF_NODE_H_ +#ifndef OPENMW_COMPONENTS_NIF_NODE_HPP +#define OPENMW_COMPONENTS_NIF_NODE_HPP #include diff --git a/components/nif/property.hpp b/components/nif/property.hpp index cdf97986c..cd1e0a5d1 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_PROPERTY_H_ -#define _NIF_PROPERTY_H_ +#ifndef OPENMW_COMPONENTS_NIF_PROPERTY_HPP +#define OPENMW_COMPONENTS_NIF_PROPERTY_HPP #include "controlled.hpp" diff --git a/components/nif/record.hpp b/components/nif/record.hpp index 9f0645dfd..3a3cd9b84 100644 --- a/components/nif/record.hpp +++ b/components/nif/record.hpp @@ -21,8 +21,8 @@ */ -#ifndef _NIF_RECORD_H_ -#define _NIF_RECORD_H_ +#ifndef OPENMW_COMPONENTS_NIF_RECORD_HPP +#define OPENMW_COMPONENTS_NIF_RECORD_HPP #include diff --git a/components/nif/record_ptr.hpp b/components/nif/recordptr.hpp similarity index 97% rename from components/nif/record_ptr.hpp rename to components/nif/recordptr.hpp index 855099a04..c5bafea12 100644 --- a/components/nif/record_ptr.hpp +++ b/components/nif/recordptr.hpp @@ -21,10 +21,10 @@ */ -#ifndef _NIF_RECORD_PTR_H_ -#define _NIF_RECORD_PTR_H_ +#ifndef OPENMW_COMPONENTS_NIF_RECORDPTR_HPP +#define OPENMW_COMPONENTS_NIF_RECORDPTR_HPP -#include "nif_file.hpp" +#include "niffile.hpp" #include namespace Nif diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bullet_nif_loader.cpp index 3d9c16ebb..e33754264 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bullet_nif_loader.cpp @@ -25,7 +25,7 @@ http://www.gnu.org/licenses/ . #include #include -#include "../nif/nif_file.hpp" +#include "../nif/niffile.hpp" #include "../nif/node.hpp" #include "../nif/data.hpp" #include "../nif/property.hpp" From 109dff2d29f1ed3b71c4169f917f390043278b46 Mon Sep 17 00:00:00 2001 From: Nathan Jeffords Date: Sun, 24 Feb 2013 13:52:23 -0800 Subject: [PATCH 49/61] renamed high level NIF files... --- apps/openmw/engine.cpp | 4 ++-- apps/openmw/mwrender/animation.hpp | 2 +- apps/openmw/mwrender/objects.cpp | 2 +- apps/openmw/mwrender/sky.cpp | 2 +- apps/openmw/mwworld/physicssystem.cpp | 2 +- components/CMakeLists.txt | 4 ++-- .../nifbullet/{bullet_nif_loader.cpp => bulletnifloader.cpp} | 2 +- .../nifbullet/{bullet_nif_loader.hpp => bulletnifloader.hpp} | 4 ++-- components/nifogre/{ogre_nif_loader.cpp => ogrenifloader.cpp} | 2 +- components/nifogre/{ogre_nif_loader.hpp => ogrenifloader.hpp} | 4 ++-- components/nifoverrides/nifoverrides.hpp | 4 ++-- libs/openengine/bullet/CMotionState.cpp | 2 +- libs/openengine/bullet/physic.cpp | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) rename components/nifbullet/{bullet_nif_loader.cpp => bulletnifloader.cpp} (99%) rename components/nifbullet/{bullet_nif_loader.hpp => bulletnifloader.hpp} (96%) rename components/nifogre/{ogre_nif_loader.cpp => ogrenifloader.cpp} (99%) rename components/nifogre/{ogre_nif_loader.hpp => ogrenifloader.hpp} (96%) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a69dc7402..74e967d8d 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -12,8 +12,8 @@ #include #include -#include -#include +#include +#include #include "mwinput/inputmanagerimp.hpp" diff --git a/apps/openmw/mwrender/animation.hpp b/apps/openmw/mwrender/animation.hpp index 810ca869f..7caf35169 100644 --- a/apps/openmw/mwrender/animation.hpp +++ b/apps/openmw/mwrender/animation.hpp @@ -1,7 +1,7 @@ #ifndef _GAME_RENDER_ANIMATION_H #define _GAME_RENDER_ANIMATION_H -#include +#include #include "../mwworld/ptr.hpp" diff --git a/apps/openmw/mwrender/objects.cpp b/apps/openmw/mwrender/objects.cpp index e91180a42..89425e9f2 100644 --- a/apps/openmw/mwrender/objects.cpp +++ b/apps/openmw/mwrender/objects.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include #include #include "../mwworld/ptr.hpp" diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 062079693..0f778511d 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -14,7 +14,7 @@ #include -#include +#include #include diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 65cbc1164..566a463b6 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include //#include "../mwbase/world.hpp" // FIXME #include "../mwbase/environment.hpp" diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index a80afdd6b..9fdc72873 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -19,11 +19,11 @@ add_component_dir (nif ) add_component_dir (nifogre - ogre_nif_loader + ogrenifloader ) add_component_dir (nifbullet - bullet_nif_loader + bulletnifloader ) add_component_dir (to_utf8 diff --git a/components/nifbullet/bullet_nif_loader.cpp b/components/nifbullet/bulletnifloader.cpp similarity index 99% rename from components/nifbullet/bullet_nif_loader.cpp rename to components/nifbullet/bulletnifloader.cpp index e33754264..91fd6dbcf 100644 --- a/components/nifbullet/bullet_nif_loader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -21,7 +21,7 @@ http://www.gnu.org/licenses/ . */ -#include "bullet_nif_loader.hpp" +#include "bulletnifloader.hpp" #include #include diff --git a/components/nifbullet/bullet_nif_loader.hpp b/components/nifbullet/bulletnifloader.hpp similarity index 96% rename from components/nifbullet/bullet_nif_loader.hpp rename to components/nifbullet/bulletnifloader.hpp index 0629b208d..0ff4b4ccd 100644 --- a/components/nifbullet/bullet_nif_loader.hpp +++ b/components/nifbullet/bulletnifloader.hpp @@ -21,8 +21,8 @@ */ -#ifndef _BULLET_NIF_LOADER_H_ -#define _BULLET_NIF_LOADER_H_ +#ifndef OPENMW_COMPONENTS_NIFBULLET_BULLETNIFLOADER_HPP +#define OPENMW_COMPONENTS_NIFBULLET_BULLETNIFLOADER_HPP #include #include diff --git a/components/nifogre/ogre_nif_loader.cpp b/components/nifogre/ogrenifloader.cpp similarity index 99% rename from components/nifogre/ogre_nif_loader.cpp rename to components/nifogre/ogrenifloader.cpp index d33243dd4..4eaedeaa8 100644 --- a/components/nifogre/ogre_nif_loader.cpp +++ b/components/nifogre/ogrenifloader.cpp @@ -21,7 +21,7 @@ */ -#include "ogre_nif_loader.hpp" +#include "ogrenifloader.hpp" #include diff --git a/components/nifogre/ogre_nif_loader.hpp b/components/nifogre/ogrenifloader.hpp similarity index 96% rename from components/nifogre/ogre_nif_loader.hpp rename to components/nifogre/ogrenifloader.hpp index eae37dd8a..b8b2e3c00 100644 --- a/components/nifogre/ogre_nif_loader.hpp +++ b/components/nifogre/ogrenifloader.hpp @@ -21,8 +21,8 @@ */ -#ifndef _OGRE_NIF_LOADER_H_ -#define _OGRE_NIF_LOADER_H_ +#ifndef OPENMW_COMPONENTS_NIFOGRE_OGRENIFLOADER_HPP +#define OPENMW_COMPONENTS_NIFOGRE_OGRENIFLOADER_HPP #include #include diff --git a/components/nifoverrides/nifoverrides.hpp b/components/nifoverrides/nifoverrides.hpp index c9b711df6..ba2e4cc3c 100644 --- a/components/nifoverrides/nifoverrides.hpp +++ b/components/nifoverrides/nifoverrides.hpp @@ -1,5 +1,5 @@ -#ifndef COMPONENTS_NIFOVERRIDES_H -#define COMPONENTS_NIFOVERRIDES_H +#ifndef OPENMW_COMPONENTS_NIFOVERRIDES_NIFOVERRIDES_HPP +#define OPENMW_COMPONENTS_NIFOVERRIDES_NIFOVERRIDES_HPP #include diff --git a/libs/openengine/bullet/CMotionState.cpp b/libs/openengine/bullet/CMotionState.cpp index 6be615dfb..c20415884 100644 --- a/libs/openengine/bullet/CMotionState.cpp +++ b/libs/openengine/bullet/CMotionState.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include namespace OEngine { namespace Physic diff --git a/libs/openengine/bullet/physic.cpp b/libs/openengine/bullet/physic.cpp index f993ce68e..119f6893a 100644 --- a/libs/openengine/bullet/physic.cpp +++ b/libs/openengine/bullet/physic.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include "CMotionState.h" #include "OgreRoot.h" #include "btKinematicCharacterController.h" From cf87708c1fc4a83aac6c668f3125020373371a5a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 12:01:19 +0100 Subject: [PATCH 50/61] Magic effect icons for spells --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwgui/hud.cpp | 23 ++- apps/openmw/mwgui/hud.hpp | 10 +- apps/openmw/mwgui/spellicons.cpp | 246 +++++++++++++++++++++++ apps/openmw/mwgui/spellicons.hpp | 47 +++++ apps/openmw/mwgui/spellwindow.cpp | 10 + apps/openmw/mwgui/spellwindow.hpp | 5 + apps/openmw/mwgui/tooltips.cpp | 12 +- apps/openmw/mwgui/tooltips.hpp | 4 + apps/openmw/mwgui/widgets.cpp | 12 +- apps/openmw/mwgui/windowmanagerimp.cpp | 3 + apps/openmw/mwgui/windowmanagerimp.hpp | 1 + apps/openmw/mwmechanics/activespells.cpp | 5 + apps/openmw/mwmechanics/activespells.hpp | 2 + files/mygui/openmw_hud.layout | 5 +- files/mygui/openmw_hud_box.skin.xml | 4 + files/mygui/openmw_spell_window.layout | 4 +- 17 files changed, 360 insertions(+), 35 deletions(-) create mode 100644 apps/openmw/mwgui/spellicons.cpp create mode 100644 apps/openmw/mwgui/spellicons.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 7cfeb84c5..e09dfb108 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -30,7 +30,7 @@ add_openmw_dir (mwgui formatting inventorywindow container hud countdialog tradewindow settingswindow confirmationdialog alchemywindow referenceinterface spellwindow mainmenu quickkeysmenu itemselection spellbuyingwindow loadingscreen levelupdialog waitdialog spellcreationdialog - enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor + enchantingdialog trainingwindow travelwindow imagebutton exposedwindow cursor spellicons ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index a2c3a318b..2eb96249c 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -19,6 +19,7 @@ #include "inventorywindow.hpp" #include "container.hpp" #include "console.hpp" +#include "spellicons.hpp" using namespace MWGui; @@ -32,7 +33,6 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) , mWeapStatus(NULL) , mSpellStatus(NULL) , mEffectBox(NULL) - , mEffect1(NULL) , mMinimap(NULL) , mCompass(NULL) , mCrosshair(NULL) @@ -86,9 +86,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) mSpellBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); getWidget(mEffectBox, "EffectBox"); - getWidget(mEffect1, "Effect1"); mEffectBoxBaseRight = viewSize.width - mEffectBox->getRight(); - mEffectBox->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onMagicClicked); getWidget(mMinimapBox, "MiniMapBox"); mMinimapBoxBaseRight = viewSize.width - mMinimapBox->getRight(); @@ -107,13 +105,18 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop) getWidget(mTriangleCounter, "TriangleCounter"); getWidget(mBatchCounter, "BatchCounter"); - setEffect("icons\\s\\tx_s_chameleon.dds"); - LocalMapBase::init(mMinimap, mCompass, this); mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked); mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver); mMainWidget->eventMouseLostFocus += MyGUI::newDelegate(this, &HUD::onWorldMouseLostFocus); + + mSpellIcons = new SpellIcons(); +} + +HUD::~HUD() +{ + delete mSpellIcons; } void HUD::setFpsLevel(int level) @@ -156,11 +159,6 @@ void HUD::setBatchCount(unsigned int count) mBatchCounter->setCaption(boost::lexical_cast(count)); } -void HUD::setEffect(const char *img) -{ - mEffect1->setImageTexture(img); -} - void HUD::setValue(const std::string& id, const MWMechanics::DynamicStat& value) { static const char *ids[] = @@ -542,3 +540,8 @@ void HUD::updatePositions() mMapVisible = mMinimapBox->getVisible (); mEffectBox->setPosition((viewSize.width - mEffectBoxBaseRight) - mEffectBox->getWidth() + effectsDx, mEffectBox->getTop()); } + +void HUD::update() +{ + mSpellIcons->updateWidgets(mEffectBox, true); +} diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index 013ad59f0..39d6eadca 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -8,12 +8,13 @@ namespace MWGui { class DragAndDrop; + class SpellIcons; class HUD : public OEngine::GUI::Layout, public LocalMapBase { public: HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop); - void setEffect(const char *img); + virtual ~HUD(); void setValue (const std::string& id, const MWMechanics::DynamicStat& value); void setFPS(float fps); void setTriangleCount(unsigned int count); @@ -43,6 +44,10 @@ namespace MWGui bool getWorldMouseOver() { return mWorldMouseOver; } + MyGUI::Widget* getEffectBox() { return mEffectBox; } + + void update(); + private: MyGUI::ProgressPtr mHealth, mMagicka, mStamina; MyGUI::Widget* mHealthFrame; @@ -51,7 +56,6 @@ namespace MWGui MyGUI::ProgressPtr mWeapStatus, mSpellStatus; MyGUI::Widget *mEffectBox, *mMinimapBox; MyGUI::Button* mMinimapButton; - MyGUI::ImageBox* mEffect1; MyGUI::ScrollView* mMinimap; MyGUI::ImageBox* mCompass; MyGUI::ImageBox* mCrosshair; @@ -85,6 +89,8 @@ namespace MWGui bool mWorldMouseOver; + SpellIcons* mSpellIcons; + void onWorldClicked(MyGUI::Widget* _sender); void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y); void onWorldMouseLostFocus(MyGUI::Widget* _sender, MyGUI::Widget* _new); diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp new file mode 100644 index 000000000..19b2a87ec --- /dev/null +++ b/apps/openmw/mwgui/spellicons.cpp @@ -0,0 +1,246 @@ +#include "spellicons.hpp" + +#include +#include +#include + +#include + +#include "../mwbase/world.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/windowmanager.hpp" + +#include "../mwworld/player.hpp" +#include "../mwworld/class.hpp" + +#include "../mwmechanics/activespells.hpp" +#include "../mwmechanics/creaturestats.hpp" + +#include "tooltips.hpp" + + +namespace MWGui +{ + + void SpellIcons::updateWidgets(MyGUI::Widget *parent, bool adjustSize) + { + MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const MWMechanics::CreatureStats& stats = MWWorld::Class::get(player).getCreatureStats(player); + + std::map > effects; + + // add permanent spells + const MWMechanics::Spells& spells = stats.getSpells(); + for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it) + { + const ESM::Spell* spell = MWBase::Environment::get().getWorld()->getStore().get().find(it->first); + + // these are the spell types that are permanently in effect + if (!(spell->mData.mType == ESM::Spell::ST_Ability) + && !(spell->mData.mType == ESM::Spell::ST_Disease) + && !(spell->mData.mType == ESM::Spell::ST_Curse) + && !(spell->mData.mType == ESM::Spell::ST_Blight)) + continue; + ESM::EffectList list = spell->mEffects; + for (std::vector::const_iterator effectIt = list.mList.begin(); + effectIt != list.mList.end(); ++effectIt) + { + const ESM::MagicEffect* magicEffect = + MWBase::Environment::get().getWorld ()->getStore ().get().find(effectIt->mEffectID); + MagicEffectInfo effectInfo; + effectInfo.mSource = getSpellDisplayName (it->first); + effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID); + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) + effectInfo.mKey.mArg = effectIt->mSkill; + else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + effectInfo.mKey.mArg = effectIt->mAttribute; + // just using the min magnitude here, permanent spells with a random magnitude just wouldn't make any sense + effectInfo.mMagnitude = effectIt->mMagnMin; + effectInfo.mPermanent = true; + + effects[effectIt->mEffectID].push_back (effectInfo); + } + } + + // add lasting effect spells/potions etc + const MWMechanics::ActiveSpells::TContainer& activeSpells = stats.getActiveSpells().getActiveSpells(); + for (MWMechanics::ActiveSpells::TContainer::const_iterator it = activeSpells.begin(); + it != activeSpells.end(); ++it) + { + ESM::EffectList list = getSpellEffectList(it->first); + + float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); + + for (std::vector::const_iterator effectIt = list.mList.begin(); + effectIt != list.mList.end(); ++effectIt) + { + const ESM::MagicEffect* magicEffect = + MWBase::Environment::get().getWorld ()->getStore ().get().find(effectIt->mEffectID); + + MagicEffectInfo effectInfo; + effectInfo.mSource = getSpellDisplayName (it->first); + effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID); + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) + effectInfo.mKey.mArg = effectIt->mSkill; + else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + effectInfo.mKey.mArg = effectIt->mAttribute; + effectInfo.mMagnitude = effectIt->mMagnMin + (effectIt->mMagnMax-effectIt->mMagnMin) * it->second.second; + effectInfo.mRemainingTime = effectIt->mDuration + + (it->second.first - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale; + + effects[effectIt->mEffectID].push_back (effectInfo); + } + } + + parent->setVisible(effects.size() != 0); + + int w=2; + if (adjustSize) + { + int s = effects.size() * 16+4; + int diff = parent->getWidth() - s; + parent->setSize(s, parent->getHeight()); + parent->setPosition(parent->getLeft()+diff, parent->getTop()); + } + + + for (std::map >::const_iterator it = effects.begin(); it != effects.end(); ++it) + { + MyGUI::ImageBox* image; + if (mWidgetMap.find(it->first) == mWidgetMap.end()) + image = parent->createWidget + ("ImageBox", MyGUI::IntCoord(w,2,16,16), MyGUI::Align::Default); + else + image = mWidgetMap[it->first]; + mWidgetMap[it->first] = image; + image->setPosition(w,2); + image->setVisible(true); + + const ESM::MagicEffect* effect = + MWBase::Environment::get().getWorld ()->getStore ().get().find(it->first); + + std::string icon = effect->mIcon; + icon[icon.size()-3] = 'd'; + icon[icon.size()-2] = 'd'; + icon[icon.size()-1] = 's'; + icon = "icons\\" + icon; + + image->setImageTexture(icon); + w += 16; + + float remainingDuration = 0; + + std::string sourcesDescription; + + const float fadeTime = 5.f; + + for (std::vector::const_iterator effectIt = it->second.begin(); + effectIt != it->second.end(); ++effectIt) + { + if (effectIt != it->second.begin()) + sourcesDescription += "\n"; + + // if at least one of the effect sources is permanent, the effect will never wear off + if (effectIt->mPermanent) + remainingDuration = fadeTime; + else + remainingDuration = std::max(remainingDuration, effectIt->mRemainingTime); + + sourcesDescription += effectIt->mSource; + + if (effect->mData.mFlags & ESM::MagicEffect::TargetSkill) + sourcesDescription += " (" + + MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Skill::sSkillNameIds[effectIt->mKey.mArg], "") + ")"; + if (effect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + sourcesDescription += " (" + + MWBase::Environment::get().getWindowManager()->getGameSettingString( + ESM::Attribute::sGmstAttributeIds[effectIt->mKey.mArg], "") + ")"; + + if (!(effect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) + { + std::string pt = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoint", ""); + std::string pts = MWBase::Environment::get().getWindowManager()->getGameSettingString("spoints", ""); + + sourcesDescription += ": " + boost::lexical_cast(effectIt->mMagnitude); + sourcesDescription += " " + ((effectIt->mMagnitude > 1) ? pts : pt); + } + } + + std::string name = ESM::MagicEffect::effectIdToString (it->first); + + ToolTipInfo tooltipInfo; + tooltipInfo.caption = "#{" + name + "}"; + tooltipInfo.icon = effect->mIcon; + tooltipInfo.text = sourcesDescription; + tooltipInfo.imageSize = 16; + tooltipInfo.wordWrap = false; + + image->setUserData(tooltipInfo); + image->setUserString("ToolTipType", "ToolTipInfo"); + + // Fade out during the last 5 seconds + image->setAlpha(std::min(remainingDuration/fadeTime, 1.f)); + } + + // hide inactive effects + for (std::map::iterator it = mWidgetMap.begin(); it != mWidgetMap.end(); ++it) + { + if (effects.find(it->first) == effects.end()) + it->second->setVisible(false); + } + + } + + + std::string SpellIcons::getSpellDisplayName (const std::string& id) + { + if (const ESM::Spell *spell = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return spell->mName; + + if (const ESM::Potion *potion = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return potion->mName; + + if (const ESM::Ingredient *ingredient = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return ingredient->mName; + + throw std::runtime_error ("ID " + id + " has no display name"); + } + + ESM::EffectList SpellIcons::getSpellEffectList (const std::string& id) + { + if (const ESM::Spell *spell = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return spell->mEffects; + + if (const ESM::Potion *potion = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + return potion->mEffects; + + if (const ESM::Ingredient *ingredient = + MWBase::Environment::get().getWorld()->getStore().get().search (id)) + { + const ESM::MagicEffect *magicEffect = + MWBase::Environment::get().getWorld()->getStore().get().find ( + ingredient->mData.mEffectID[0]); + + ESM::ENAMstruct effect; + effect.mEffectID = ingredient->mData.mEffectID[0]; + effect.mSkill = ingredient->mData.mSkills[0]; + effect.mAttribute = ingredient->mData.mAttributes[0]; + effect.mRange = 0; + effect.mArea = 0; + effect.mDuration = magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration ? 0 : 1; + effect.mMagnMin = 1; + effect.mMagnMax = 1; + ESM::EffectList result; + result.mList.push_back (effect); + return result; + } + throw std::runtime_error("ID " + id + " does not have effects"); + } + +} diff --git a/apps/openmw/mwgui/spellicons.hpp b/apps/openmw/mwgui/spellicons.hpp new file mode 100644 index 000000000..af600e347 --- /dev/null +++ b/apps/openmw/mwgui/spellicons.hpp @@ -0,0 +1,47 @@ +#ifndef MWGUI_SPELLICONS_H +#define MWGUI_SPELLICONS_H + +#include + +#include "../mwmechanics/magiceffects.hpp" + +namespace MyGUI +{ + class Widget; + class ImageBox; +} +namespace ESM +{ + struct ENAMstruct; + struct EffectList; +} + +namespace MWGui +{ + + // information about a single magic effect source as required for display in the tooltip + struct MagicEffectInfo + { + MagicEffectInfo() : mPermanent(false) {} + std::string mSource; // display name for effect source (e.g. potion name) + MWMechanics::EffectKey mKey; + int mMagnitude; + float mRemainingTime; + bool mPermanent; // the effect is permanent + }; + + class SpellIcons + { + public: + void updateWidgets(MyGUI::Widget* parent, bool adjustSize); + + private: + std::string getSpellDisplayName (const std::string& id); + ESM::EffectList getSpellEffectList (const std::string& id); + + std::map mWidgetMap; + }; + +} + +#endif diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 47e1d739a..50691d554 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -19,6 +19,7 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/spellsuccess.hpp" +#include "spellicons.hpp" #include "inventorywindow.hpp" #include "confirmationdialog.hpp" @@ -51,6 +52,8 @@ namespace MWGui , mHeight(0) , mWidth(0) { + mSpellIcons = new SpellIcons(); + getWidget(mSpellView, "SpellView"); getWidget(mEffectBox, "EffectsBox"); @@ -61,6 +64,11 @@ namespace MWGui mMainWidget->castType()->eventWindowChangeCoord += MyGUI::newDelegate(this, &SpellWindow::onWindowResize); } + SpellWindow::~SpellWindow() + { + delete mSpellIcons; + } + void SpellWindow::onPinToggled() { mWindowManager.setSpellVisibility(!mPinned); @@ -73,6 +81,8 @@ namespace MWGui void SpellWindow::updateSpells() { + mSpellIcons->updateWidgets(mEffectBox, false); + const int spellHeight = 18; mHeight = 0; diff --git a/apps/openmw/mwgui/spellwindow.hpp b/apps/openmw/mwgui/spellwindow.hpp index caa67fd74..1963d4346 100644 --- a/apps/openmw/mwgui/spellwindow.hpp +++ b/apps/openmw/mwgui/spellwindow.hpp @@ -5,10 +5,13 @@ namespace MWGui { + class SpellIcons; + class SpellWindow : public WindowPinnableBase { public: SpellWindow(MWBase::WindowManager& parWindowManager); + virtual ~SpellWindow(); void updateSpells(); @@ -33,6 +36,8 @@ namespace MWGui virtual void onPinToggled(); virtual void open(); + + SpellIcons* mSpellIcons; }; } diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index c7acf568d..b42f9ac25 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -127,9 +127,7 @@ void ToolTips::onFrame(float frameDuration) Widget* focus = InputManager::getInstance().getMouseFocusWidget(); if (focus == 0) - { return; - } IntSize tooltipSize; @@ -168,6 +166,10 @@ void ToolTips::onFrame(float frameDuration) mFocusObject = *focus->getUserData(); tooltipSize = getToolTipViaPtr(false); } + else if (type == "ToolTipInfo") + { + tooltipSize = createToolTip(*focus->getUserData()); + } else if (type == "AvatarItemSelection") { MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord (); @@ -363,7 +365,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) std::string caption = info.caption; std::string image = info.icon; - int imageSize = (image != "") ? 32 : 0; + int imageSize = (image != "") ? info.imageSize : 0; std::string text = info.text; // remove the first newline (easier this way) @@ -403,7 +405,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) EditBox* captionWidget = mDynamicToolTipBox->createWidget("NormalText", IntCoord(0, 0, 300, 300), Align::Left | Align::Top, "ToolTipCaption"); captionWidget->setProperty("Static", "true"); - captionWidget->setCaption(caption); + captionWidget->setCaptionWithReplacing(caption); IntSize captionSize = captionWidget->getTextSize(); int captionHeight = std::max(caption != "" ? captionSize.height : 0, imageSize); @@ -411,7 +413,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) EditBox* textWidget = mDynamicToolTipBox->createWidget("SandText", IntCoord(0, captionHeight+imageCaptionVPadding, 300, 300-captionHeight-imageCaptionVPadding), Align::Stretch, "ToolTipText"); textWidget->setProperty("Static", "true"); textWidget->setProperty("MultiLine", "true"); - textWidget->setProperty("WordWrap", "true"); + textWidget->setProperty("WordWrap", info.wordWrap ? "true" : "false"); textWidget->setCaptionWithReplacing(text); textWidget->setTextAlign(Align::HCenter | Align::Top); IntSize textSize = textWidget->getTextSize(); diff --git a/apps/openmw/mwgui/tooltips.hpp b/apps/openmw/mwgui/tooltips.hpp index 4048d0d5a..ba94915cc 100644 --- a/apps/openmw/mwgui/tooltips.hpp +++ b/apps/openmw/mwgui/tooltips.hpp @@ -15,11 +15,14 @@ namespace MWGui public: ToolTipInfo() : isPotion(false) + , imageSize(32) + , wordWrap(true) {} std::string caption; std::string text; std::string icon; + int imageSize; // enchantment (for cloth, armor, weapons) std::string enchant; @@ -28,6 +31,7 @@ namespace MWGui Widgets::SpellEffectList effects; bool isPotion; // potions do not show target in the tooltip + bool wordWrap; }; class ToolTips : public OEngine::GUI::Layout diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index f932c1f03..ade681963 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -421,17 +421,7 @@ void MWSpellEffect::updateWidgets() } if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) { - static const char *attributes[8] = { - "sAttributeStrength", - "sAttributeIntelligence", - "sAttributeWillpower", - "sAttributeAgility", - "sAttributeSpeed", - "sAttributeEndurance", - "sAttributePersonality", - "sAttributeLuck" - }; - spellLine += " " + mWindowManager->getGameSettingString(attributes[mEffectParams.mAttribute], ""); + spellLine += " " + mWindowManager->getGameSettingString(ESM::Attribute::sGmstAttributeIds[mEffectParams.mAttribute], ""); } if ((mEffectParams.mMagnMin >= 0 || mEffectParams.mMagnMax >= 0) && !(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1138f62fa..0110171e6 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -54,6 +54,7 @@ #include "imagebutton.hpp" #include "exposedwindow.hpp" #include "cursor.hpp" +#include "spellicons.hpp" using namespace MWGui; @@ -270,6 +271,8 @@ void WindowManager::update() mHud->setTriangleCount(mTriangleCount); mHud->setBatchCount(mBatchCount); + mHud->update(); + mCursor->update(); } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index e2d64a855..4e8f12160 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -73,6 +73,7 @@ namespace MWGui class EnchantingDialog; class TrainingWindow; class Cursor; + class SpellIcons; class WindowManager : public MWBase::WindowManager { diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index ee1e9da36..933c5094d 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -274,4 +274,9 @@ namespace MWMechanics } return false; } + + const ActiveSpells::TContainer& ActiveSpells::getActiveSpells() const + { + return mSpells; + } } diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 6b832f4cd..05aa2bbdd 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -63,6 +63,8 @@ namespace MWMechanics const MagicEffects& getMagicEffects() const; + const TContainer& getActiveSpells() const; + TIterator begin() const; TIterator end() const; diff --git a/files/mygui/openmw_hud.layout b/files/mygui/openmw_hud.layout index e4c6f0765..382bc6dc9 100644 --- a/files/mygui/openmw_hud.layout +++ b/files/mygui/openmw_hud.layout @@ -61,10 +61,7 @@ - - + diff --git a/files/mygui/openmw_hud_box.skin.xml b/files/mygui/openmw_hud_box.skin.xml index 23480e8d3..f847ca51a 100644 --- a/files/mygui/openmw_hud_box.skin.xml +++ b/files/mygui/openmw_hud_box.skin.xml @@ -16,6 +16,10 @@ + + + + diff --git a/files/mygui/openmw_spell_window.layout b/files/mygui/openmw_spell_window.layout index 6c6629605..18a5af352 100644 --- a/files/mygui/openmw_spell_window.layout +++ b/files/mygui/openmw_spell_window.layout @@ -4,8 +4,8 @@ - - + + From 8e05c4159d309259cd31fd30181e1593d0e02ffb Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 12:17:37 +0100 Subject: [PATCH 51/61] Magic effect icons for permanent enchantments --- apps/openmw/mwgui/spellicons.cpp | 40 ++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index 19b2a87ec..dcbbed49c 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -12,6 +12,7 @@ #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwmechanics/activespells.hpp" #include "../mwmechanics/creaturestats.hpp" @@ -29,6 +30,41 @@ namespace MWGui std::map > effects; + // add permanent item enchantments + MWWorld::InventoryStore& store = MWWorld::Class::get(player).getInventoryStore(player); + for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) + { + MWWorld::ContainerStoreIterator it = store.getSlot(slot); + if (it == store.end()) + continue; + std::string enchantment = MWWorld::Class::get(*it).getEnchantment(*it); + if (enchantment.empty()) + continue; + const ESM::Enchantment* enchant = MWBase::Environment::get().getWorld()->getStore().get().find(enchantment); + if (enchant->mData.mType != ESM::Enchantment::ConstantEffect) + continue; + + const ESM::EffectList& list = enchant->mEffects; + for (std::vector::const_iterator effectIt = list.mList.begin(); + effectIt != list.mList.end(); ++effectIt) + { + const ESM::MagicEffect* magicEffect = + MWBase::Environment::get().getWorld ()->getStore ().get().find(effectIt->mEffectID); + + MagicEffectInfo effectInfo; + effectInfo.mSource = MWWorld::Class::get(*it).getName(*it); + effectInfo.mKey = MWMechanics::EffectKey (effectIt->mEffectID); + if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetSkill) + effectInfo.mKey.mArg = effectIt->mSkill; + else if (magicEffect->mData.mFlags & ESM::MagicEffect::TargetAttribute) + effectInfo.mKey.mArg = effectIt->mAttribute; + // just using the min magnitude here, permanent enchantments with a random magnitude just wouldn't make any sense + effectInfo.mMagnitude = effectIt->mMagnMin; + effectInfo.mPermanent = true; + effects[effectIt->mEffectID].push_back (effectInfo); + } + } + // add permanent spells const MWMechanics::Spells& spells = stats.getSpells(); for (MWMechanics::Spells::TIterator it = spells.begin(); it != spells.end(); ++it) @@ -41,7 +77,7 @@ namespace MWGui && !(spell->mData.mType == ESM::Spell::ST_Curse) && !(spell->mData.mType == ESM::Spell::ST_Blight)) continue; - ESM::EffectList list = spell->mEffects; + const ESM::EffectList& list = spell->mEffects; for (std::vector::const_iterator effectIt = list.mList.begin(); effectIt != list.mList.end(); ++effectIt) { @@ -67,7 +103,7 @@ namespace MWGui for (MWMechanics::ActiveSpells::TContainer::const_iterator it = activeSpells.begin(); it != activeSpells.end(); ++it) { - ESM::EffectList list = getSpellEffectList(it->first); + const ESM::EffectList& list = getSpellEffectList(it->first); float timeScale = MWBase::Environment::get().getWorld()->getTimeScaleFactor(); From 6f05c4229f9183c04687fba5cc172bddb6e475d5 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 12:41:37 +0100 Subject: [PATCH 52/61] Implemented potion & ingredient effect stacking --- apps/openmw/mwmechanics/activespells.cpp | 32 +++++++++++++----------- apps/openmw/mwmechanics/activespells.hpp | 5 ++-- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwmechanics/activespells.cpp b/apps/openmw/mwmechanics/activespells.cpp index 933c5094d..9aca6b7b7 100644 --- a/apps/openmw/mwmechanics/activespells.cpp +++ b/apps/openmw/mwmechanics/activespells.cpp @@ -62,7 +62,7 @@ namespace MWMechanics for (TIterator iter (begin()); iter!=end(); ++iter) { - std::pair effects = getEffectList (iter->first); + std::pair > effects = getEffectList (iter->first); const MWWorld::TimeStamp& start = iter->second.first; float magnitude = iter->second.second; @@ -74,7 +74,7 @@ namespace MWMechanics { int duration = iter->mDuration; - if (effects.second) + if (effects.second.first) duration *= magnitude; MWWorld::TimeStamp end = start; @@ -85,7 +85,7 @@ namespace MWMechanics { EffectParam param; - if (effects.second) + if (effects.second.first) { const ESM::MagicEffect *magicEffect = MWBase::Environment::get().getWorld()->getStore().get().find ( @@ -113,15 +113,15 @@ namespace MWMechanics } } - std::pair ActiveSpells::getEffectList (const std::string& id) const + std::pair > ActiveSpells::getEffectList (const std::string& id) const { if (const ESM::Spell *spell = MWBase::Environment::get().getWorld()->getStore().get().search (id)) - return std::make_pair (spell->mEffects, false); + return std::make_pair (spell->mEffects, std::make_pair(false, false)); if (const ESM::Potion *potion = MWBase::Environment::get().getWorld()->getStore().get().search (id)) - return std::make_pair (potion->mEffects, false); + return std::make_pair (potion->mEffects, std::make_pair(false, true)); if (const ESM::Ingredient *ingredient = MWBase::Environment::get().getWorld()->getStore().get().search (id)) @@ -140,11 +140,12 @@ namespace MWMechanics effect.mMagnMin = 1; effect.mMagnMax = 1; - std::pair result; - + std::pair > result; + result.second.second = true; + result.second.first = true; + result.first.mList.push_back (effect); - result.second = true; - + return result; } @@ -157,7 +158,8 @@ namespace MWMechanics bool ActiveSpells::addSpell (const std::string& id, const MWWorld::Ptr& actor) { - std::pair effects = getEffectList (id); + std::pair > effects = getEffectList (id); + bool stacks = effects.second.second; bool found = false; @@ -178,7 +180,7 @@ namespace MWMechanics float random = static_cast (std::rand()) / RAND_MAX; - if (effects.second) + if (effects.second.first) { // ingredient -> special treatment required. const CreatureStats& creatureStats = MWWorld::Class::get (actor).getCreatureStats (actor); @@ -194,7 +196,7 @@ namespace MWMechanics random *= 0.25 * x; } - if (iter==mSpells.end()) + if (iter==mSpells.end() || stacks) mSpells.insert (std::make_pair (id, std::make_pair (MWBase::Environment::get().getWorld()->getTimeStamp(), random))); else @@ -236,7 +238,7 @@ namespace MWMechanics double ActiveSpells::timeToExpire (const TIterator& iterator) const { - std::pair effects = getEffectList (iterator->first); + std::pair > effects = getEffectList (iterator->first); int duration = 0; @@ -247,7 +249,7 @@ namespace MWMechanics duration = iter->mDuration; } - if (effects.second) + if (effects.second.first) duration *= iterator->second.second; double scaledDuration = duration * diff --git a/apps/openmw/mwmechanics/activespells.hpp b/apps/openmw/mwmechanics/activespells.hpp index 05aa2bbdd..8c859b2cb 100644 --- a/apps/openmw/mwmechanics/activespells.hpp +++ b/apps/openmw/mwmechanics/activespells.hpp @@ -30,7 +30,7 @@ namespace MWMechanics { public: - typedef std::map > TContainer; + typedef std::multimap > TContainer; typedef TContainer::const_iterator TIterator; private: @@ -44,7 +44,8 @@ namespace MWMechanics void rebuildEffects() const; - std::pair getEffectList (const std::string& id) const; + std::pair > getEffectList (const std::string& id) const; + ///< @return (EffectList, (isIngredient, stacks)) public: From 6037c44ea6850595bace11f5f0bde64f5ae8f31e Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 12:41:57 +0100 Subject: [PATCH 53/61] Fix ingredient effect display --- apps/openmw/mwgui/spellicons.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/openmw/mwgui/spellicons.cpp b/apps/openmw/mwgui/spellicons.cpp index dcbbed49c..16e02ebba 100644 --- a/apps/openmw/mwgui/spellicons.cpp +++ b/apps/openmw/mwgui/spellicons.cpp @@ -124,6 +124,17 @@ namespace MWGui effectInfo.mRemainingTime = effectIt->mDuration + (it->second.first - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale; + // ingredients need special casing for their magnitude / duration + /// \todo duplicated from ActiveSpells, helper function? + if (MWBase::Environment::get().getWorld()->getStore().get().search (it->first)) + { + effectInfo.mRemainingTime = effectIt->mDuration * it->second.second + + (it->second.first - MWBase::Environment::get().getWorld()->getTimeStamp())*3600/timeScale; + + effectInfo.mMagnitude = static_cast (0.05*it->second.second / (0.1 * magicEffect->mData.mBaseCost)); + } + + effects[effectIt->mEffectID].push_back (effectInfo); } } From 9a84f6744f561a4e8dd1e86d652602dae19ca330 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 13:11:02 +0100 Subject: [PATCH 54/61] Fix headers including whole MyGUI.h, forward declare where appropriate, and fix some deprecated types (WidgetPtr) --- apps/openmw/mwgui/alchemywindow.cpp | 2 +- apps/openmw/mwgui/birth.cpp | 12 +++--- apps/openmw/mwgui/birth.hpp | 4 +- apps/openmw/mwgui/class.cpp | 56 +++++++++++++------------- apps/openmw/mwgui/class.hpp | 18 ++++----- apps/openmw/mwgui/console.cpp | 4 +- apps/openmw/mwgui/console.hpp | 8 ++-- apps/openmw/mwgui/cursor.cpp | 4 +- apps/openmw/mwgui/dialogue.cpp | 6 +-- apps/openmw/mwgui/dialogue.hpp | 2 +- apps/openmw/mwgui/exposedwindow.cpp | 4 +- apps/openmw/mwgui/exposedwindow.hpp | 2 +- apps/openmw/mwgui/hud.cpp | 4 +- apps/openmw/mwgui/hud.hpp | 2 +- apps/openmw/mwgui/imagebutton.hpp | 2 +- apps/openmw/mwgui/journalwindow.hpp | 4 +- apps/openmw/mwgui/list.cpp | 5 ++- apps/openmw/mwgui/list.hpp | 7 +++- apps/openmw/mwgui/messagebox.cpp | 10 ++--- apps/openmw/mwgui/messagebox.hpp | 16 +++++--- apps/openmw/mwgui/race.cpp | 16 ++++---- apps/openmw/mwgui/race.hpp | 8 ++-- apps/openmw/mwgui/review.cpp | 6 +-- apps/openmw/mwgui/review.hpp | 2 +- apps/openmw/mwgui/stats_window.cpp | 4 +- apps/openmw/mwgui/stats_window.hpp | 4 +- apps/openmw/mwgui/text_input.cpp | 4 +- apps/openmw/mwgui/text_input.hpp | 2 +- apps/openmw/mwgui/tooltips.cpp | 4 +- apps/openmw/mwgui/widgets.cpp | 47 +++++++++++---------- apps/openmw/mwgui/widgets.hpp | 20 ++++++--- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- libs/openengine/gui/manager.cpp | 7 ++-- libs/openengine/gui/manager.hpp | 2 + 34 files changed, 164 insertions(+), 136 deletions(-) diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index db1a81c2c..fce612600 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -237,7 +237,7 @@ namespace MWGui Widgets::SpellEffectList _list = Widgets::MWEffectList::effectListFromESM(&list); effectsWidget->setEffectList(_list); - std::vector effectItems; + std::vector effectItems; effectsWidget->createEffectWidgets(effectItems, mEffectsBox, coord, false, 0); effectsWidget->setCoord(coord); } diff --git a/apps/openmw/mwgui/birth.cpp b/apps/openmw/mwgui/birth.cpp index 53e5c022d..4b07dd698 100644 --- a/apps/openmw/mwgui/birth.cpp +++ b/apps/openmw/mwgui/birth.cpp @@ -40,11 +40,11 @@ BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager) mBirthList->eventListMouseItemActivate += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); mBirthList->eventListChangePosition += MyGUI::newDelegate(this, &BirthDialog::onSelectBirth); - MyGUI::ButtonPtr backButton; + MyGUI::Button* backButton; getWidget(backButton, "BackButton"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onBackClicked); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &BirthDialog::onOkClicked); @@ -55,7 +55,7 @@ BirthDialog::BirthDialog(MWBase::WindowManager& parWindowManager) void BirthDialog::setNextButtonShow(bool shown) { - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); if (shown) @@ -82,7 +82,7 @@ void BirthDialog::setBirthId(const std::string &birthId) if (boost::iequals(*mBirthList->getItemDataAt(i), birthId)) { mBirthList->setIndexSelected(i); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); break; } @@ -110,7 +110,7 @@ void BirthDialog::onSelectBirth(MyGUI::ListBox* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); const std::string *birthId = mBirthList->getItemDataAt(_index); @@ -159,7 +159,7 @@ void BirthDialog::updateBirths() void BirthDialog::updateSpells() { - for (std::vector::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it) + for (std::vector::iterator it = mSpellItems.begin(); it != mSpellItems.end(); ++it) { MyGUI::Gui::getInstance().destroyWidget(*it); } diff --git a/apps/openmw/mwgui/birth.hpp b/apps/openmw/mwgui/birth.hpp index ad1c0b40f..d3f82dace 100644 --- a/apps/openmw/mwgui/birth.hpp +++ b/apps/openmw/mwgui/birth.hpp @@ -46,9 +46,9 @@ namespace MWGui void updateSpells(); MyGUI::ListBox* mBirthList; - MyGUI::WidgetPtr mSpellArea; + MyGUI::Widget* mSpellArea; MyGUI::ImageBox* mBirthImage; - std::vector mSpellItems; + std::vector mSpellItems; std::string mCurrentBirthId; }; diff --git a/apps/openmw/mwgui/class.cpp b/apps/openmw/mwgui/class.cpp index f3bac898b..a2f09096a 100644 --- a/apps/openmw/mwgui/class.cpp +++ b/apps/openmw/mwgui/class.cpp @@ -31,11 +31,11 @@ GenerateClassResultDialog::GenerateClassResultDialog(MWBase::WindowManager& parW getWidget(mClassImage, "ClassImage"); getWidget(mClassName, "ClassName"); - MyGUI::ButtonPtr backButton; + MyGUI::Button* backButton; getWidget(backButton, "BackButton"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onBackClicked); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &GenerateClassResultDialog::onOkClicked); @@ -97,11 +97,11 @@ PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager) getWidget(mClassImage, "ClassImage"); - MyGUI::ButtonPtr backButton; + MyGUI::Button* backButton; getWidget(backButton, "BackButton"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onBackClicked); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &PickClassDialog::onOkClicked); @@ -111,7 +111,7 @@ PickClassDialog::PickClassDialog(MWBase::WindowManager& parWindowManager) void PickClassDialog::setNextButtonShow(bool shown) { - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); if (shown) @@ -138,7 +138,7 @@ void PickClassDialog::setClassId(const std::string &classId) if (boost::iequals(*mClassList->getItemDataAt(i), classId)) { mClassList->setIndexSelected(i); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); break; } @@ -166,7 +166,7 @@ void PickClassDialog::onSelectClass(MyGUI::ListBox* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); const std::string *classId = mClassList->getItemDataAt(_index); @@ -256,7 +256,7 @@ void InfoBoxDialog::fitToText(MyGUI::TextBox* widget) widget->setSize(size); } -void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin) +void InfoBoxDialog::layoutVertically(MyGUI::Widget* widget, int margin) { size_t count = widget->getChildCount(); int pos = 0; @@ -264,7 +264,7 @@ void InfoBoxDialog::layoutVertically(MyGUI::WidgetPtr widget, int margin) int width = 0; for (unsigned i = 0; i < count; ++i) { - MyGUI::WidgetPtr child = widget->getChildAt(i); + MyGUI::Widget* child = widget->getChildAt(i); if (!child->getVisible()) continue; @@ -302,7 +302,7 @@ std::string InfoBoxDialog::getText() const void InfoBoxDialog::setButtons(ButtonList &buttons) { - for (std::vector::iterator it = this->mButtons.begin(); it != this->mButtons.end(); ++it) + for (std::vector::iterator it = this->mButtons.begin(); it != this->mButtons.end(); ++it) { MyGUI::Gui::getInstance().destroyWidget(*it); } @@ -310,7 +310,7 @@ void InfoBoxDialog::setButtons(ButtonList &buttons) mCurrentButton = -1; // TODO: The buttons should be generated from a template in the layout file, ie. cloning an existing widget - MyGUI::ButtonPtr button; + MyGUI::Button* button; MyGUI::IntCoord coord = MyGUI::IntCoord(0, 0, mButtonBar->getWidth(), 10); ButtonList::const_iterator end = buttons.end(); for (ButtonList::const_iterator it = buttons.begin(); it != end; ++it) @@ -342,11 +342,11 @@ int InfoBoxDialog::getChosenButton() const return mCurrentButton; } -void InfoBoxDialog::onButtonClicked(MyGUI::WidgetPtr _sender) +void InfoBoxDialog::onButtonClicked(MyGUI::Widget* _sender) { - std::vector::const_iterator end = mButtons.end(); + std::vector::const_iterator end = mButtons.end(); int i = 0; - for (std::vector::const_iterator it = mButtons.begin(); it != end; ++it) + for (std::vector::const_iterator it = mButtons.begin(); it != end; ++it) { if (*it == _sender) { @@ -376,10 +376,10 @@ ClassChoiceDialog::ClassChoiceDialog(MWBase::WindowManager& parWindowManager) CreateClassDialog::CreateClassDialog(MWBase::WindowManager& parWindowManager) : WindowModal("openmw_chargen_create_class.layout", parWindowManager) - , mSpecDialog(nullptr) - , mAttribDialog(nullptr) - , mSkillDialog(nullptr) - , mDescDialog(nullptr) + , mSpecDialog(NULL) + , mAttribDialog(NULL) + , mSkillDialog(NULL) + , mDescDialog(NULL) { // Centre dialog center(); @@ -420,15 +420,15 @@ CreateClassDialog::CreateClassDialog(MWBase::WindowManager& parWindowManager) // Make sure the edit box has focus MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName); - MyGUI::ButtonPtr descriptionButton; + MyGUI::Button* descriptionButton; getWidget(descriptionButton, "DescriptionButton"); descriptionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onDescriptionClicked); - MyGUI::ButtonPtr backButton; + MyGUI::Button* backButton; getWidget(backButton, "BackButton"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onBackClicked); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CreateClassDialog::onOkClicked); @@ -518,7 +518,7 @@ std::vector CreateClassDialog::getMinorSkills() const void CreateClassDialog::setNextButtonShow(bool shown) { - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); if (shown) @@ -544,7 +544,7 @@ void CreateClassDialog::onDialogCancel() mDescDialog = 0; } -void CreateClassDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) +void CreateClassDialog::onSpecializationClicked(MyGUI::Widget* _sender) { delete mSpecDialog; mSpecDialog = new SelectSpecializationDialog(mWindowManager); @@ -694,7 +694,7 @@ SelectSpecializationDialog::SelectSpecializationDialog(MWBase::WindowManager& pa ToolTips::createSpecializationToolTip(mSpecialization1, magic, ESM::Class::Magic); ToolTips::createSpecializationToolTip(mSpecialization2, stealth, ESM::Class::Stealth); - MyGUI::ButtonPtr cancelButton; + MyGUI::Button* cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSpecializationDialog::onCancelClicked); @@ -706,7 +706,7 @@ SelectSpecializationDialog::~SelectSpecializationDialog() // widget controls -void SelectSpecializationDialog::onSpecializationClicked(MyGUI::WidgetPtr _sender) +void SelectSpecializationDialog::onSpecializationClicked(MyGUI::Widget* _sender) { if (_sender == mSpecialization0) mSpecializationId = ESM::Class::Combat; @@ -747,7 +747,7 @@ SelectAttributeDialog::SelectAttributeDialog(MWBase::WindowManager& parWindowMan ToolTips::createAttributeToolTip(attribute, attribute->getAttributeId()); } - MyGUI::ButtonPtr cancelButton; + MyGUI::Button* cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectAttributeDialog::onCancelClicked); @@ -840,7 +840,7 @@ SelectSkillDialog::SelectSkillDialog(MWBase::WindowManager& parWindowManager) } } - MyGUI::ButtonPtr cancelButton; + MyGUI::Button* cancelButton; getWidget(cancelButton, "CancelButton"); cancelButton->setCaption(mWindowManager.getGameSettingString("sCancel", "")); cancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SelectSkillDialog::onCancelClicked); @@ -873,7 +873,7 @@ DescriptionDialog::DescriptionDialog(MWBase::WindowManager& parWindowManager) getWidget(mTextEdit, "TextEdit"); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DescriptionDialog::onOkClicked); okButton->setCaption(mWindowManager.getGameSettingString("sInputMenu1", "")); diff --git a/apps/openmw/mwgui/class.hpp b/apps/openmw/mwgui/class.hpp index 2662d94cc..8c60331d8 100644 --- a/apps/openmw/mwgui/class.hpp +++ b/apps/openmw/mwgui/class.hpp @@ -1,7 +1,7 @@ #ifndef MWGUI_CLASS_H #define MWGUI_CLASS_H -#include + #include "widgets.hpp" #include "window_base.hpp" @@ -35,17 +35,17 @@ namespace MWGui EventHandle_Int eventButtonSelected; protected: - void onButtonClicked(MyGUI::WidgetPtr _sender); + void onButtonClicked(MyGUI::Widget* _sender); private: void fitToText(MyGUI::TextBox* widget); - void layoutVertically(MyGUI::WidgetPtr widget, int margin); + void layoutVertically(MyGUI::Widget* widget, int margin); int mCurrentButton; - MyGUI::WidgetPtr mTextBox; + MyGUI::Widget* mTextBox; MyGUI::TextBox* mText; - MyGUI::WidgetPtr mButtonBar; - std::vector mButtons; + MyGUI::Widget* mButtonBar; + std::vector mButtons; }; // Lets the player choose between 3 ways of creating a class @@ -235,7 +235,7 @@ namespace MWGui void onOkClicked(MyGUI::Widget* _sender); private: - MyGUI::EditPtr mTextEdit; + MyGUI::EditBox* mTextEdit; }; class CreateClassDialog : public WindowModal @@ -265,7 +265,7 @@ namespace MWGui void onOkClicked(MyGUI::Widget* _sender); void onBackClicked(MyGUI::Widget* _sender); - void onSpecializationClicked(MyGUI::WidgetPtr _sender); + void onSpecializationClicked(MyGUI::Widget* _sender); void onSpecializationSelected(); void onAttributeClicked(Widgets::MWAttributePtr _sender); void onAttributeSelected(); @@ -280,7 +280,7 @@ namespace MWGui void update(); private: - MyGUI::EditPtr mEditName; + MyGUI::EditBox* mEditName; MyGUI::TextBox* mSpecializationName; Widgets::MWAttributePtr mFavoriteAttribute0, mFavoriteAttribute1; Widgets::MWSkillPtr mMajorSkill[5]; diff --git a/apps/openmw/mwgui/console.cpp b/apps/openmw/mwgui/console.cpp index b2281d87e..1aebe57da 100644 --- a/apps/openmw/mwgui/console.cpp +++ b/apps/openmw/mwgui/console.cpp @@ -216,7 +216,7 @@ namespace MWGui } } - void Console::keyPress(MyGUI::WidgetPtr _sender, + void Console::keyPress(MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char _char) { @@ -266,7 +266,7 @@ namespace MWGui } } - void Console::acceptCommand(MyGUI::EditPtr _sender) + void Console::acceptCommand(MyGUI::EditBox* _sender) { const std::string &cm = command->getCaption(); if(cm.empty()) return; diff --git a/apps/openmw/mwgui/console.hpp b/apps/openmw/mwgui/console.hpp index 1893b0148..b1d961ed2 100644 --- a/apps/openmw/mwgui/console.hpp +++ b/apps/openmw/mwgui/console.hpp @@ -55,8 +55,8 @@ namespace MWGui public: - MyGUI::EditPtr command; - MyGUI::EditPtr history; + MyGUI::EditBox* command; + MyGUI::EditBox* history; typedef std::list StringList; @@ -95,11 +95,11 @@ namespace MWGui private: - void keyPress(MyGUI::WidgetPtr _sender, + void keyPress(MyGUI::Widget* _sender, MyGUI::KeyCode key, MyGUI::Char _char); - void acceptCommand(MyGUI::EditPtr _sender); + void acceptCommand(MyGUI::EditBox* _sender); std::string complete( std::string input, std::vector &matches ); }; diff --git a/apps/openmw/mwgui/cursor.cpp b/apps/openmw/mwgui/cursor.cpp index 15f61d5b6..399695ae3 100644 --- a/apps/openmw/mwgui/cursor.cpp +++ b/apps/openmw/mwgui/cursor.cpp @@ -14,7 +14,7 @@ namespace MWGui ResourceImageSetPointerFix::ResourceImageSetPointerFix() : - mImageSet(nullptr) + mImageSet(NULL) { } @@ -50,7 +50,7 @@ namespace MWGui void ResourceImageSetPointerFix::setImage(MyGUI::ImageBox* _image) { - if (mImageSet != nullptr) + if (mImageSet != NULL) _image->setItemResourceInfo(mImageSet->getIndexInfo(0, 0)); } diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index c7918ceb7..859e3008c 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -151,7 +151,7 @@ DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager) getWidget(mTopicsList, "TopicsList"); mTopicsList->eventItemSelected += MyGUI::newDelegate(this, &DialogueWindow::onSelectTopic); - MyGUI::ButtonPtr byeButton; + MyGUI::Button* byeButton; getWidget(byeButton, "ByeButton"); byeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &DialogueWindow::onByeClicked); @@ -164,7 +164,7 @@ DialogueWindow::DialogueWindow(MWBase::WindowManager& parWindowManager) void DialogueWindow::onHistoryClicked(MyGUI::Widget* _sender) { MyGUI::ISubWidgetText* t = mHistory->getClient()->getSubWidgetText(); - if(t == nullptr) + if(t == NULL) return; const MyGUI::IntPoint& lastPressed = MyGUI::InputManager::getInstance().getLastPressedPosition(MyGUI::MouseButton::Left); @@ -381,7 +381,7 @@ std::string DialogueWindow::parseText(const std::string& text) std::vector hypertext = MWDialogue::ParseHyperText(text); size_t historySize = 0; - if(mHistory->getClient()->getSubWidgetText() != nullptr) + if(mHistory->getClient()->getSubWidgetText() != NULL) { historySize = mHistory->getOnlyText().size(); } diff --git a/apps/openmw/mwgui/dialogue.hpp b/apps/openmw/mwgui/dialogue.hpp index 5c11c311a..e39cecc3c 100644 --- a/apps/openmw/mwgui/dialogue.hpp +++ b/apps/openmw/mwgui/dialogue.hpp @@ -113,7 +113,7 @@ namespace MWGui DialogueHistory* mHistory; Widgets::MWList* mTopicsList; MyGUI::ProgressPtr mDispositionBar; - MyGUI::EditPtr mDispositionText; + MyGUI::EditBox* mDispositionText; PersuasionDialog mPersuasionDialog; diff --git a/apps/openmw/mwgui/exposedwindow.cpp b/apps/openmw/mwgui/exposedwindow.cpp index fa37568d7..150a8c893 100644 --- a/apps/openmw/mwgui/exposedwindow.cpp +++ b/apps/openmw/mwgui/exposedwindow.cpp @@ -1,7 +1,5 @@ #include "exposedwindow.hpp" -#include "MyGUI_Window.h" - namespace MWGui { MyGUI::VectorWidgetPtr ExposedWindow::getSkinWidgetsByName (const std::string &name) @@ -16,7 +14,7 @@ namespace MWGui if (widgets.empty()) { MYGUI_ASSERT( ! _throw, "widget name '" << _name << "' not found in skin of layout '" << getName() << "'"); - return nullptr; + return NULL; } else { diff --git a/apps/openmw/mwgui/exposedwindow.hpp b/apps/openmw/mwgui/exposedwindow.hpp index 906d0b406..7df2fcb35 100644 --- a/apps/openmw/mwgui/exposedwindow.hpp +++ b/apps/openmw/mwgui/exposedwindow.hpp @@ -1,7 +1,7 @@ #ifndef MWGUI_EXPOSEDWINDOW_H #define MWGUI_EXPOSEDWINDOW_H -#include "MyGUI_Window.h" +#include namespace MWGui { diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index a2c3a318b..7cb0f3924 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -2,7 +2,9 @@ #include -#include +#include +#include +#include #include diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index 013ad59f0..51dcffb09 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -60,7 +60,7 @@ namespace MWGui MyGUI::Widget* mDummy; - MyGUI::WidgetPtr mFpsBox; + MyGUI::Widget* mFpsBox; MyGUI::TextBox* mFpsCounter; MyGUI::TextBox* mTriangleCounter; MyGUI::TextBox* mBatchCounter; diff --git a/apps/openmw/mwgui/imagebutton.hpp b/apps/openmw/mwgui/imagebutton.hpp index 9fce12da1..f531e2246 100644 --- a/apps/openmw/mwgui/imagebutton.hpp +++ b/apps/openmw/mwgui/imagebutton.hpp @@ -1,7 +1,7 @@ #ifndef MWGUI_IMAGEBUTTON_H #define MWGUI_IMAGEBUTTON_H -#include "MyGUI_ImageBox.h" +#include namespace MWGui { diff --git a/apps/openmw/mwgui/journalwindow.hpp b/apps/openmw/mwgui/journalwindow.hpp index 044a2b2a4..cd1ff7ebb 100644 --- a/apps/openmw/mwgui/journalwindow.hpp +++ b/apps/openmw/mwgui/journalwindow.hpp @@ -29,8 +29,8 @@ namespace MWGui void notifyNextPage(MyGUI::Widget* _sender); void notifyPrevPage(MyGUI::Widget* _sender); - MyGUI::EditPtr mLeftTextWidget; - MyGUI::EditPtr mRightTextWidget; + MyGUI::EditBox* mLeftTextWidget; + MyGUI::EditBox* mRightTextWidget; MWGui::ImageButton* mPrevBtn; MWGui::ImageButton* mNextBtn; std::vector mLeftPages; diff --git a/apps/openmw/mwgui/list.cpp b/apps/openmw/mwgui/list.cpp index 0bafced97..d60e9b687 100644 --- a/apps/openmw/mwgui/list.cpp +++ b/apps/openmw/mwgui/list.cpp @@ -1,6 +1,9 @@ #include "list.hpp" -#include +#include +#include +#include +#include using namespace MWGui; using namespace MWGui::Widgets; diff --git a/apps/openmw/mwgui/list.hpp b/apps/openmw/mwgui/list.hpp index d07d49de6..38797e779 100644 --- a/apps/openmw/mwgui/list.hpp +++ b/apps/openmw/mwgui/list.hpp @@ -1,7 +1,12 @@ #ifndef MWGUI_LIST_HPP #define MWGUI_LIST_HPP -#include +#include + +namespace MyGUI +{ + class ScrollView; +} namespace MWGui { diff --git a/apps/openmw/mwgui/messagebox.cpp b/apps/openmw/mwgui/messagebox.cpp index 0ee042e32..b8a34c457 100644 --- a/apps/openmw/mwgui/messagebox.cpp +++ b/apps/openmw/mwgui/messagebox.cpp @@ -247,7 +247,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan std::vector::const_iterator it; for(it = buttons.begin(); it != buttons.end(); ++it) { - MyGUI::ButtonPtr button = mButtonsWidget->createWidget( + MyGUI::Button* button = mButtonsWidget->createWidget( MyGUI::WidgetStyle::Child, std::string("MW_Button"), dummyCoord, @@ -301,7 +301,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan MyGUI::IntSize buttonSize(0, buttonHeight); int left = (mainWidgetSize.width - buttonsWidth)/2 + buttonPadding; - std::vector::const_iterator button; + std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { buttonCord.left = left; @@ -349,7 +349,7 @@ InteractiveMessageBox::InteractiveMessageBox(MessageBoxManager& parMessageBoxMan int top = textButtonPadding + buttonTopPadding + textSize.height; - std::vector::const_iterator button; + std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { buttonSize.width = (*button)->getTextSize().width + buttonPadding*2; @@ -371,7 +371,7 @@ void InteractiveMessageBox::enterPressed() { std::string ok = Misc::StringUtils::lowerCase(MyGUI::LanguageManager::getInstance().replaceTags("#{sOK}")); - std::vector::const_iterator button; + std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { if(Misc::StringUtils::lowerCase((*button)->getCaption()) == ok) @@ -393,7 +393,7 @@ void InteractiveMessageBox::buttonActivated (MyGUI::Widget* pressed) { mMarkedToDelete = true; int index = 0; - std::vector::const_iterator button; + std::vector::const_iterator button; for(button = mButtons.begin(); button != mButtons.end(); ++button) { if(*button == pressed) diff --git a/apps/openmw/mwgui/messagebox.hpp b/apps/openmw/mwgui/messagebox.hpp index 4be8bc5b7..149aa7e7f 100644 --- a/apps/openmw/mwgui/messagebox.hpp +++ b/apps/openmw/mwgui/messagebox.hpp @@ -2,7 +2,6 @@ #define MWGUI_MESSAGE_BOX_H #include -#include #include "window_base.hpp" @@ -10,6 +9,13 @@ #undef MessageBox +namespace MyGUI +{ + class Widget; + class Button; + class EditBox; +} + namespace MWGui { class InteractiveMessageBox; @@ -61,7 +67,7 @@ namespace MWGui MessageBoxManager& mMessageBoxManager; int mHeight; const std::string& mMessage; - MyGUI::EditPtr mMessageWidget; + MyGUI::EditBox* mMessageWidget; int mFixedWidth; int mBottomPadding; int mNextBoxPadding; @@ -81,9 +87,9 @@ namespace MWGui void buttonActivated (MyGUI::Widget* _widget); MessageBoxManager& mMessageBoxManager; - MyGUI::EditPtr mMessageWidget; - MyGUI::WidgetPtr mButtonsWidget; - std::vector mButtons; + MyGUI::EditBox* mMessageWidget; + MyGUI::Widget* mButtonsWidget; + std::vector mButtons; int mTextButtonPadding; int mButtonPressed; diff --git a/apps/openmw/mwgui/race.cpp b/apps/openmw/mwgui/race.cpp index 71a4d1b3e..1436995c5 100644 --- a/apps/openmw/mwgui/race.cpp +++ b/apps/openmw/mwgui/race.cpp @@ -41,7 +41,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) mHeadRotate->eventScrollChangePosition += MyGUI::newDelegate(this, &RaceDialog::onHeadRotate); // Set up next/previous buttons - MyGUI::ButtonPtr prevButton, nextButton; + MyGUI::Button *prevButton, *nextButton; setText("GenderChoiceT", mWindowManager.getGameSettingString("sRaceMenu2", "Change Sex")); getWidget(prevButton, "PrevGenderButton"); @@ -73,11 +73,11 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) setText("SpellPowerT", mWindowManager.getGameSettingString("sRaceMenu7", "Specials")); getWidget(mSpellPowerList, "SpellPowerList"); - MyGUI::ButtonPtr backButton; + MyGUI::Button* backButton; getWidget(backButton, "BackButton"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onBackClicked); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->setCaption(mWindowManager.getGameSettingString("sOK", "")); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &RaceDialog::onOkClicked); @@ -89,7 +89,7 @@ RaceDialog::RaceDialog(MWBase::WindowManager& parWindowManager) void RaceDialog::setNextButtonShow(bool shown) { - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); if (shown) @@ -134,7 +134,7 @@ void RaceDialog::setRaceId(const std::string &raceId) if (boost::iequals(*mRaceList->getItemDataAt(i), raceId)) { mRaceList->setIndexSelected(i); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); break; } @@ -256,7 +256,7 @@ void RaceDialog::onSelectRace(MyGUI::ListBox* _sender, size_t _index) if (_index == MyGUI::ITEM_NONE) return; - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); const std::string *raceId = mRaceList->getItemDataAt(_index); if (boost::iequals(mCurrentRaceId, *raceId)) @@ -331,7 +331,7 @@ void RaceDialog::updateRaces() void RaceDialog::updateSkills() { - for (std::vector::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it) + for (std::vector::iterator it = mSkillItems.begin(); it != mSkillItems.end(); ++it) { MyGUI::Gui::getInstance().destroyWidget(*it); } @@ -369,7 +369,7 @@ void RaceDialog::updateSkills() void RaceDialog::updateSpellPowers() { - for (std::vector::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it) + for (std::vector::iterator it = mSpellPowerItems.begin(); it != mSpellPowerItems.end(); ++it) { MyGUI::Gui::getInstance().destroyWidget(*it); } diff --git a/apps/openmw/mwgui/race.hpp b/apps/openmw/mwgui/race.hpp index 619556906..efd08f439 100644 --- a/apps/openmw/mwgui/race.hpp +++ b/apps/openmw/mwgui/race.hpp @@ -85,11 +85,11 @@ namespace MWGui MyGUI::ListBox* mRaceList; MyGUI::ScrollBar* mHeadRotate; - MyGUI::WidgetPtr mSkillList; - std::vector mSkillItems; + MyGUI::Widget* mSkillList; + std::vector mSkillItems; - MyGUI::WidgetPtr mSpellPowerList; - std::vector mSpellPowerItems; + MyGUI::Widget* mSpellPowerList; + std::vector mSpellPowerItems; int mGenderIndex, mFaceIndex, mHairIndex; int mFaceCount, mHairCount; diff --git a/apps/openmw/mwgui/review.cpp b/apps/openmw/mwgui/review.cpp index 50dc26e42..50508cc5f 100644 --- a/apps/openmw/mwgui/review.cpp +++ b/apps/openmw/mwgui/review.cpp @@ -86,11 +86,11 @@ ReviewDialog::ReviewDialog(MWBase::WindowManager& parWindowManager) mSkillWidgetMap.insert(std::make_pair(i, static_cast (0))); } - MyGUI::ButtonPtr backButton; + MyGUI::Button* backButton; getWidget(backButton, "BackButton"); backButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onBackClicked); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &ReviewDialog::onOkClicked); } @@ -309,7 +309,7 @@ void ReviewDialog::addSkills(const SkillList &skills, const std::string &titleId void ReviewDialog::updateSkillArea() { - for (std::vector::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it) + for (std::vector::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it) { MyGUI::Gui::getInstance().destroyWidget(*it); } diff --git a/apps/openmw/mwgui/review.hpp b/apps/openmw/mwgui/review.hpp index aac609a64..4f41ec42d 100644 --- a/apps/openmw/mwgui/review.hpp +++ b/apps/openmw/mwgui/review.hpp @@ -91,7 +91,7 @@ namespace MWGui std::map mSkillWidgetMap; std::string mName, mRaceId, mBirthSignId; ESM::Class mKlass; - std::vector mSkillWidgets; //< Skills and other information + std::vector mSkillWidgets; //< Skills and other information }; } #endif diff --git a/apps/openmw/mwgui/stats_window.cpp b/apps/openmw/mwgui/stats_window.cpp index 70ceed857..0fa4127b5 100644 --- a/apps/openmw/mwgui/stats_window.cpp +++ b/apps/openmw/mwgui/stats_window.cpp @@ -67,7 +67,7 @@ StatsWindow::StatsWindow (MWBase::WindowManager& parWindowManager) for (int i = 0; i < ESM::Skill::Length; ++i) { mSkillValues.insert(std::pair >(i, MWMechanics::Stat())); - mSkillWidgetMap.insert(std::pair(i, (MyGUI::TextBox*)nullptr)); + mSkillWidgetMap.insert(std::pair(i, (MyGUI::TextBox*)NULL)); } MyGUI::WindowPtr t = static_cast(mMainWidget); @@ -419,7 +419,7 @@ void StatsWindow::updateSkillArea() { mChanged = false; - for (std::vector::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it) + for (std::vector::iterator it = mSkillWidgets.begin(); it != mSkillWidgets.end(); ++it) { MyGUI::Gui::getInstance().destroyWidget(*it); } diff --git a/apps/openmw/mwgui/stats_window.hpp b/apps/openmw/mwgui/stats_window.hpp index 6619680fa..3befc1f00 100644 --- a/apps/openmw/mwgui/stats_window.hpp +++ b/apps/openmw/mwgui/stats_window.hpp @@ -67,11 +67,11 @@ namespace MWGui SkillList mMajorSkills, mMinorSkills, mMiscSkills; std::map > mSkillValues; std::map mSkillWidgetMap; - std::map mFactionWidgetMap; + std::map mFactionWidgetMap; FactionList mFactions; ///< Stores a list of factions and the current rank std::string mBirthSignId; int mReputation, mBounty; - std::vector mSkillWidgets; //< Skills and other information + std::vector mSkillWidgets; //< Skills and other information std::set mExpelled; bool mChanged; diff --git a/apps/openmw/mwgui/text_input.cpp b/apps/openmw/mwgui/text_input.cpp index c19394833..9265cadf9 100644 --- a/apps/openmw/mwgui/text_input.cpp +++ b/apps/openmw/mwgui/text_input.cpp @@ -13,7 +13,7 @@ TextInputDialog::TextInputDialog(MWBase::WindowManager& parWindowManager) getWidget(mTextEdit, "TextEdit"); mTextEdit->eventEditSelectAccept += newDelegate(this, &TextInputDialog::onTextAccepted); - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); @@ -23,7 +23,7 @@ TextInputDialog::TextInputDialog(MWBase::WindowManager& parWindowManager) void TextInputDialog::setNextButtonShow(bool shown) { - MyGUI::ButtonPtr okButton; + MyGUI::Button* okButton; getWidget(okButton, "OKButton"); if (shown) diff --git a/apps/openmw/mwgui/text_input.hpp b/apps/openmw/mwgui/text_input.hpp index 649990281..29de7388b 100644 --- a/apps/openmw/mwgui/text_input.hpp +++ b/apps/openmw/mwgui/text_input.hpp @@ -30,7 +30,7 @@ namespace MWGui void onTextAccepted(MyGUI::Edit* _sender); private: - MyGUI::EditPtr mTextEdit; + MyGUI::EditBox* mTextEdit; }; } #endif diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index c7acf568d..261a7f8bd 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -439,7 +439,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) effectsWidget->setWindowManager(mWindowManager); effectsWidget->setEffectList(info.effects); - std::vector effectItems; + std::vector effectItems; effectsWidget->createEffectWidgets(effectItems, effectArea, coord, true, info.isPotion ? Widgets::MWEffectList::EF_NoTarget : 0); totalSize.height += coord.top-6; totalSize.width = std::max(totalSize.width, coord.width); @@ -459,7 +459,7 @@ IntSize ToolTips::createToolTip(const MWGui::ToolTipInfo& info) enchantWidget->setWindowManager(mWindowManager); enchantWidget->setEffectList(Widgets::MWEffectList::effectListFromESM(&enchant->mEffects)); - std::vector enchantEffectItems; + std::vector enchantEffectItems; int flag = (enchant->mData.mType == ESM::Enchantment::ConstantEffect) ? Widgets::MWEffectList::EF_Constant : 0; enchantWidget->createEffectWidgets(enchantEffectItems, enchantArea, coord, true, flag); totalSize.height += coord.top-6; diff --git a/apps/openmw/mwgui/widgets.cpp b/apps/openmw/mwgui/widgets.cpp index f932c1f03..8857ecfa3 100644 --- a/apps/openmw/mwgui/widgets.cpp +++ b/apps/openmw/mwgui/widgets.cpp @@ -2,6 +2,9 @@ #include +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/windowmanager.hpp" @@ -31,10 +34,10 @@ void MWGui::Widgets::fixTexturePath(std::string &path) /* MWSkill */ MWSkill::MWSkill() - : mManager(nullptr) + : mManager(NULL) , mSkillId(ESM::Skill::Length) - , mSkillNameWidget(nullptr) - , mSkillValueWidget(nullptr) + , mSkillNameWidget(NULL) + , mSkillValueWidget(NULL) { } @@ -103,7 +106,7 @@ void MWSkill::initialiseOverride() assignWidget(mSkillNameWidget, "StatName"); assignWidget(mSkillValueWidget, "StatValue"); - MyGUI::ButtonPtr button; + MyGUI::Button* button; assignWidget(button, "StatNameButton"); if (button) { @@ -123,10 +126,10 @@ void MWSkill::initialiseOverride() /* MWAttribute */ MWAttribute::MWAttribute() - : mManager(nullptr) + : mManager(NULL) , mId(-1) - , mAttributeNameWidget(nullptr) - , mAttributeValueWidget(nullptr) + , mAttributeNameWidget(NULL) + , mAttributeValueWidget(NULL) { } @@ -195,7 +198,7 @@ void MWAttribute::initialiseOverride() assignWidget(mAttributeNameWidget, "StatName"); assignWidget(mAttributeValueWidget, "StatValue"); - MyGUI::ButtonPtr button; + MyGUI::Button* button; assignWidget(button, "StatNameButton"); if (button) { @@ -215,8 +218,8 @@ void MWAttribute::initialiseOverride() /* MWSpell */ MWSpell::MWSpell() - : mWindowManager(nullptr) - , mSpellNameWidget(nullptr) + : mWindowManager(NULL) + , mSpellNameWidget(NULL) { } @@ -226,7 +229,7 @@ void MWSpell::setSpellId(const std::string &spellId) updateWidgets(); } -void MWSpell::createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags) +void MWSpell::createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags) { const MWWorld::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); @@ -234,7 +237,7 @@ void MWSpell::createEffectWidgets(std::vector &effects, MyGUI: const ESM::Spell *spell = store.get().search(mId); MYGUI_ASSERT(spell, "spell with id '" << mId << "' not found"); - MWSpellEffectPtr effect = nullptr; + MWSpellEffectPtr effect = NULL; std::vector::const_iterator end = spell->mEffects.mList.end(); for (std::vector::const_iterator it = spell->mEffects.mList.begin(); it != end; ++it) { @@ -286,7 +289,7 @@ MWSpell::~MWSpell() /* MWEffectList */ MWEffectList::MWEffectList() - : mWindowManager(nullptr) + : mWindowManager(NULL) , mEffectList(0) { } @@ -297,11 +300,11 @@ void MWEffectList::setEffectList(const SpellEffectList& list) updateWidgets(); } -void MWEffectList::createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags) +void MWEffectList::createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags) { // We don't know the width of all the elements beforehand, so we do it in // 2 steps: first, create all widgets and check their width.... - MWSpellEffectPtr effect = nullptr; + MWSpellEffectPtr effect = NULL; int maxwidth = coord.width; for (SpellEffectList::iterator it=mEffectList.begin(); @@ -320,7 +323,7 @@ void MWEffectList::createEffectWidgets(std::vector &effects, M } // ... then adjust the size for all widgets - for (std::vector::iterator it = effects.begin(); it != effects.end(); ++it) + for (std::vector::iterator it = effects.begin(); it != effects.end(); ++it) { effect = static_cast(*it); bool needcenter = center && (maxwidth > effect->getRequestedWidth()); @@ -375,9 +378,9 @@ SpellEffectList MWEffectList::effectListFromESM(const ESM::EffectList* effects) /* MWSpellEffect */ MWSpellEffect::MWSpellEffect() - : mWindowManager(nullptr) - , mImageWidget(nullptr) - , mTextWidget(nullptr) + : mWindowManager(NULL) + , mImageWidget(NULL) + , mTextWidget(NULL) , mRequestedWidth(0) { } @@ -495,9 +498,9 @@ void MWSpellEffect::initialiseOverride() MWDynamicStat::MWDynamicStat() : mValue(0) , mMax(1) -, mTextWidget(nullptr) -, mBarWidget(nullptr) -, mBarTextWidget(nullptr) +, mTextWidget(NULL) +, mBarWidget(NULL) +, mBarTextWidget(NULL) { } diff --git a/apps/openmw/mwgui/widgets.hpp b/apps/openmw/mwgui/widgets.hpp index 7cbb5e53a..597bcbe32 100644 --- a/apps/openmw/mwgui/widgets.hpp +++ b/apps/openmw/mwgui/widgets.hpp @@ -2,10 +2,16 @@ #define MWGUI_WIDGETS_H #include "../mwworld/esmstore.hpp" +#include "../mwmechanics/stat.hpp" -#include +#include +#include +#include -#include "../mwmechanics/stat.hpp" +namespace MyGUI +{ + class ImageBox; +} namespace MWBase { @@ -118,7 +124,8 @@ namespace MWGui MWBase::WindowManager *mManager; ESM::Skill::SkillEnum mSkillId; SkillValue mValue; - MyGUI::WidgetPtr mSkillNameWidget, mSkillValueWidget; + MyGUI::Widget* mSkillNameWidget; + MyGUI::Widget* mSkillValueWidget; }; typedef MWSkill* MWSkillPtr; @@ -160,7 +167,8 @@ namespace MWGui MWBase::WindowManager *mManager; int mId; AttributeValue mValue; - MyGUI::WidgetPtr mAttributeNameWidget, mAttributeValueWidget; + MyGUI::Widget* mAttributeNameWidget; + MyGUI::Widget* mAttributeValueWidget; }; typedef MWAttribute* MWAttributePtr; @@ -186,7 +194,7 @@ namespace MWGui * @param spell category, if this is 0, this means the spell effects are permanent and won't display e.g. duration * @param various flags, see MWEffectList::EffectFlags */ - void createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, int flags); + void createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, int flags); const std::string &getSpellId() const { return mId; } @@ -230,7 +238,7 @@ namespace MWGui * @param center the effect widgets horizontally * @param various flags, see MWEffectList::EffectFlags */ - void createEffectWidgets(std::vector &effects, MyGUI::WidgetPtr creator, MyGUI::IntCoord &coord, bool center, int flags); + void createEffectWidgets(std::vector &effects, MyGUI::Widget* creator, MyGUI::IntCoord &coord, bool center, int flags); protected: virtual ~MWEffectList(); diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1138f62fa..7d5b6af6e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -3,7 +3,7 @@ #include #include -#include "MyGUI_UString.h" +#include #include #include diff --git a/libs/openengine/gui/manager.cpp b/libs/openengine/gui/manager.cpp index e5a164b81..07fbafa7d 100644 --- a/libs/openengine/gui/manager.cpp +++ b/libs/openengine/gui/manager.cpp @@ -1,8 +1,9 @@ -#include +#include "manager.hpp" + +#include #include -#include -#include "manager.hpp" +#include using namespace OEngine::GUI; diff --git a/libs/openengine/gui/manager.hpp b/libs/openengine/gui/manager.hpp index c0f98da88..9443fba01 100644 --- a/libs/openengine/gui/manager.hpp +++ b/libs/openengine/gui/manager.hpp @@ -1,6 +1,8 @@ #ifndef OENGINE_MYGUI_MANAGER_H #define OENGINE_MYGUI_MANAGER_H +#include + namespace MyGUI { class Gui; From ac0a23a68d644610789f00ad1912f5443aa88937 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 14:53:47 +0100 Subject: [PATCH 55/61] Fix initialization problem --- files/materials/objects.shader | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 88ca2d152..6495b0cb4 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -146,7 +146,7 @@ #if VERTEX_LIGHTING float3 lightDir; float d; - + lightResult = float3(0,0,0); @shForeach(@shGlobalSettingString(num_lights)) lightDir = lightPosition[@shIterator].xyz - (shInputPosition.xyz * lightPosition[@shIterator].w); d = length(lightDir); From 11f21a19886fdb010fe6f67c1c42ececb95ee4b6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 15:10:40 +0100 Subject: [PATCH 56/61] Weather update should be before renderer update --- apps/openmw/mwworld/worldimp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index f8efcdbd4..cddcda68b 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -974,6 +974,8 @@ namespace MWWorld void World::update (float duration, bool paused) { + mWeatherManager->update (duration); + mWorldScene->update (duration, paused); float pitch, yaw; @@ -981,8 +983,6 @@ namespace MWWorld mRendering->getPlayerData(eyepos, pitch, yaw); mPhysics->updatePlayerData(eyepos, pitch, yaw); - mWeatherManager->update (duration); - performUpdateSceneQueries (); updateWindowManager (); From 867b22ce19cad53e4e5ba3aaf9f2826b7273fe43 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 15:11:19 +0100 Subject: [PATCH 57/61] Fix a terrain glitch --- apps/openmw/mwrender/terrain.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwrender/terrain.cpp b/apps/openmw/mwrender/terrain.cpp index 212dd94c3..438366873 100644 --- a/apps/openmw/mwrender/terrain.cpp +++ b/apps/openmw/mwrender/terrain.cpp @@ -42,7 +42,8 @@ namespace MWRender // We don't want any pixel error at all. Really, LOD makes no sense here - morrowind uses 65x65 verts in one cell, // so applying LOD is most certainly slower than doing no LOD at all. - mTerrainGlobals->setMaxPixelError(0); + // Setting this to 0 seems to cause glitches though. :/ + mTerrainGlobals->setMaxPixelError(1); mTerrainGlobals->setLayerBlendMapSize(32); From 002830e13bc8ce0f9a882b9b225959f3cbfb2120 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 15:11:45 +0100 Subject: [PATCH 58/61] Make sure render textures are inactive when in a cell without water --- apps/openmw/mwrender/refraction.cpp | 5 +++++ apps/openmw/mwrender/refraction.hpp | 1 + apps/openmw/mwrender/water.cpp | 6 ++++-- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index 15575362b..bb2d88865 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -99,4 +99,9 @@ namespace MWRender } } + void Refraction::setActive(bool active) + { + mRenderTarget->setActive(active); + } + } diff --git a/apps/openmw/mwrender/refraction.hpp b/apps/openmw/mwrender/refraction.hpp index de47d6e43..b9ab8deac 100644 --- a/apps/openmw/mwrender/refraction.hpp +++ b/apps/openmw/mwrender/refraction.hpp @@ -25,6 +25,7 @@ namespace MWRender void preRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void postRenderTargetUpdate(const Ogre::RenderTargetEvent& evt); void setUnderwater(bool underwater) {mIsUnderwater = underwater;} + void setActive (bool active); void renderQueueStarted (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &skipThisInvocation); void renderQueueEnded (Ogre::uint8 queueGroupId, const Ogre::String &invocation, bool &repeatThisInvocation); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index d112e17b2..c116a6384 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -372,9 +372,9 @@ void Water::updateVisible() { mWater->setVisible(mToggled && mActive); if (mReflection) - { mReflection->setActive(mToggled && mActive); - } + if (mRefraction) + mRefraction->setActive(mToggled && mActive); } void Water::update(float dt, Ogre::Vector3 player) @@ -424,6 +424,8 @@ void Water::applyRTT() mRefraction = new Refraction(mCamera); mRefraction->setHeight(mTop); } + + updateVisible(); } void Water::applyVisibilityMask() From f0e3463e9bb636e303b5d77834848f058e8b715a Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 16:50:10 +0100 Subject: [PATCH 59/61] Disable assertion for comparing iterators from different containers (Bug #605) --- apps/openmw/mwworld/containerstore.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/containerstore.cpp b/apps/openmw/mwworld/containerstore.cpp index eb2a14d5b..8a7884e9e 100644 --- a/apps/openmw/mwworld/containerstore.cpp +++ b/apps/openmw/mwworld/containerstore.cpp @@ -548,7 +548,8 @@ MWWorld::ContainerStoreIterator MWWorld::ContainerStoreIterator::operator++ (int bool MWWorld::ContainerStoreIterator::isEqual (const ContainerStoreIterator& iter) const { - assert (mContainer==iter.mContainer); + if (mContainer!=iter.mContainer) + return false; if (mType!=iter.mType) return false; From c9fefc7f5d245541c5d24def1e26ac7bb3cd8776 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 19:28:11 +0100 Subject: [PATCH 60/61] Simpler, more lightweight underwater effect, changed colors to match vanilla better --- apps/openmw/mwgui/settingswindow.cpp | 13 ----- apps/openmw/mwgui/settingswindow.hpp | 1 - apps/openmw/mwrender/renderconst.hpp | 3 ++ apps/openmw/mwrender/renderingmanager.cpp | 40 ++++++--------- apps/openmw/mwrender/renderingmanager.hpp | 2 +- apps/openmw/mwrender/videoplayer.cpp | 6 ++- apps/openmw/mwrender/water.cpp | 24 --------- apps/openmw/mwrender/water.hpp | 3 +- files/CMakeLists.txt | 1 - files/materials/objects.shader | 58 ++++------------------ files/materials/openmw.configuration | 1 + files/materials/terrain.shader | 55 ++------------------ files/materials/underwater.h | 4 +- files/materials/water.mat | 8 --- files/materials/water.shader | 30 ++--------- files/mygui/openmw_settings_window.layout | 7 --- files/settings-default.cfg | 2 - files/water/underwater_dome.mesh | Bin 22585 -> 0 bytes 18 files changed, 46 insertions(+), 212 deletions(-) delete mode 100644 files/water/underwater_dome.mesh diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index ebeb42ab2..04856c3ed 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -129,7 +129,6 @@ namespace MWGui getWidget(mStaticsShadows, "StaticsShadows"); getWidget(mMiscShadows, "MiscShadows"); getWidget(mShadowsDebug, "ShadowsDebug"); - getWidget(mUnderwaterButton, "UnderwaterButton"); getWidget(mControlsBox, "ControlsBox"); getWidget(mResetControlsButton, "ResetControlsButton"); getWidget(mInvertYButton, "InvertYButton"); @@ -141,7 +140,6 @@ namespace MWGui mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); - mUnderwaterButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled); mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled); mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); @@ -236,7 +234,6 @@ namespace MWGui mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}"); mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}"); mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}"); - mUnderwaterButton->setCaptionWithReplacing(Settings::Manager::getBool("underwater effect", "Water") ? "#{sOn}" : "#{sOff}"); mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows")); //mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}"); @@ -267,7 +264,6 @@ namespace MWGui if (!Settings::Manager::getBool("shaders", "Objects")) { mRefractionButton->setEnabled(false); - mUnderwaterButton->setEnabled (false); mShadowsEnabledButton->setEnabled(false); } @@ -389,10 +385,6 @@ namespace MWGui Settings::Manager::setBool("shader", "Water", newState); else if (_sender == mRefractionButton) Settings::Manager::setBool("refraction", "Water", newState); - else if (_sender == mUnderwaterButton) - { - Settings::Manager::setBool("underwater effect", "Water", newState); - } else if (_sender == mReflectObjectsButton) { Settings::Manager::setBool("reflect misc", "Water", newState); @@ -459,10 +451,6 @@ namespace MWGui { Settings::Manager::setBool("shaders", "Objects", false); - mUnderwaterButton->setCaptionWithReplacing("#{sOff}"); - - mUnderwaterButton->setEnabled(false); - // refraction needs shaders to display underwater fog mRefractionButton->setCaptionWithReplacing("#{sOff}"); mRefractionButton->setEnabled(false); @@ -485,7 +473,6 @@ namespace MWGui mReflectTerrainButton->setEnabled(true); mRefractionButton->setEnabled(true); - mUnderwaterButton->setEnabled(true); mShadowsEnabledButton->setEnabled(true); } diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 55cc0a870..fc1ec9e36 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -50,7 +50,6 @@ namespace MWGui MyGUI::Button* mReflectTerrainButton; MyGUI::Button* mShadersButton; MyGUI::Button* mShaderModeButton; - MyGUI::Button* mUnderwaterButton; MyGUI::Button* mRefractionButton; MyGUI::Button* mShadowsEnabledButton; diff --git a/apps/openmw/mwrender/renderconst.hpp b/apps/openmw/mwrender/renderconst.hpp index cc3cbee29..1d2cdf1ea 100644 --- a/apps/openmw/mwrender/renderconst.hpp +++ b/apps/openmw/mwrender/renderconst.hpp @@ -56,6 +56,9 @@ enum VisibilityFlags RV_Debug = 512, + // overlays, we only want these on the main render target + RV_Overlay = 1024, + 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 943208a66..c8b5926d9 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -133,8 +133,8 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const sh::Factory::getInstance ().setGlobalSetting ("lighting", "true"); sh::Factory::getInstance ().setGlobalSetting ("num_lights", Settings::Manager::getString ("num lights", "Objects")); sh::Factory::getInstance ().setGlobalSetting ("terrain_num_lights", Settings::Manager::getString ("num lights", "Terrain")); - sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); sh::Factory::getInstance ().setGlobalSetting ("simple_water", Settings::Manager::getBool("shader", "Water") ? "false" : "true"); + sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false"); sh::Factory::getInstance ().setSharedParameter ("waterEnabled", sh::makeProperty (new sh::FloatValue(0.0))); sh::Factory::getInstance ().setSharedParameter ("waterLevel", sh::makeProperty(new sh::FloatValue(0))); @@ -355,16 +355,7 @@ void RenderingManager::update (float duration, bool paused) Ogre::ControllerManager::getSingleton().setTimeFactor(paused ? 0.f : 1.f); - /* - if (world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam)) - { - mFogColour = Ogre::ColourValue(0.18039, 0.23137, 0.25490); - mFogStart = 0; - mFogEnd = 1500; - } - */ - - applyFog(); + applyFog(world->isUnderwater (world->getPlayer().getPlayer().getCell(), cam)); if(paused) { @@ -529,16 +520,20 @@ void RenderingManager::configureFog(const float density, const Ogre::ColourValue mRendering.getCamera()->setFarClipDistance ( Settings::Manager::getFloat("max viewing distance", "Viewing distance") / density ); } -void RenderingManager::applyFog () +void RenderingManager::applyFog (bool underwater) { - mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd); - - mRendering.getViewport()->setBackgroundColour (mFogColour); - - mWater->setViewportBackground (mFogColour); - - sh::Factory::getInstance ().setSharedParameter ("viewportBackground", - sh::makeProperty (new sh::Vector3(mFogColour.r, mFogColour.g, mFogColour.b))); + if (!underwater) + { + mRendering.getScene()->setFog (FOG_LINEAR, mFogColour, 0, mFogStart, mFogEnd); + mRendering.getViewport()->setBackgroundColour (mFogColour); + mWater->setViewportBackground (mFogColour); + } + else + { + mRendering.getScene()->setFog (FOG_LINEAR, Ogre::ColourValue(0.18039, 0.23137, 0.25490), 0, 0, 1000); + mRendering.getViewport()->setBackgroundColour (Ogre::ColourValue(0.18039, 0.23137, 0.25490)); + mWater->setViewportBackground (Ogre::ColourValue(0.18039, 0.23137, 0.25490)); + } } void RenderingManager::setAmbientMode() @@ -784,11 +779,6 @@ void RenderingManager::processChangedSettings(const Settings::CategorySettingVec sh::Factory::getInstance ().setGlobalSetting ("refraction", Settings::Manager::getBool("refraction", "Water") ? "true" : "false"); rebuild = true; } - else if (it->second == "underwater effect" && it->first == "Water") - { - sh::Factory::getInstance ().setGlobalSetting ("underwater_effects", Settings::Manager::getString("underwater effect", "Water")); - rebuild = true; - } else if (it->second == "shaders" && it->first == "Objects") { sh::Factory::getInstance ().setShadersEnabled (Settings::Manager::getBool("shaders", "Objects")); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 02d796fdd..49cde25a3 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -208,7 +208,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList sh::Factory* mFactory; void setAmbientMode(); - void applyFog(); + void applyFog(bool underwater); void setMenuTransparency(float val); diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index a0dedb6bc..2cbc85cd3 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -17,6 +17,8 @@ #include "../mwsound/sound_decoder.hpp" #include "../mwsound/sound.hpp" +#include "renderconst.hpp" + #ifdef _WIN32 #include @@ -1067,9 +1069,9 @@ VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr) mBackgroundNode->attachObject(mBackgroundRectangle); mRectangle->setVisible(false); - mRectangle->setVisibilityFlags(0x1); + mRectangle->setVisibilityFlags(RV_Overlay); mBackgroundRectangle->setVisible(false); - mBackgroundRectangle->setVisibilityFlags(0x1); + mBackgroundRectangle->setVisibilityFlags(RV_Overlay); } VideoPlayer::~VideoPlayer() diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index c116a6384..49836535f 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -4,14 +4,10 @@ #include #include #include -#include -#include -#include #include #include "sky.hpp" #include "renderingmanager.hpp" -#include "compositors.hpp" #include "ripplesimulation.hpp" #include "refraction.hpp" @@ -224,16 +220,6 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend) : mWater->setMaterial(mMaterial); - /* - Ogre::Entity* underwaterDome = mSceneManager->createEntity ("underwater_dome.mesh"); - underwaterDome->setRenderQueueGroup (RQG_UnderWater); - mUnderwaterDome = mSceneManager->getRootSceneNode ()->createChildSceneNode (); - mUnderwaterDome->attachObject (underwaterDome); - mUnderwaterDome->setScale(10000,10000,10000); - mUnderwaterDome->setVisible(false); - underwaterDome->setMaterialName("Underwater_Dome"); - */ - setHeight(mTop); sh::MaterialInstance* m = sh::Factory::getInstance ().getMaterialInstance ("Water"); @@ -379,21 +365,11 @@ void Water::updateVisible() void Water::update(float dt, Ogre::Vector3 player) { - /* - Ogre::Vector3 pos = mCamera->getDerivedPosition (); - pos.y = -mWaterPlane.d; - mUnderwaterDome->setPosition (pos); - */ - mWaterTimer += dt; sh::Factory::getInstance ().setSharedParameter ("waterTimer", sh::makeProperty(new sh::FloatValue(mWaterTimer))); mRendering->getSkyManager ()->setGlareEnabled (!mIsUnderwater); - //if (player.y <= mTop) - { - //mSimulation->addImpulse(Ogre::Vector2(player.x, player.z)); - } mSimulation->update(dt, Ogre::Vector2(player.x, player.y)); if (mReflection) diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index ddf6ef7ab..633a30664 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -25,6 +25,7 @@ namespace Ogre class SceneNode; class Entity; class Vector3; + class Rectangle2D; struct RenderTargetEvent; } @@ -108,8 +109,6 @@ namespace MWRender { Ogre::SceneNode *mWaterNode; Ogre::Entity *mWater; - //Ogre::SceneNode* mUnderwaterDome; - bool mIsUnderwater; bool mActive; bool mToggled; diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index c29d917b8..9e65b516b 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -1,7 +1,6 @@ project(resources) set(WATER_FILES - underwater_dome.mesh water_nm.png circle.png ) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 6495b0cb4..37ff17843 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -16,7 +16,7 @@ #endif -#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING +#define UNDERWATER @shGlobalSettingBool(render_refraction) #define HAS_VERTEXCOLOR @shPropertyBool(has_vertex_colour) @@ -242,18 +242,8 @@ #endif #if UNDERWATER - - shUniform(float, waterLevel) @shSharedParameter(waterLevel) - - shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0) - - shSampler2D(causticMap) - - shUniform(float, waterTimer) @shSharedParameter(waterTimer) - shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight) + shUniform(float, waterLevel) @shSharedParameter(waterLevel) shUniform(float, waterEnabled) @shSharedParameter(waterEnabled) - - shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed) #endif #if VERTEX_LIGHTING @@ -305,13 +295,7 @@ #endif #if UNDERWATER - float3 waterEyePos = float3(1,1,1); - // NOTE: this calculation would be wrong for non-uniform scaling - float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); - waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel); - caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed); - if (worldPos.z >= waterLevel || waterEnabled != 1.f) - caustics = float3(1,1,1); + float3 waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel); #endif #if !VERTEX_LIGHTING @@ -358,41 +342,17 @@ #if FOG float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); - #if UNDERWATER - // regular fog only if fragment is above water - if (worldPos.z > waterLevel || waterEnabled != 1.f) - #endif + +#if UNDERWATER + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, UNDERWATER_COLOUR, shSaturate(length(waterEyePos-worldPos) / VISIBILITY)); +#else shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); +#endif + #endif // prevent negative colour output (for example with negative lights) shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0)); - -#if UNDERWATER - float fogAmount = (cameraPos.z > waterLevel) - ? shSaturate(length(waterEyePos-worldPos) / VISIBILITY) - : shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY); - - float3 eyeVec = normalize(cameraPos.xyz-worldPos); - - float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); - waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = float3(0.0,1.0,0.85) *waterSunGradient * 0.5; - - float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); - waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = ( float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; - watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); - watercolour = (cameraPos.z <= waterLevel) ? watercolour : watercolour*0.3; - - - float darkness = VISIBILITY*2.0; - darkness = clamp((waterEyePos.z - waterLevel + darkness)/darkness,0.2,1.0); - watercolour *= darkness; - - float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0; - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater * waterEnabled); -#endif } #endif diff --git a/files/materials/openmw.configuration b/files/materials/openmw.configuration index 21ac9416b..b953a9131 100644 --- a/files/materials/openmw.configuration +++ b/files/materials/openmw.configuration @@ -8,6 +8,7 @@ configuration water_reflection configuration water_refraction { viewproj_fix true + render_refraction true } configuration local_map diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index ea54bb24c..af5be42cd 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -21,7 +21,7 @@ #define NEED_DEPTH 1 #endif -#define UNDERWATER @shGlobalSettingBool(underwater_effects) && LIGHTING +#define UNDERWATER @shGlobalSettingBool(render_refraction) #define VIEWPROJ_FIX @shGlobalSettingBool(viewproj_fix) @@ -210,14 +210,6 @@ #if UNDERWATER shUniform(float, waterLevel) @shSharedParameter(waterLevel) - shUniform(float4, lightDirectionWS0) @shAutoConstant(lightDirectionWS0, light_position, 0) - - shSampler2D(causticMap) - - shUniform(float, waterTimer) @shSharedParameter(waterTimer) - shUniform(float2, waterSunFade_sunHeight) @shSharedParameter(waterSunFade_sunHeight) - - shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed) #endif @@ -242,17 +234,7 @@ float3 caustics = float3(1,1,1); #if UNDERWATER - - float3 waterEyePos = float3(1,1,1); - // NOTE: this calculation would be wrong for non-uniform scaling - float4 worldNormal = shMatrixMult(worldMatrix, float4(normal.xyz, 0)); - waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel); - caustics = getCaustics(causticMap, worldPos, waterEyePos.xyz, worldNormal.xyz, lightDirectionWS0.xyz, waterLevel, waterTimer, windDir_windSpeed); - if (worldPos.z >= waterLevel) - caustics = float3(1,1,1); - - - + float3 waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel); #endif @@ -353,41 +335,14 @@ float fogValue = shSaturate((depth - fogParams.y) * fogParams.w); #if UNDERWATER - // regular fog only if fragment is above water - if (worldPos.z > waterLevel) - #endif + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, UNDERWATER_COLOUR, shSaturate(length(waterEyePos-worldPos) / VISIBILITY)); + #else shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColour, fogValue); + #endif #endif // prevent negative colour output (for example with negative lights) shOutputColour(0).xyz = max(shOutputColour(0).xyz, float3(0,0,0)); - -#if UNDERWATER - float fogAmount = (cameraPos.z > waterLevel) - ? shSaturate(length(waterEyePos-worldPos) / VISIBILITY) - : shSaturate(length(cameraPos.xyz-worldPos)/ VISIBILITY); - - float3 eyeVec = normalize(cameraPos.xyz-worldPos); - - float waterSunGradient = dot(eyeVec, -normalize(lightDirectionWS0.xyz)); - waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; - - float waterGradient = dot(eyeVec, float3(0.0,-1.0,0.0)); - waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; - float3 waterext = float3(0.6, 0.9, 1.0);//water extinction - watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); - watercolour = (cameraPos.z <= waterLevel) ? watercolour : watercolour*0.3; - - - float darkness = VISIBILITY*2.0; - darkness = clamp((waterEyePos.z - waterLevel + darkness)/darkness,0.2,1.0); - watercolour *= darkness; - - float isUnderwater = (worldPos.z < waterLevel) ? 1.0 : 0.0; - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, watercolour, fogAmount * isUnderwater); -#endif } #endif diff --git a/files/materials/underwater.h b/files/materials/underwater.h index a760202fa..8474f299d 100644 --- a/files/materials/underwater.h +++ b/files/materials/underwater.h @@ -1,4 +1,6 @@ -#define VISIBILITY 1500.0 // how far you can look through water +#define UNDERWATER_COLOUR float3(0.18039, 0.23137, 0.25490) + +#define VISIBILITY 1000.0 // how far you can look through water #define BIG_WAVES_X 0.3 // strength of big waves #define BIG_WAVES_Y 0.3 diff --git a/files/materials/water.mat b/files/materials/water.mat index 372058f0a..3ea6a2c2b 100644 --- a/files/materials/water.mat +++ b/files/materials/water.mat @@ -56,11 +56,3 @@ material Water } } } - - -material Underwater_Dome -{ - parent openmw_objects_base - - depth_write off -} diff --git a/files/materials/water.shader b/files/materials/water.shader index 59b9e5a43..793cdc95e 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -272,38 +272,16 @@ #if REFRACTION shOutputColour(0).xyz = shLerp( shLerp(refraction, scatterColour, lightScatter), reflection, fresnel) + specular * sunSpecular.xyz; #else - shOutputColour(0).xyz = reflection + specular * sunSpecular.xyz; + shOutputColour(0).xyz = shLerp(reflection, float3(0.18039, 0.23137, 0.25490), (1.0-fresnel)*0.5) + specular * sunSpecular.xyz; #endif // fog - if (isUnderwater == 1) - { - float waterSunGradient = dot(-vVec, -lVec); - waterSunGradient = shSaturate(pow(waterSunGradient*0.7+0.3,2.0)); - float3 waterSunColour = float3(0.0,1.0,0.85)*waterSunGradient * 0.5; - - float waterGradient = dot(-vVec, float3(0.0,-1.0,0.0)); - waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); - float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; - float3 waterext = float3(0.6, 0.9, 1.0);//water extinction - watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); - - float darkness = VISIBILITY*2.0; - darkness = clamp((cameraPos.z+darkness)/darkness,0.2,1.0); - - - float fog = shSaturate(length(cameraPos.xyz-position.xyz) / VISIBILITY); - shOutputColour(0).xyz = shLerp(shOutputColour(0).xyz, watercolour * darkness, shSaturate(fog / waterext)); - } - else - { - float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); - shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); - } + float fogValue = shSaturate((depthPassthrough - fogParams.y) * fogParams.w); + shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); #if REFRACTION shOutputColour(0).w = 1; #else - shOutputColour(0).w = shSaturate(fresnel + specular); + shOutputColour(0).w = shSaturate(fresnel*2 + specular); #endif } diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 00d4eea11..693c5a9cb 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -280,13 +280,6 @@ - - - - - - - diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 044cc3406..2dee5ac88 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -138,8 +138,6 @@ reflect small statics = false reflect actors = false reflect misc = false -underwater effect = false - [Sound] # Device name. Blank means default device = diff --git a/files/water/underwater_dome.mesh b/files/water/underwater_dome.mesh deleted file mode 100644 index 64ca569c22a04110e7913505c427f0087cef51c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22585 zcmZu(b$k`a_uVA~0)Zewf`tIVH8>=125SjW+?@cyr4-i&cUoH9DH@h)b7#(6nb{a=Th@;5+ofUjPhF#WbR81?Q`-Sy#mcu% zX_Sa>YT&olJS~<+ zy2gyGZY|GNU+?($h3k2zEG&=VcRp_TS;{G=>=c3eBV5;FgXH-vPr7e}JfG#!Q_Jd& z8Be=f;rYquJ$1AEX||!B-UX{Gmd^bGuKL~pB5M%{m(M#{5fzvH^q@JA`{6{fAle}?Pj z)7q$&+fwVB_q$2`^NV|UCbmwH`U$7<>!Jgjs7Z#uly48a;yN7I#WN@>LA6*~-Ws^D zj1G+%s-D+KuCuKBRqA`5M|rMnd?xirtMv)Osp-$ptMJd~rGBT*WjyT{mzMg&Mg-|YHi52D)W^`TQa^V>faj0ljimmZOX>87+3_k{(N$93-)F2Vhi@t=-@WUq+b>6u ze)xEg>b>MwwXbe+56A!F^cU8yK2cJC=idSPUXueV+l8r8p13v2_3xcTDeqU=?cRSe zPW8MDWj)^2PwFpR>Zb>0xTa42T};Y*eog5rQuKEzUzMwy`{M?G zT{Q14b*|e}SCt`|r2bzAYg$hdhe-W@*ZS%&1sGYV{TMrFItni2<&ksp?(@IO@i+g-@ zli_a^)E0BDM;5719YU1)D;IoKJyII_N!2z|e?zXV5xv4ZQom+Yu)Fg7q`F$!cZ$4V z`>CI1&BLXA?@P>gf9{?_=dS-u<@hyJ`d_`#1XsY)Nz(sRf8TM>tsbD8HM@`b*G%+# zXKS3Rooln`x77PgR^c*%I&bCcD(9lHGJeC_UvX{Ba$Ux6;L-|Kj_@E|)i|#*3|T1i zBX9pC%DCer^JCk@7S`j=Idsce$JN@CaWem6-)2yG2WOJ`_n^jL>%`{VI{4Z?m9^Ia zncpi@=2La%=9l@M`OGA1aYO+<^08ax&VEVw(|b%A)h9OPPxxOaah=tvTScAFX^Fb? zG>NP))WiDuEo6NelI0)E|NF|iP?MRe)8gc^e%;vAPI;o*d&-B+P(MxFVJ)5>sny>T zWqsoM$$5JAb7xr}hZfyw?T@afvz8sAo}^4I>+j7CUDfHf-DUk9@OihD=}j};EN5F; z|2XPX!Go(6ddT`cZDWF!v_*T}V@_pdUHzPl={JwQ+t+Yj@HAf&s6oW zez87zykTx5sUMm;z!STyw=ObzlB{2BA9=j$U_EJH&XN9}WdmC3^FJy1vVWAAb~VY4v-WQ5X8@zRH(1gYYZt(O%cJ ziGzh-u5J0O{PogmzkW{??FRYD^|Qj<0>aPb^>4T{?n|k6wtc0l_(cl8Gp_b^WlOhC z_#JsO+8r3_t5-#QQ2lchl5$?d>;ER@yxz8ab-!Vs6zu|^&ueH@8hJjiYLmY%e&e0G zd-tP@>m#pLSR-j4uVep7r(cG@R^%P~$7{&&$Q4@X;{qWj;>{`(e zul-)PB6~~44gV)7(4vKzx4eS`IbH03_)-RbT*YDO`k@-RU&3RJn&rCAE zc^0cf!oZnoBBJ1au`ORygsrB@QImcCj zdB=qxymt7msQ53uX6fHt*J*c1>@)dAJKgS=FyR-kYf^R4_tx%F#qORH{_@%*Z)xE# zuMKMS)W!a^#Qu}N^aFYvE-n1!^~$_KdUdv~io7TPxek!`^bffX6p87hE2@WLzgeH_ z0C`XUkn6zjWryoDsqTyYX8Y*JkoWZOxDI^U-%0;e=dmL1$$zc`+Zf+*8}0k$hN)@y*+1Gp+I{wqen9JlAlQ#2 zns%T1p&vlIPyNsjC<*->&Eun~AL^I(fp%Z~NB9BerM$Z42_H?n&+(xjK)cWJDLOEd zC+zPcy6MoQn(Ge7m;9sM=lIeOSm7z9|1R#UY4_c_1l2TV9yMIYUeOw;aje$o%1-RJzIAF%y>O}$`za?O5oe$x-2-RJzKACP2z zLp`FGpQha>Kj;V0?vo$%1LFQ|rS~>Yp=tNYFUBdf`{Wn>fNbtgI^c(tns%T3r5`}M zPySws>h1{}+DETz?5}C}$zR4nwEN^Q{Q&Z}#fVgzaUtt7PGnrj`iv9X7wf6}7R#j> z7qUL%IL3vn&p2_|h(Y?utWZt=mF;63$GDB{V;tAvRD1nH=3vdZjQwMr#<+~}8{@PF zHJW2?Wz(Ej)DQc|xQqH>9Ol=wp58byNHeaYei>&muA+V!XJt+wsrP=(s5$RBK3sno zH*tIzM}<_Wq~qoWYQ{wzU&cv{i#WbhqN{lB{99gUXq!&cu5o^h!ura%hx3DRP?mjR z+OI+y&A5j1i*XL)8qP1qIj*OLbjjSQHTlQ+N&km&3+E@}n5k_;^@e=@nsEu|H{%q> zC7j=kQ@;8J>!`9RgkR(b$C+^l`N25kHo`NcRRbW=LLVX&`e z+(3SE92hr{pNu2o|Mu6xt9>-%0`i-20^F>?}9YIWaN%Go}~NvzNIF;41KJFVV+*-y&ZKkqzb{}_kue2`K1 zy5=wC)DPo4)~9|L=XLudn_l%WK+36K`kySPei=ue|2da#5RhKVIX;Y2SQpo`(El9wlSWmipPA5>ih7G7rP&lfTTveEFxN9($sUl=I({ zbe24hLH;t2lUTU7F4-cS{C7L}ue|)v)V-OW-#3!{m)wobf8<8~?h=u@A$}kHcRTp6y!_w&zLNfKR2lN$?cl%i^8aI{ ziaPRRaq{0y{`dNi|H{k%MUP79fA-Ng7`&rANhIX~!Mf&a?O|C#v< z=obZYk^gQ7|6N}GXIYb5S6i8#{C7L}@AC3LZL1u5cda1u-|gVP%gg_2WrOtQv>C{M zw}byKFaOsU3)CxKry>8{4*t8m{7+LYKv#L-PyWX{`0w)ae}9)0I_^nw@;~0e{|GPt zPs~lKeLwnW*ncUv?Z3-w|EIWpbop~hrF{KXDUDvzJCOEY^kdt9<+cB(&jspceS>KKErqf6HP2WqfJ>2R#kZJ31Di{kJ$jmrv0}Z_Fv{F?f=7L#dW_S6>0x1hy9oNP5WP~Ng2JX zTxHsSi~O+dzwm?hzeeqFeWGn7?Z4%)|H3cY|JeA-x<>kXwEvdF{tJI;|7-7v)N{Ht zqy4wYf7|{Gf5rYcsiy-+MQQl|Qs4IfHTh5fe_F+|+Lb?AW8Ibdw*L?Ck{=dvG+y9sOMgRYLx{SKQ>HHf0 zzsyhD|Cjkm|3CS^>2$gSxitKLi~P6!f0^I(|Icg;&_ix#lle{l+y1}sgZ_VkMgIEl zLYXxDf8m$y|10vJ{{Q~Pe)`#@w6gw?pSJ%m{G|WCZndv|Wcq9P|8DZ%_Wy<7^#7-9 zPofKt@zsd?rQDAHrJV8qmU*VGhZunCBcE@_|BCAim&X_8gakq$BzF+KaBtPz4Oy2sszjUkpFi4FZyNt zf9PgPeQSBBM%*vsW5@q8K8*iU-ASb*%NEv%|7Coc2SD7fxxO?0zx6Rdzf4+EBkq^^ zVaNZP_JQ$#uHbaKW9|wX^TKk(|C;uN@qcXBKpix*l1AJw^V5$1HSH7Q|L6l5b&mm& z8gYlrZ#({%`OWx0wsw$CdA6QL+%NpF>VNhQ*5JL=xAT8epLu|7 zpHu1r!+z4>z3|`8|4Du30qzB*(u;pVtXT4cw9n4}N&A=w==M5=9y`3V2JfYRcK%QL z$2>rjmwvi=x7HfG7ya1zKhY2K0A+prbY!MR8oU?%+W9}xFY^FP!;{GW_3^8lBZ`XY`Gm+_^2;QRvbWqvRZ5co8y?&Dip zgZDDO?EIgmePJG;Sh=J+^l1@Ue>gww{GZHE<^jr&_tDW=@@ep1=C_^ylljd&z|}iR zbdP~K#lDaqcK%QJ!8}0PN=fu6BZ~&_E!uxO|0n!n9-#IzQ;&*GFa8htY3KihpUeaF zNowlNT~lfBUifY2|AgPn0~GIS=ws!QG5;^+cK%<=nFr|5;fr#kocCfBApm7xMt2&mXGD9-TGfeh=+G^8m2>!e8bArq8*r z4mSM>^Yg#GFYbfE?hAjJ2YB}Rj*6%~LL=^%`u6^?)Mp;xN~?I~>*=ZC_j~9+a32eC zztm?QpnHLTRA|A$8gak0kMSqserX@`0ACV!tNV33XvF=}KYM>x`o}y#?D+#K%ZBFC zKkA2h0L1;GALaor)jg)Ndg^J!{T}*P_Wr8qw^NN0R`=1TRHrVHvi`{W{NMhmj1Thw z-*r5%CQYlP5%|M&3|Q&5{~%zsxUt ze^cfc^8gJx-cc(`6c+!7^OO8T+%NNU*vYHzv8^7cDGNh2;(nRm_Wq>IZ{`8se4nVQ zR0`G@SK$Zwg}7h%!8|~AzvpU;Uyw%JFZ{Ci7lmKU18jG{QWIcb8Gn(V_Wq&plX-vx zQSVfRr~Vpozwq1M9~6GK7`ZgQzwt@Me(=?Z`=y*?jJRLQaT`;7*LziBw6DZ}d_Kz& z_sjEHzWT;Xl@U1`#QoAfmLu+$_OU$E`$Uy>Vp{P($$yq3?w9_tyveJ3s%^eZ8gakq zhvkU-ML#V6`@#+N?0PowKdE1qBkmXdvfLVfNtKSzr4jeb_^=#tzl;ydU#C5zemk6B z>>tOM<%s)bd|4jT?wI;Ju$V^NFY|-{hPYqm2k(p5-LJaOEv>PCFZKohW+3jD`Ni@^ zpFHaAfN+htU*;#v5%C13hPYq&%lp~=$16|A-cJ6zk@xfRUrpK8Qq8E-%*+26<^df1SDqp+^}b7#lmBi9 z|JD8F168jNb)EcoBk$+szZx`ag6dEu(#e0fga7Jtj~U80V`V4*-N^fS`LCM(zE}lz zs_5ju8+ku3|5b~$Yt*}-(mKum`0vK~2rvIt#|LpLHe)d-|J@G$tCj8Cs$WzAC;#2Z z`^o&ekn4--SWRm;fjLVTwn`{q{N8ZoN|A-Ph z-l`&JlRE8xJo5ft`|nES^G5yi-p6VG-H7|W_TQDP!()~Aaq@5WpLqbp{a*X;y1L<} zdUD_2Y5(2G`+M!bT6pffD)Bsx)Bd}W_xIX=HS^Rlm5?rj)Baly`>$5U>`|E`gPiu? zLfr4Q|El1FZEE16>`wb{IqbhG@NB(m8Jf#!|1HG*Ui+_({kTkpoyhC7|CYo4t6hC( ztL>gbPWx{m?)Tb%m1oB!HSJz;r~S7a_Fw(*;}F%OO&Q(ffA-%(-0!vjszO|AwN-~Z z?Z1V%-)sL>tVgM`(T+dut4%Bt}{}$qY zsSp2OUrc)5mETiF)<3Qn%mZNG&+Gr|8Dqw{23HJs`u`T5ci9I;s2|Yo_=cBygW|--*Wi> zs{FYLs@8#=PXFIR+%Mw`|6c`+nx&$%Wq11jmc##7UuQ2<U4)w z%J;JWH~)X_!@X|A{lYK!|0-_YRTYc;I`f~l|L;cJFZ_i6?<%(bfvR=K*XjSe5%&wf z;s3k3#=cTB-Xw9x|8B(nQqJp_?Jw1dv!*ltcO&kX=kq$~c~i2J?qzk1msR$UBE?Tr5|NBpm&_sv(~Wzy)h|BL@E#QicqcpWxps#@MSo!;`l z_}@a@FZPAkhzY}0?}dTR_}@a@FY}Yv!zJ3N*f$xS@xO(*U*Ne<9`crzwnFK;O=)_rLqL;RCfH&E8>3PFRz_0&u|?tk;@zZ$1o3o zxL^3oYmPr3M#Rktb>{yp^4`w>>7&QmyGHc(_vZg%=m#P0m-<`>{1dZBY+Rnong6pK z`9B>Ny5Ci=UP@>F&m!;b{GTpd#$T0=OySJ`S%~{ZKU@bkXDFe1HuQ7m|19#J`4z4M zzRMb@nZuI{|LFfS4}iGeoBz|5O7~T1HYIcB|19#J`5mqUcl{=+hWC7(`9BMBzc>G< zC-0rDV#9o$`9F)iXZ+7~;NZO#s_DR_&itQ+xL@Wc*MT3V#i;|we7@!XT*w2E_snl| z9VmNbrz%iL_P53VXP%k7XMUXPz|4P+s>-91IP-rNd2i?clz+R6>eDsTng4T>_sq|6 z9oTmDt_rDaI`e;S@}Bv9t^+<*UaH6yhBN=~M%*vu^aHw}eDkF*iu)5>Uzi6#-0#i* zt4i1Is&jvQR*w9?g}C3F|Cjdd?)FJJ^8Xg%e(4|mfJJdf70)*~^8Xg%e$fy8fGqoW zs>g5Se1tduZz1j%{n8IeJuyyoTk%dg^8Xg%eiR$MgdpBoo3L z{Xbpc#cfyP@q3ha|L+{~0Eqj&`+vId)gbjE{~?^u`?mk*LEJC;VI0tSe1uxj>9}(2 z|9P`uBD7)ziB-lw<$TqTg@t|LLrCVpYVeJ3N2m-T$)?_j~vM^!Q$z zRmxWnlw<$TLfr4&|5K$4C#Wx{5`|xkk2%hW`@Q>rDrCWNwQlNj<=FqT5chlc|5UDH zm(;cjua#r}&yBcW_{liH|I|Iz?b18t*#C1Q?)UEhxq8RHR0jrqQt<5zd;eeddAU9? z53p^`E2S%ZkaF_ho(G1#|F72m^+5Txd?n@f{=dZ7_Wr;6ZoySGs_zpiXaDSZXxRJz zYEi3Gs>{IpQf}}6OMQF)Uv0awUv+MOQ_30td-tL2{eRsrPrPcK<+7C9`~Om(qV_+sdS(AOF8Ek?H_ez@BiyM zb0(-cyLL*sz5g#c4txJ!zYXuFdZgGU<;-t+^Kj%p^8jOqHdZq({3Yeg|1l51=iB@L zI&^4hm9N5TDJTEEc{qFjUyn>otERtPB<1%0ztp$)|MiH~r(I9)$-5GKY>b@;@b3TX zL-k{D&S#?Xp8vUxJfP$JkM10kO`ZL-jk3>u#Mu0|?EQaTaMNSgQcop0zs~kC59m1m zqw|bIe&Fq3@?XyX*!;Kb{eOM=d@I##`b6^Id;W*~x2PZTf6x8F>P6L=(O9|_h!ufE=`5()1{zs=dy-mHlwNK99aei_ilzBgU|6ix>vqw!|c%1zAp8p~L zz2|>aVfQg*2A(JX<$RpYfA9Gp6?XExs#E?RJ^w@g zyY2mdwIcelx>Wla`R_gdL;icu|G4t{zEPt~y>p)bqy2Z=`~R-z?zc(}eIxC2*nfFG z^8g9wo~rVf9@G9y`?wF_IRB?MUb?4Z3f`jq_n!Zw{kQD>f7N==HFd1+1=@en5BC8a z=l@jPkaKE(t>bb&lKSO7vE%%oj!Sl2MSa>s`>*W%f7*YG{Kxq}J-XgLwX^wlIe+Z1 z|1!SJ1DIvp>O=bt%6tBg`v8vffBNkHIF;_sGC7~k`DNRGnP1EUY&{aIYCf7x`>*W% zf7*YUpUeZ?Y_?c6FFTp`U)lTrwEr@{Y5x~T%uw6<45j^7KkdIo{?q=?7}r7-?;Wh{b5~ybFZ^X5pv|Rl6*%mr z%W?jf{=diT|8E}mn@SaN&c%H{t{=Al501+Izpm*&UfoYO+Qof8wvYCg`+oNRziyvq zp}OIh{@eNALf8l7zMt3sUudmV`FfRcp8uu)FYjm3{~xnugL?l%6X*F~`v0O|`v0Fk zZBYdZ^q2F$93R{Nm+@g9;9P=7ZOc0G+xg!)*avi+|J70D_p6|jv%a1GWt`_Y|Ev2{ zIHoE;U*aM=*Jpa%5U;4-R|4Fjvs&d*B&h!6_|3yEH|D($!s+3C; zWPHefp3`ug|5tmPKTyRlZFZjjXZ$bY!#u!)c6U^&^|9a1|6lJkm+`;H-v8HI3f)i} zQZ7)4{}t^&^8noUxA*^b@hg{AyMt2|=7r+?;{4#gzrFvj{UXk*+S`Xa&;K+2_t^XY z`rc2c)PcNhzMcPn*Yg15e-F>MF#ez4;+UE>JHmPXpYgx&gYkd!JqJ|keL>Fi|BU~I zUyT3%-nLuCx4P{@+%NpMrKtSpr>&i8+q|C8}y9^gvV7phTsU-%c_-v43#&!c>DYvuvm*I%lH!V?wG{m?#ee(~H7 z=LhouD{8-1n&u1Qh=l;ll<^g6UH?_O*y>IXT+4+BIAM*gsmz#Rbsf%L&*gxh0csI`F=I`|3tsc1H8SRQC~>bMsfY&_%ILPcz;?A?iZ*t%p9)Z_sja;80Ua_ z?w{*B^8lkurqj3fO_lYP^MiQ+$NSH!x`DI*<^t#Y&D{SJ{xc7-bYk(JKs;{{-4Zm<^j^b_0ucoz!t#26aIr=j`xpUy)q@&Cjw45-!JC= zpYV%$fR8R;9ar_T#9!nm^8k+bhh4vR_tEuh-v9P~u)Y5${Kk6#5yKXkI=nRE_ez~J zEnGg2DaDOO9M+oDvBqT0hWPO1iw@kSQb)Yw4fZY9Hc^MS$SZ2NCna2 z3cw1G3ZN$yffXU;M-Rh+;gIs7=MlgNNO_?V7tjSM6q-^%1t||SsDT<%ZfLd=uo9$P z&~_z!LX66gDhXCLs^D8%u!>O?wUuC1qZ*#-60Bx?hhK{j{Lc6utq2$V-l&e&RTQjl zM55Id1S5?a=uLUS8b(d@vYcQ|qZWE!RJh3sbF{B^xOHF`HAk{((ngW|bs)?30 z12%(H11)Y2Yz`?BJ!t`K0jWBA*b>+h()Z|jD_|=~-$5g-fvq7`gQnU5+d!%c4Ymcg zg;WKaZ3k=zsWPt*x>_J!07HTwbkLF$Po_6PQd)C0dX05||r zceG$2a3G{^XxSj(AV^)&;=#bdkh-8JLx4jdbw&?|0*6BCgq{xr4ucd8jSL44htv_8 z8UY*usRK0lGw^3f?V;HiU<{-vXgda<5Mv~y7{QUoD17T@!BNI&)E*%?+8BeU4i_9_ zjK!}F6C7)dLo0>~jx)xibwdQl8xzp#!GaTviRjHB!HLEs^m3r!Bx5pqKR|G@F$G%b zFF3`R3T^choN7#i7W)cLGk$?~`w0GG{EE*n#&qCx<2T$*GkypD4rv-{&H&DUG!;*r z37iRO3Vvx8a2BM=Xu)jYY)F&PvN^yxkS3zVbAfXqO+ZiP0p~#)j~>nk&WAJ(JzoG^ z0BI~VvJkis(imuJ5pWTt(a_*x;9^LlpxGtBC6Go!+e`2XF_uDFBDmD}1K(OK_=m9! zwHFC4GnV723k8=OEAVRz1Xma<(Te$kD~(lX-8{in#%i>BuHb4T7QLAx7;CISFJ}v` zG1j8@vjo=~>!6jHg6oVwp{*H$e;Vtd#oq4F=Kzwp^$Yy@sJ{>I&UBMuk` zX+3Ig0&arzC!Y8Z@E=I)@JpM4n<1@53$_5aKw5*AZ3S+H6pI#b18#$~8a>$#+zx3K zdbk6)1JX+LJRTSiX$3Um2D%|Fho&r`1!);H=mB~l{Q=GH1nz{i6x!a2Pl&M#(oVr$ z#%_GeBe>g0Ky6Df!PtYRx&`+bd+}@Wf_sg9XvGe}ea3#YZoA-q;{aN{P4Iwm5WU$d zc+fb6UTzUQWE@8CHwzv%jzBB_2p%zxLR*^zj~d6I#W=xZ#&KwOqu_Dl1U|=&lfaY4 zzqmVQoC2PLbPP3515ZObiYJ}{o`G}(zjPLO7Sds~;2iKAq(f-gdEj|S2hrjSzzdKL zpeGlB7a{FO4=({PLE49&Uj|-=v=WZZcok9tGQxFmSjxQEtV6uf8L zN2@Og-ZvhgH|GT(7!T3QbAk_zN9g@o!AHhpXyuIHVS#qWXdA>Bt$J^(*Jx`!Tq1b&2c7d`(3`~>L^H1Zkv8PaWN>I?7-q+8J7SKwDj zH=$X>yovw6;x2?Pt{GyOkN`l_Ok#e)H;GA1AM-Qn5Pi&~<|jOhnAG$&KjJrtzGgD> z1Ad#B%uH^+N1KSrO+WJ;+Dh~@Qo zOX!H0+6*wCLwCdgGmZHIIwhtt)8doHOb1M7rpH}?83+u76oC2}fEggA#&a_QGeSy* z-^&Ed1j!%m$PCO3DJ9w$1Pp?d0`1NM%mT>|{mBZ<3Mo1InGKi?QZn>EJ1{#WU+5(V zFbAZh&{r@p7?Kb4m=l;2QW9u31Q-GdcSZ>A;GaVZF^Rd%-1t^b!Q5sZ)D9NRV}|0X zIRrz^y!f^3f_cq+Xhk-`d}e;ME~{XEvjAG1MX-Qb5WNW!ENB)&FEa}kG7F>knFI@) zMWB_8fapX#9cA76tEPeVyIafSQ=7M zJh2S045T9XrLw@XkP4#(<$&cN6++9(1It4yh!$4>R)AChJ*fz+2q`~$7!C}Fln*_R z07gK{3yrvdE=Zx!lmaS9d7wcJ)R1yRtCfJ2AmxI#E8#B0z?l$SiIvSN_?8x|Vpc_M zC0Nz0hNrp&tC`>7*CGVJGrvbG!UexKtD|)l1*@BpXmtg_NV5idQ(mx!Srff1Cs@<0 zh2EDHtY!WHt&|b`!K@8!l@_dR)`1pF3Dz;|Lc3vtbzfU5SI2A!YzV0i zYBmBkf>aw%Yz%A+=?DB$6JQfawa|j5z^0IDqGip1%^=l4i<<+RLyAOCS^!%>s*WDE z1h$0qJ$l{>*b35j&`4`wYe?0gsW!kikg7t1ZGmkeRe@I90oy^U3~jf=U5F6{shvrT zGTY-@Z3Ww#9ZgIx7%&zE7 zGr_KAH}tZpU^lZndf!B_yV(O;X)M^o>lg!EJ{Q$wq<`ih9zu**eDzw#4aH=^CTI?%0&HM%0 z?IZY$`71uZnA3sN&EIf0&HNqsJEUo-IRiKY(o{TgCU7RCDfp#Xz*&$cqXn~pvms4F z%jN**K$?ga&jrqfGyy%C2b>3KJbE}EI3LnD^n3wu0i?0e$U@*kNMoR>MZiUnMni*( zfr}xHf>xIRmp~c`Z7;!Hh_MvX5|g;p`~%-wEcl1H47C>tE;E{n=9~Z3j|k~ zE76Mif-B8cXx%))Rpx56damGVGZwv>BN%J0K`&+nmP zftw+%MGLk7w?JBhmTd)Yg%pbxZv$?Fv>H9x4%`lD6?(V>xC7Ek^gJFI4`~H7;s&}Q zEr+Hopap3eH0S|(ApHTY?gZ|Hv=rLjiMtSE7o?pgahJIp-|`6VHWN_W5==1n;HhrG zJ?38gTD;(1b01o-zowhA6J522S^1P_^q(fiGUhs`6< z%0Gff%%jlOCc&fTF=#PP@R)fV+TAF4+&qELaq}ebr1>xIj+v)`ryw0e&C|fskdESs zXMkrQ9l#_K-vRMT?Jl+lmHE0173r)8(O^%ybfs>w0#|SA;t|z*G=LL^CrG^P4K39 z3$?Eb-ZF3FsaFJVn|JVQmj&;bchQPVf_Ke(Xx&A@d**$#`hwtn^8tEuUhskW5WPGn z_|SZW-k%kGWIl#g&Imp>6QQlsf{Er6Xz`Tb6Z0vwds6VJ`3#?@=5ye4^9Amnm@k1Z zAw5COSHM@067j^>z}Ju-b~&9{3*8ee~o5@B^fK z=;24;M@VfBV3xC41h(X8~f5dMPGa--s0l!Vmfc)}%w27D=dFOX% zD={td(QnZQVgT~gZ_qblD&((UqtC>Y$ZNlXE{J|cGUFw5L`-HRHJ(Fv#H5Cg@d7#} v`k>)yEBP7BmK(q3#+8S#_{TVTwg0fL{9zXSn>Lo@!Z(bi*@*vNLjL~%QsK$) From f1d35b73b80c361724efe518de3742f998bd3103 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 3 Mar 2013 19:52:20 +0100 Subject: [PATCH 61/61] Cleanup --- apps/openmw/mwrender/localmap.hpp | 3 --- apps/openmw/mwrender/refraction.cpp | 2 +- apps/openmw/mwrender/renderingmanager.cpp | 14 -------------- apps/openmw/mwrender/renderingmanager.hpp | 2 -- apps/openmw/mwrender/terrainmaterial.cpp | 6 ------ apps/openmw/mwrender/water.cpp | 17 ++++++++--------- files/materials/objects.shader | 13 ++----------- files/materials/terrain.shader | 7 ++----- files/settings-default.cfg | 6 +++--- 9 files changed, 16 insertions(+), 54 deletions(-) diff --git a/apps/openmw/mwrender/localmap.hpp b/apps/openmw/mwrender/localmap.hpp index 9c82258f9..72e637d9a 100644 --- a/apps/openmw/mwrender/localmap.hpp +++ b/apps/openmw/mwrender/localmap.hpp @@ -117,9 +117,6 @@ namespace MWRender int mCellX, mCellY; Ogre::AxisAlignedBox mBounds; std::string mInteriorName; - - // maps texture name to according camera settings - std::map mCameraSettings; }; } diff --git a/apps/openmw/mwrender/refraction.cpp b/apps/openmw/mwrender/refraction.cpp index bb2d88865..d590dbf4c 100644 --- a/apps/openmw/mwrender/refraction.cpp +++ b/apps/openmw/mwrender/refraction.cpp @@ -33,7 +33,7 @@ namespace MWRender vp->setShadowsEnabled(false); vp->setVisibilityMask(RV_Actors + RV_Misc + RV_Statics + RV_StaticsSmall + RV_Terrain + RV_Sky); vp->setMaterialScheme("water_refraction"); - vp->setBackgroundColour (Ogre::ColourValue(0.180, 0.235, 0.22352)); + vp->setBackgroundColour (Ogre::ColourValue(0.18039, 0.23137, 0.25490)); mRenderTarget->setAutoUpdated(true); mRenderTarget->addListener(this); } diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index c8b5926d9..382ec6557 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -121,9 +121,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const //mRendering.getScene()->setCameraRelativeRendering(true); // disable unsupported effects - //const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); - if (!waterShaderSupported()) - Settings::Manager::setBool("shader", "Water", false); if (!Settings::Manager::getBool("shaders", "Objects")) Settings::Manager::setBool("enabled", "Shadows", false); @@ -504,9 +501,6 @@ void RenderingManager::configureFog(MWWorld::Ptr::CellStore &mCell) color.setAsABGR (mCell.mCell->mAmbi.mFog); configureFog(mCell.mCell->mAmbi.mFogDensity, color); - - //if (mWater) - // mWater->setViewportBackground (Ogre::ColourValue(0.8f, 0.9f, 1.0f)); } void RenderingManager::configureFog(const float density, const Ogre::ColourValue& colour) @@ -854,14 +848,6 @@ void RenderingManager::windowClosed(Ogre::RenderWindow* rw) Ogre::Root::getSingleton ().queueEndRendering (); } -bool RenderingManager::waterShaderSupported() -{ - //const RenderSystemCapabilities* caps = Root::getSingleton().getRenderSystem()->getCapabilities(); - //if (caps->getNumMultiRenderTargets() < 2 || !Settings::Manager::getBool("shaders", "Objects")) - //return false; - return true; -} - void RenderingManager::applyCompositors() { } diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 49cde25a3..e40672ada 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -184,8 +184,6 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList Ogre::Viewport* getViewport() { return mRendering.getViewport(); } - static bool waterShaderSupported(); - void getInteriorMapPosition (Ogre::Vector2 position, float& nX, float& nY, int &x, int& y); ///< see MWRender::LocalMap::getInteriorMapPosition diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index d5e531f86..8a568883d 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -119,10 +119,6 @@ namespace MWRender shadowTex->setProperty ("content_type", sh::makeProperty (new sh::StringValue("shadow"))); } - // caustics - sh::MaterialInstanceTextureUnit* caustics = p->createTextureUnit ("causticMap"); - caustics->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue("water_nm.png"))); - p->mShaderProperties.setProperty ("shadowtexture_offset", sh::makeProperty(new sh::StringValue( Ogre::StringConverter::toString(numBlendTextures + numLayers + 2)))); @@ -156,8 +152,6 @@ namespace MWRender // shadow --freeTextureUnits; - --freeTextureUnits; // caustics - // each layer needs 1.25 units (1xdiffusespec, 0.25xblend) return static_cast(freeTextureUnits / (1.25f)); } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 49836535f..2801e6494 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -210,6 +210,7 @@ Water::Water (Ogre::Camera *camera, RenderingManager* rend) : mWater = mSceneMgr->createEntity("water"); mWater->setVisibilityFlags(RV_Water); mWater->setCastShadows(false); + mWater->setRenderQueueGroup(RQG_Alpha); mWaterNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); @@ -380,6 +381,8 @@ void Water::applyRTT() { delete mReflection; mReflection = NULL; + delete mRefraction; + mRefraction = NULL; // Create rendertarget for reflection //int rttsize = Settings::Manager::getInt("rtt size", "Water"); @@ -389,16 +392,12 @@ void Water::applyRTT() mReflection = new PlaneReflection(mSceneMgr, mSky); mReflection->setParentCamera (mCamera); mReflection->setHeight(mTop); - } - mWater->setRenderQueueGroup(RQG_Alpha); - delete mRefraction; - mRefraction = NULL; - - if (Settings::Manager::getBool("refraction", "Water")) - { - mRefraction = new Refraction(mCamera); - mRefraction->setHeight(mTop); + if (Settings::Manager::getBool("refraction", "Water")) + { + mRefraction = new Refraction(mCamera); + mRefraction->setHeight(mTop); + } } updateVisible(); diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 37ff17843..7c7a604cc 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -260,13 +260,6 @@ float3 lightDir; float3 diffuse = float3(0,0,0); float d; - -#if HAS_VERTEXCOLOR - // ambient vertex colour tracking, FFP behaviour - //float3 ambient = colourPassthrough.xyz * lightAmbient.xyz; -#else - //float3 ambient = materialAmbient.xyz * lightAmbient.xyz; -#endif // shadows only for the first (directional) light #if SHADOWS @@ -288,8 +281,6 @@ - float3 caustics = float3(1,1,1); - #if (UNDERWATER) || (FOG) float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePositionPassthrough,1)).xyz; #endif @@ -311,10 +302,10 @@ #if @shIterator == 0 #if (SHADOWS || SHADOWS_PSSM) - diffuse += materialDiffuse.xyz * lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * shadow * caustics; + diffuse += materialDiffuse.xyz * lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * shadow; #else - diffuse += materialDiffuse.xyz * lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * caustics; + diffuse += materialDiffuse.xyz * lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0); #endif diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index af5be42cd..0120629fc 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -230,9 +230,6 @@ #endif - - float3 caustics = float3(1,1,1); - #if UNDERWATER float3 waterEyePos = intercept(worldPos, cameraPos.xyz - worldPos, float3(0,0,1), waterLevel); #endif @@ -312,10 +309,10 @@ #if @shIterator == 0 #if (SHADOWS || SHADOWS_PSSM) - diffuse += lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * shadow * caustics; + diffuse += lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * shadow; #else - diffuse += lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0) * caustics; + diffuse += lightDiffuse@shIterator.xyz * (1.0 / ((lightAttenuation@shIterator.y) + (lightAttenuation@shIterator.z * d) + (lightAttenuation@shIterator.w * d * d))) * max(dot(normal, lightDir), 0); #endif diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 2dee5ac88..6ff7fb432 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -94,7 +94,7 @@ fps = 0 crosshair = true [Objects] -shaders = false +shaders = true # Max. number of lights that affect objects. Setting to 1 will only reflect sunlight # Note: has no effect when shaders are turned off @@ -127,9 +127,9 @@ fog end factor = 1.0 num lights = 8 [Water] -shader = false +shader = true -refraction = false +refraction = true rtt size = 512 reflect terrain = true