Add more settings to water reflections in exteriors (feature #4859)

pull/2095/head
Andrei Kortunov 5 years ago
parent 14d342558b
commit 00ab552184

@ -46,6 +46,7 @@
Feature #4730: Native animated containers support
Feature #4812: Support NiSwitchNode
Feature #4836: Daytime node switch
Feature #4859: Make water reflections more configurable
Feature #4887: Add openmw command option to set initial random seed
Feature #4890: Make Distant Terrain configurable
Task #4686: Upgrade media decoder to a more current FFmpeg API

@ -2,6 +2,7 @@
#include <components/esm/loadacti.hpp>
#include <components/misc/rng.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
@ -18,6 +19,7 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwgui/tooltips.hpp"
@ -29,8 +31,10 @@ namespace MWClass
void Activator::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
if (!model.empty()) {
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}

@ -2,6 +2,7 @@
#include <components/esm/loaddoor.hpp>
#include <components/esm/doorstate.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp"
@ -24,6 +25,7 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/animation.hpp"
#include "../mwrender/vismask.hpp"
#include "../mwmechanics/actorutil.hpp"
@ -53,8 +55,10 @@ namespace MWClass
void Door::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
if (!model.empty()) {
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model, true);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}

@ -1,6 +1,7 @@
#include "static.hpp"
#include <components/esm/loadstat.hpp>
#include <components/sceneutil/positionattitudetransform.hpp>
#include "../mwworld/ptr.hpp"
#include "../mwphysics/physicssystem.hpp"
@ -8,14 +9,17 @@
#include "../mwrender/objects.hpp"
#include "../mwrender/renderinginterface.hpp"
#include "../mwrender/vismask.hpp"
namespace MWClass
{
void Static::insertObjectRendering (const MWWorld::Ptr& ptr, const std::string& model, MWRender::RenderingInterface& renderingInterface) const
{
if (!model.empty()) {
if (!model.empty())
{
renderingInterface.getObjects().insertModel(ptr, model);
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Static);
}
}

@ -193,6 +193,7 @@ namespace MWGui
getWidget(mKeyboardSwitch, "KeyboardButton");
getWidget(mControllerSwitch, "ControllerButton");
getWidget(mWaterTextureSize, "WaterTextureSize");
getWidget(mWaterReflectionDetail, "WaterReflectionDetail");
#ifndef WIN32
// hide gamma controls since it currently does not work under Linux
@ -216,6 +217,7 @@ namespace MWGui
mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected);
mWaterTextureSize->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWaterTextureSizeChanged);
mWaterReflectionDetail->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onWaterReflectionDetailChanged);
mKeyboardSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onKeyboardSwitchClicked);
mControllerSwitch->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onControllerSwitchClicked);
@ -249,7 +251,7 @@ namespace MWGui
std::string tmip = Settings::Manager::getString("texture mipmap", "General");
mTextureFilteringButton->setCaption(textureMipmappingToStr(tmip));
int waterTextureSize = Settings::Manager::getInt ("rtt size", "Water");
int waterTextureSize = Settings::Manager::getInt("rtt size", "Water");
if (waterTextureSize >= 512)
mWaterTextureSize->setIndexSelected(0);
if (waterTextureSize >= 1024)
@ -257,6 +259,10 @@ namespace MWGui
if (waterTextureSize >= 2048)
mWaterTextureSize->setIndexSelected(2);
int waterReflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
waterReflectionDetail = std::min(3, std::max(0, waterReflectionDetail));
mWaterReflectionDetail->setIndexSelected(waterReflectionDetail);
mWindowBorderButton->setEnabled(!Settings::Manager::getBool("fullscreen", "Video"));
mKeyboardSwitch->setStateSelected(true);
@ -336,6 +342,13 @@ namespace MWGui
apply();
}
void SettingsWindow::onWaterReflectionDetailChanged(MyGUI::ComboBox* _sender, size_t pos)
{
unsigned int level = std::min((unsigned int)3, (unsigned int)pos);
Settings::Manager::setInt("reflection detail", "Water", level);
apply();
}
void SettingsWindow::onButtonToggled(MyGUI::Widget* _sender)
{
std::string on = MWBase::Environment::get().getWindowManager()->getGameSettingString("sOn", "On");

@ -33,6 +33,7 @@ namespace MWGui
MyGUI::Widget* mAnisotropyBox;
MyGUI::ComboBox* mWaterTextureSize;
MyGUI::ComboBox* mWaterReflectionDetail;
// controls
MyGUI::ScrollView* mControlsBox;
@ -52,6 +53,7 @@ namespace MWGui
void highlightCurrentResolution();
void onWaterTextureSizeChanged(MyGUI::ComboBox* _sender, size_t pos);
void onWaterReflectionDetailChanged(MyGUI::ComboBox* _sender, size_t pos);
void onRebindAction(MyGUI::Widget* _sender);
void onInputTabMouseWheel(MyGUI::Widget* _sender, int _rel);

@ -178,7 +178,7 @@ osg::ref_ptr<osg::Camera> LocalMap::createOrthographicCamera(float x, float y, f
camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
camera->setRenderOrder(osg::Camera::PRE_RENDER);
camera->setCullMask(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object);
camera->setCullMask(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static);
camera->setNodeMask(Mask_RenderToTexture);
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
@ -380,7 +380,7 @@ void LocalMap::requestExteriorMap(const MWWorld::CellStore* cell)
void LocalMap::requestInteriorMap(const MWWorld::CellStore* cell)
{
osg::ComputeBoundsVisitor computeBoundsVisitor;
computeBoundsVisitor.setTraversalMask(Mask_Scene | Mask_Terrain | Mask_Object);
computeBoundsVisitor.setTraversalMask(Mask_Scene | Mask_Terrain | Mask_Object | Mask_Static);
mSceneRoot->accept(computeBoundsVisitor);
osg::BoundingBox bounds = computeBoundsVisitor.getBoundingBox();

@ -243,7 +243,7 @@ namespace MWRender
int indoorShadowCastingTraversalMask = shadowCastingTraversalMask;
if (Settings::Manager::getBool("object shadows", "Shadows"))
shadowCastingTraversalMask |= Mask_Object;
shadowCastingTraversalMask |= (Mask_Object|Mask_Static);
mShadowManager.reset(new SceneUtil::ShadowManager(sceneRoot, mRootNode, shadowCastingTraversalMask, indoorShadowCastingTraversalMask, mResourceSystem->getSceneManager()->getShaderManager()));

@ -34,25 +34,26 @@ namespace MWRender
Mask_Terrain = (1<<8),
Mask_FirstPerson = (1<<9),
Mask_Object = (1<<10),
Mask_Static = (1<<11),
// child of Sky
Mask_Sun = (1<<11),
Mask_WeatherParticles = (1<<12),
Mask_Sun = (1<<12),
Mask_WeatherParticles = (1<<13),
// top level masks
Mask_Scene = (1<<13),
Mask_GUI = (1<<14),
Mask_Scene = (1<<14),
Mask_GUI = (1<<15),
// Set on a ParticleSystem Drawable
Mask_ParticleSystem = (1<<15),
Mask_ParticleSystem = (1<<16),
// Set on cameras within the main scene graph
Mask_RenderToTexture = (1<<16),
Mask_RenderToTexture = (1<<17),
Mask_PreCompile = (1<<17),
Mask_PreCompile = (1<<18),
// Set on a camera's cull mask to enable the LightManager
Mask_Lighting = (1<<18)
Mask_Lighting = (1<<19)
};
}

@ -225,7 +225,7 @@ public:
setSmallFeatureCullingPixelSize(Settings::Manager::getInt("small feature culling pixel size", "Water"));
setName("RefractionCamera");
setCullMask(Mask_Effect|Mask_Scene|Mask_Object|Mask_Terrain|Mask_Actor|Mask_ParticleSystem|Mask_Sky|Mask_Sun|Mask_Player|Mask_Lighting);
setCullMask(Mask_Effect|Mask_Scene|Mask_Object|Mask_Static|Mask_Terrain|Mask_Actor|Mask_ParticleSystem|Mask_Sky|Mask_Sun|Mask_Player|Mask_Lighting);
setNodeMask(Mask_RenderToTexture);
setViewport(0, 0, rttSize, rttSize);
@ -307,7 +307,7 @@ private:
class Reflection : public osg::Camera
{
public:
Reflection()
Reflection(bool isInterior)
{
setRenderOrder(osg::Camera::PRE_RENDER);
setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -316,9 +316,13 @@ public:
setSmallFeatureCullingPixelSize(Settings::Manager::getInt("small feature culling pixel size", "Water"));
setName("ReflectionCamera");
bool reflectActors = Settings::Manager::getBool("reflect actors", "Water");
setCullMask(Mask_Effect|Mask_Scene|Mask_Object|Mask_Terrain|Mask_ParticleSystem|Mask_Sky|Mask_Player|Mask_Lighting|(reflectActors ? Mask_Actor : 0));
unsigned int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
reflectionDetail = std::max((unsigned int)isInterior, reflectionDetail);
unsigned int extraMask = 0;
if(reflectionDetail >= 1) extraMask |= Mask_Static;
if(reflectionDetail >= 2) extraMask |= Mask_Effect|Mask_ParticleSystem|Mask_Object;
if(reflectionDetail >= 3) extraMask |= Mask_Actor;
setCullMask(Mask_Scene|Mask_Terrain|Mask_Sky|Mask_Player|Mask_Lighting|extraMask);
setNodeMask(Mask_RenderToTexture);
unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water");
@ -405,6 +409,7 @@ Water::Water(osg::Group *parent, osg::Group* sceneRoot, Resource::ResourceSystem
, mEnabled(true)
, mToggled(true)
, mTop(0)
, mInterior(false)
{
mSimulation.reset(new RippleSimulation(parent, resourceSystem, fallback));
@ -457,7 +462,7 @@ void Water::updateWaterMaterial()
if (Settings::Manager::getBool("shader", "Water"))
{
mReflection = new Reflection;
mReflection = new Reflection(mInterior);
mReflection->setWaterLevel(mTop);
mReflection->setScene(mSceneRoot);
mParent->addChild(mReflection);
@ -630,10 +635,20 @@ void Water::setEnabled(bool enabled)
void Water::changeCell(const MWWorld::CellStore* store)
{
if (store->getCell()->isExterior())
bool isInterior = !store->getCell()->isExterior();
bool wasInterior = mInterior;
if (!isInterior)
{
mWaterNode->setPosition(getSceneNodeCoordinates(store->getCell()->mData.mX, store->getCell()->mData.mY));
mInterior = false;
}
else
{
mWaterNode->setPosition(osg::Vec3f(0,0,mTop));
mInterior = true;
}
if(mInterior != wasInterior)
updateWaterMaterial();
// create a new StateSet to prevent threading issues
osg::ref_ptr<osg::StateSet> nodeStateSet (new osg::StateSet);

@ -70,6 +70,7 @@ namespace MWRender
bool mEnabled;
bool mToggled;
float mTop;
bool mInterior;
osg::Vec3f getSceneNodeCoordinates(int gridX, int gridY);
void updateVisible();

@ -58,17 +58,22 @@ This setting has no effect if the shader setting is false.
This setting can be toggled with the 'Refraction' button in the Water tab of the Video panel of the Options menu.
reflect actors
reflection detail
--------------
:Type: boolean
:Range: True/False
:Default: False
:Type: integer
:Range: 0, 1, 2, 3
:Default: 1
Controls what kinds of things are rendered in water reflections.
This setting controls whether or not NPCs and creatures are drawn in water reflections.
Setting this to true will enable actors in reflections and increase realism with a likely decrease in performance.
0: only terrain and the sky are reflected (acts like level 1 in interiors)
1: statics, activators, and doors are also reflected
2: items, containers, and particles are also reflected
3: actors are also reflected
This setting can be toggled with the 'Reflect actors' button in the Water tab of the Video panel of the Options menu.
The player is always reflected in third-person mode.
This setting can be changed ingame with the "Reflection shader detail" dropdown under the Water tab of the Video panel in the Options menu.
small feature culling pixel size
--------------------------------

@ -428,13 +428,14 @@
</Widget>
</Widget>
<Widget type="HBox" skin="" position="4 56 350 24">
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 24 24" align="Left Top">
<UserString key="SettingCategory" value="Water"/>
<UserString key="SettingName" value="reflect actors"/>
<UserString key="SettingType" value="CheckButton"/>
<Widget type="ComboBox" skin="MW_ComboBox" position="0 0 115 24" align="Left Top" name="WaterReflectionDetail">
<Property key="AddItem" value="Terrain"/>
<Property key="AddItem" value="World"/>
<Property key="AddItem" value="Objects"/>
<Property key="AddItem" value="Everything"/>
</Widget>
<Widget type="AutoSizedTextBox" skin="SandText" position="28 4 79 16" align="Left Top">
<Property key="Caption" value="Reflect actors"/>
<Widget type="AutoSizedTextBox" skin="SandText" position="64 4 90 16" align="Left Top">
<Property key="Caption" value="Reflection shader detail"/>
</Widget>
</Widget>
</Widget>

@ -462,8 +462,8 @@ rtt size = 512
# Enable refraction which affects visibility through water plane.
refraction = false
# Draw NPCs and creatures on water reflections.
reflect actors = false
# Draw objects on water reflections.
reflection detail = 1
# Overrides the value in '[Camera] small feature culling pixel size' specifically for water reflection/refraction textures.
small feature culling pixel size = 20.0

Loading…
Cancel
Save