1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 06:53:53 +00:00

Merge pull request #2095 from akortunov/reflections

Add more settings to water reflections
This commit is contained in:
Bret Curtis 2019-03-02 15:37:06 +01:00 committed by GitHub
commit 79fca2e7c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 91 additions and 37 deletions

View file

@ -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

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -185,6 +185,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
@ -208,6 +209,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);
@ -240,7 +242,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)
@ -248,6 +250,10 @@ namespace MWGui
if (waterTextureSize >= 2048)
mWaterTextureSize->setIndexSelected(2);
int waterReflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
waterReflectionDetail = std::min(4, std::max(0, waterReflectionDetail));
mWaterReflectionDetail->setIndexSelected(waterReflectionDetail);
mWindowBorderButton->setEnabled(!Settings::Manager::getBool("fullscreen", "Video"));
mKeyboardSwitch->setStateSelected(true);
@ -327,6 +333,13 @@ namespace MWGui
apply();
}
void SettingsWindow::onWaterReflectionDetailChanged(MyGUI::ComboBox* _sender, size_t pos)
{
unsigned int level = std::min((unsigned int)4, (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");

View file

@ -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);

View file

@ -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();

View file

@ -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()));

View file

@ -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)
};
}

View file

@ -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,14 @@ 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));
int reflectionDetail = Settings::Manager::getInt("reflection detail", "Water");
reflectionDetail = std::min(4, std::max(isInterior ? 2 : 0, reflectionDetail));
unsigned int extraMask = 0;
if(reflectionDetail >= 1) extraMask |= Mask_Terrain;
if(reflectionDetail >= 2) extraMask |= Mask_Static;
if(reflectionDetail >= 3) extraMask |= Mask_Effect|Mask_ParticleSystem|Mask_Object;
if(reflectionDetail >= 4) extraMask |= Mask_Player|Mask_Actor;
setCullMask(Mask_Scene|Mask_Sky|Mask_Lighting|extraMask);
setNodeMask(Mask_RenderToTexture);
unsigned int rttSize = Settings::Manager::getInt("rtt size", "Water");
@ -405,6 +410,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 +463,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 +636,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);

View file

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

View file

@ -58,17 +58,23 @@ 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, 4
:Default: 2
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.
Controls what kinds of things are rendered in water reflections.
This setting can be toggled with the 'Reflect actors' button in the Water tab of the Video panel of the Options menu.
0: only sky is reflected
1: terrain is also reflected
2: statics, activators, and doors are also reflected
3: items, containers, and particles are also reflected
4: actors are also reflected
In interiors the lowest level is 2.
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
--------------------------------

View file

@ -428,13 +428,15 @@
</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="Off"/>
<Property key="AddItem" value="Terrain"/>
<Property key="AddItem" value="World"/>
<Property key="AddItem" value="Objects"/>
<Property key="AddItem" value="Actors"/>
</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>

View file

@ -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 = 2
# Overrides the value in '[Camera] small feature culling pixel size' specifically for water reflection/refraction textures.
small feature culling pixel size = 20.0