1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-03-03 21:39:41 +00:00

enable shaders path and dehardcode depth formats

This commit is contained in:
glassmancody.info 2021-07-09 10:05:27 -07:00
parent b457dfd8b8
commit cad0b151cb
45 changed files with 355 additions and 158 deletions

View file

@ -38,6 +38,7 @@
Feature #5489: MCP: Telekinesis fix for activators Feature #5489: MCP: Telekinesis fix for activators
Feature #5996: Support Lua scripts in OpenMW Feature #5996: Support Lua scripts in OpenMW
Feature #6017: Separate persistent and temporary cell references when saving Feature #6017: Separate persistent and temporary cell references when saving
Feature #6032: Reverse-z depth buffer
Feature #6162: Refactor GUI to use shaders and to be GLES and GL3+ friendly Feature #6162: Refactor GUI to use shaders and to be GLES and GL3+ friendly
0.47.0 0.47.0

View file

@ -8,14 +8,12 @@
#include "MyGUI_FactoryManager.h" #include "MyGUI_FactoryManager.h"
#include <components/misc/utf8stream.hpp> #include <components/misc/utf8stream.hpp>
#include <components/sceneutil/util.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwrender/util.hpp"
namespace MWGui namespace MWGui
{ {
struct TypesetBookImpl; struct TypesetBookImpl;
@ -1221,7 +1219,7 @@ public:
RenderXform renderXform (mCroppedParent, textFormat.mRenderItem->getRenderTarget()->getInfo()); RenderXform renderXform (mCroppedParent, textFormat.mRenderItem->getRenderTarget()->getInfo());
float z = MWBase::Environment::get().getResourceSystem()->getSceneManager()->getReverseZ() ? 1.0 : -1.0; float z = MWRender::getReverseZ() ? 1.f : -1.f;
GlyphStream glyphStream(textFormat.mFont, static_cast<float>(mCoord.left), static_cast<float>(mCoord.top - mViewTop), GlyphStream glyphStream(textFormat.mFont, static_cast<float>(mCoord.left), static_cast<float>(mCoord.top - mViewTop),
z /*mNode->getNodeDepth()*/, vertices, renderXform); z /*mNode->getNodeDepth()*/, vertices, renderXform);

View file

@ -741,7 +741,7 @@ namespace MWGui
} }
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue, bool reverseZ) MapWindow::MapWindow(CustomMarkerCollection &customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue)
: WindowPinnableBase("openmw_map_window.layout") : WindowPinnableBase("openmw_map_window.layout")
, LocalMapBase(customMarkers, localMapRender) , LocalMapBase(customMarkers, localMapRender)
, NoDrop(drag, mMainWidget) , NoDrop(drag, mMainWidget)
@ -751,7 +751,7 @@ namespace MWGui
, mGlobal(Settings::Manager::getBool("global", "Map")) , mGlobal(Settings::Manager::getBool("global", "Map"))
, mEventBoxGlobal(nullptr) , mEventBoxGlobal(nullptr)
, mEventBoxLocal(nullptr) , mEventBoxLocal(nullptr)
, mGlobalMapRender(new MWRender::GlobalMap(localMapRender->getRoot(), workQueue, reverseZ)) , mGlobalMapRender(new MWRender::GlobalMap(localMapRender->getRoot(), workQueue))
, mEditNoteDialog() , mEditNoteDialog()
{ {
static bool registered = false; static bool registered = false;

View file

@ -222,7 +222,7 @@ namespace MWGui
class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop class MapWindow : public MWGui::WindowPinnableBase, public LocalMapBase, public NoDrop
{ {
public: public:
MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue, bool reverseZ); MapWindow(CustomMarkerCollection& customMarkers, DragAndDrop* drag, MWRender::LocalMap* localMapRender, SceneUtil::WorkQueue* workQueue);
virtual ~MapWindow(); virtual ~MapWindow();
void setCellName(const std::string& cellName); void setCellName(const std::string& cellName);

View file

@ -35,7 +35,6 @@
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/imagemanager.hpp> #include <components/resource/imagemanager.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/workqueue.hpp> #include <components/sceneutil/workqueue.hpp>
@ -305,9 +304,8 @@ namespace MWGui
mGuiModeStates[GM_MainMenu] = GuiModeState(menu); mGuiModeStates[GM_MainMenu] = GuiModeState(menu);
mWindows.push_back(menu); mWindows.push_back(menu);
bool reverseZ = mResourceSystem->getSceneManager()->getReverseZ(); mLocalMapRender = new MWRender::LocalMap(mViewer->getSceneData()->asGroup());
mLocalMapRender = new MWRender::LocalMap(mViewer->getSceneData()->asGroup(), reverseZ); mMap = new MapWindow(mCustomMarkers, mDragAndDrop, mLocalMapRender, mWorkQueue);
mMap = new MapWindow(mCustomMarkers, mDragAndDrop, mLocalMapRender, mWorkQueue, reverseZ);
mWindows.push_back(mMap); mWindows.push_back(mMap);
mMap->renderGlobalMap(); mMap->renderGlobalMap();
trackWindow(mMap, "map"); trackWindow(mMap, "map");

View file

@ -2,9 +2,13 @@
#include "vismask.hpp" #include "vismask.hpp"
#include <components/sceneutil/agentpath.hpp> #include <components/sceneutil/agentpath.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
namespace MWRender namespace MWRender
{ {
ActorsPaths::ActorsPaths(const osg::ref_ptr<osg::Group>& root, bool enabled) ActorsPaths::ActorsPaths(const osg::ref_ptr<osg::Group>& root, bool enabled)
@ -43,6 +47,7 @@ namespace MWRender
const auto newGroup = SceneUtil::createAgentPathGroup(path, halfExtents, start, end, settings); const auto newGroup = SceneUtil::createAgentPathGroup(path, halfExtents, start, end, settings);
if (newGroup) if (newGroup)
{ {
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(newGroup, "debug");
newGroup->setNodeMask(Mask_Debug); newGroup->setNodeMask(Mask_Debug);
mRootNode->addChild(newGroup); mRootNode->addChild(newGroup);
mGroups[actor] = newGroup; mGroups[actor] = newGroup;

View file

@ -10,10 +10,19 @@
#include <osg/PolygonMode> #include <osg/PolygonMode>
#include <osg/ShapeDrawable> #include <osg/ShapeDrawable>
#include <osg/StateSet> #include <osg/StateSet>
#include <osg/Fog>
#include "bulletdebugdraw.hpp" #include "bulletdebugdraw.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/sceneutil/util.hpp>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
namespace MWRender namespace MWRender
{ {
@ -30,7 +39,6 @@ void DebugDrawer::createGeometry()
{ {
mGeometry = new osg::Geometry; mGeometry = new osg::Geometry;
mGeometry->setNodeMask(Mask_Debug); mGeometry->setNodeMask(Mask_Debug);
mVertices = new osg::Vec3Array; mVertices = new osg::Vec3Array;
mColors = new osg::Vec4Array; mColors = new osg::Vec4Array;
@ -42,6 +50,8 @@ void DebugDrawer::createGeometry()
mGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); mGeometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
mGeometry->setDataVariance(osg::Object::DYNAMIC); mGeometry->setDataVariance(osg::Object::DYNAMIC);
mGeometry->addPrimitiveSet(mDrawArrays); mGeometry->addPrimitiveSet(mDrawArrays);
// make this friendly to recreateShaders()
mGeometry->setStateSet(new osg::StateSet);
mParentNode->addChild(mGeometry); mParentNode->addChild(mGeometry);
@ -52,6 +62,8 @@ void DebugDrawer::createGeometry()
mShapesRoot->setDataVariance(osg::Object::DYNAMIC); mShapesRoot->setDataVariance(osg::Object::DYNAMIC);
mShapesRoot->setNodeMask(Mask_Debug); mShapesRoot->setNodeMask(Mask_Debug);
mParentNode->addChild(mShapesRoot); mParentNode->addChild(mShapesRoot);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mGeometry, "debug");
} }
} }

View file

@ -168,7 +168,7 @@ namespace MWRender
mCamera->setRenderOrder(osg::Camera::PRE_RENDER); mCamera->setRenderOrder(osg::Camera::PRE_RENDER);
mCamera->attach(osg::Camera::COLOR_BUFFER, mTexture, 0, 0, false, Settings::Manager::getInt("antialiasing", "Video")); mCamera->attach(osg::Camera::COLOR_BUFFER, mTexture, 0, 0, false, Settings::Manager::getInt("antialiasing", "Video"));
mCamera->setName("CharacterPreview"); mCamera->setName("CharacterPreview");
mCamera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); mCamera->setComputeNearFarMode(osg::Camera::COMPUTE_NEAR_FAR_USING_BOUNDING_VOLUMES);
mCamera->setCullMask(~(Mask_UpdateVisitor)); mCamera->setCullMask(~(Mask_UpdateVisitor));
mCamera->setNodeMask(Mask_RenderToTexture); mCamera->setNodeMask(Mask_RenderToTexture);
@ -187,6 +187,7 @@ namespace MWRender
defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1)); defaultMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4f(1,1,1,1));
defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f));
stateset->setAttribute(defaultMat); stateset->setAttribute(defaultMat);
stateset->addUniform(new osg::Uniform("projectionMatrix", static_cast<osg::Matrixf>(mCamera->getProjectionMatrix())));
osg::ref_ptr<osg::Depth> depth = new osg::Depth; osg::ref_ptr<osg::Depth> depth = new osg::Depth;
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON); stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);

View file

@ -25,6 +25,7 @@
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include "util.hpp"
namespace namespace
{ {
@ -220,14 +221,13 @@ namespace MWRender
osg::ref_ptr<osg::Texture2D> mOverlayTexture; osg::ref_ptr<osg::Texture2D> mOverlayTexture;
}; };
GlobalMap::GlobalMap(osg::Group* root, SceneUtil::WorkQueue* workQueue, bool reverseZ) GlobalMap::GlobalMap(osg::Group* root, SceneUtil::WorkQueue* workQueue)
: mRoot(root) : mRoot(root)
, mWorkQueue(workQueue) , mWorkQueue(workQueue)
, mWidth(0) , mWidth(0)
, mHeight(0) , mHeight(0)
, mMinX(0), mMaxX(0) , mMinX(0), mMaxX(0)
, mMinY(0), mMaxY(0) , mMinY(0), mMaxY(0)
, mReverseZ(reverseZ)
{ {
mCellSize = Settings::Manager::getInt("global map cell size", "Map"); mCellSize = Settings::Manager::getInt("global map cell size", "Map");
@ -325,7 +325,7 @@ namespace MWRender
if (texture) if (texture)
{ {
osg::ref_ptr<osg::Geometry> geom = createTexturedQuad(srcLeft, srcTop, srcRight, srcBottom); osg::ref_ptr<osg::Geometry> geom = createTexturedQuad(srcLeft, srcTop, srcRight, srcBottom);
auto depth = SceneUtil::createDepth(mReverseZ); auto depth = SceneUtil::createDepth(getReverseZ());
depth->setWriteMask(0); depth->setWriteMask(0);
osg::StateSet* stateset = geom->getOrCreateStateSet(); osg::StateSet* stateset = geom->getOrCreateStateSet();
stateset->setAttribute(depth); stateset->setAttribute(depth);

View file

@ -33,7 +33,7 @@ namespace MWRender
class GlobalMap class GlobalMap
{ {
public: public:
GlobalMap(osg::Group* root, SceneUtil::WorkQueue* workQueue, bool reverseZ); GlobalMap(osg::Group* root, SceneUtil::WorkQueue* workQueue);
~GlobalMap(); ~GlobalMap();
void render(); void render();
@ -126,8 +126,6 @@ namespace MWRender
int mHeight; int mHeight;
int mMinX, mMaxX, mMinY, mMaxY; int mMinX, mMaxX, mMinY, mMaxY;
bool mReverseZ;
}; };
} }

View file

@ -30,6 +30,7 @@
#include "../mwworld/cellstore.hpp" #include "../mwworld/cellstore.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include "util.hpp"
namespace namespace
{ {
@ -83,14 +84,13 @@ namespace
namespace MWRender namespace MWRender
{ {
LocalMap::LocalMap(osg::Group* root, bool reverseZ) LocalMap::LocalMap(osg::Group* root)
: mRoot(root) : mRoot(root)
, mMapResolution(Settings::Manager::getInt("local map resolution", "Map")) , mMapResolution(Settings::Manager::getInt("local map resolution", "Map"))
, mMapWorldSize(Constants::CellSizeInUnits) , mMapWorldSize(Constants::CellSizeInUnits)
, mCellDistance(Constants::CellGridRadius) , mCellDistance(Constants::CellGridRadius)
, mAngle(0.f) , mAngle(0.f)
, mInterior(false) , mInterior(false)
, mReverseZ(reverseZ)
{ {
// Increase map resolution, if use UI scaling // Increase map resolution, if use UI scaling
float uiScale = MWBase::Environment::get().getWindowManager()->getScalingFactor(); float uiScale = MWBase::Environment::get().getWindowManager()->getScalingFactor();
@ -178,7 +178,7 @@ osg::ref_ptr<osg::Camera> LocalMap::createOrthographicCamera(float x, float y, f
{ {
osg::ref_ptr<osg::Camera> camera (new osg::Camera); osg::ref_ptr<osg::Camera> camera (new osg::Camera);
if (mReverseZ) if (getReverseZ())
camera->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsOrtho(-width/2, width/2, -height/2, height/2, 5, (zmax-zmin) + 10)); camera->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsOrtho(-width/2, width/2, -height/2, height/2, 5, (zmax-zmin) + 10));
else else
camera->setProjectionMatrixAsOrtho(-width/2, width/2, -height/2, height/2, 5, (zmax-zmin) + 10); camera->setProjectionMatrixAsOrtho(-width/2, width/2, -height/2, height/2, 5, (zmax-zmin) + 10);
@ -201,13 +201,15 @@ osg::ref_ptr<osg::Camera> LocalMap::createOrthographicCamera(float x, float y, f
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet; osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
stateset->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), osg::StateAttribute::OVERRIDE); stateset->setAttribute(new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::FILL), osg::StateAttribute::OVERRIDE);
if (mReverseZ) if (getReverseZ())
{ {
camera->setClearDepth(0.0); camera->setClearDepth(0.0);
auto depth = SceneUtil::createDepth(mReverseZ); auto depth = SceneUtil::createDepth(true);
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); stateset->setAttributeAndModes(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
} }
stateset->addUniform(new osg::Uniform("projectionMatrix", static_cast<osg::Matrixf>(camera->getProjectionMatrix())), osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
// assign large value to effectively turn off fog // assign large value to effectively turn off fog
// shaders don't respect glDisable(GL_FOG) // shaders don't respect glDisable(GL_FOG)
osg::ref_ptr<osg::Fog> fog (new osg::Fog); osg::ref_ptr<osg::Fog> fog (new osg::Fog);

View file

@ -36,7 +36,7 @@ namespace MWRender
class LocalMap class LocalMap
{ {
public: public:
LocalMap(osg::Group* root, bool reverseZ); LocalMap(osg::Group* root);
~LocalMap(); ~LocalMap();
/** /**
@ -156,7 +156,6 @@ namespace MWRender
void setupRenderToTexture(osg::ref_ptr<osg::Camera> camera, int x, int y); void setupRenderToTexture(osg::ref_ptr<osg::Camera> camera, int x, int y);
bool mInterior; bool mInterior;
bool mReverseZ;
osg::BoundingBox mBounds; osg::BoundingBox mBounds;
}; };

View file

@ -2,9 +2,14 @@
#include "vismask.hpp" #include "vismask.hpp"
#include <components/sceneutil/navmesh.hpp> #include <components/sceneutil/navmesh.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
namespace MWRender namespace MWRender
{ {
NavMesh::NavMesh(const osg::ref_ptr<osg::Group>& root, bool enabled) NavMesh::NavMesh(const osg::ref_ptr<osg::Group>& root, bool enabled)
@ -45,6 +50,7 @@ namespace MWRender
mGroup = SceneUtil::createNavMeshGroup(navMesh, settings); mGroup = SceneUtil::createNavMeshGroup(navMesh, settings);
if (mGroup) if (mGroup)
{ {
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(mGroup, "debug");
mGroup->setNodeMask(Mask_Debug); mGroup->setNodeMask(Mask_Debug);
mRootNode->addChild(mGroup); mRootNode->addChild(mGroup);
} }

View file

@ -43,6 +43,7 @@
#include "rotatecontroller.hpp" #include "rotatecontroller.hpp"
#include "renderbin.hpp" #include "renderbin.hpp"
#include "vismask.hpp" #include "vismask.hpp"
#include "util.hpp"
namespace namespace
{ {
@ -370,9 +371,9 @@ void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)
class DepthClearCallback : public osgUtil::RenderBin::DrawCallback class DepthClearCallback : public osgUtil::RenderBin::DrawCallback
{ {
public: public:
DepthClearCallback(bool reverseZ) DepthClearCallback()
{ {
mDepth = SceneUtil::createDepth(reverseZ); mDepth = SceneUtil::createDepth(getReverseZ());
mDepth->setWriteMask(true); mDepth->setWriteMask(true);
} }
@ -432,7 +433,7 @@ void NpcAnimation::setRenderBin()
if (!prototypeAdded) if (!prototypeAdded)
{ {
osg::ref_ptr<osgUtil::RenderBin> depthClearBin (new osgUtil::RenderBin); osg::ref_ptr<osgUtil::RenderBin> depthClearBin (new osgUtil::RenderBin);
depthClearBin->setDrawCallback(new DepthClearCallback(mResourceSystem->getSceneManager()->getReverseZ())); depthClearBin->setDrawCallback(new DepthClearCallback);
osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin); osgUtil::RenderBin::addRenderBinPrototype("DepthClear", depthClearBin);
prototypeAdded = true; prototypeAdded = true;
} }

View file

@ -8,7 +8,10 @@
#include <components/esm/loadpgrd.hpp> #include <components/esm/loadpgrd.hpp>
#include <components/sceneutil/pathgridutil.hpp> #include <components/sceneutil/pathgridutil.hpp>
#include <components/sceneutil/util.hpp>
#include <components/misc/coordinateconverter.hpp> #include <components/misc/coordinateconverter.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone #include "../mwbase/world.hpp" // these includes can be removed once the static-hack is gone
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
@ -112,6 +115,8 @@ void Pathgrid::enableCellPathgrid(const MWWorld::CellStore *store)
osg::ref_ptr<osg::Geometry> geometry = SceneUtil::createPathgridGeometry(*pathgrid); osg::ref_ptr<osg::Geometry> geometry = SceneUtil::createPathgridGeometry(*pathgrid);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(geometry, "debug");
cellPathGrid->addChild(geometry); cellPathGrid->addChild(geometry);
mPathGridRoot->addChild(cellPathGrid); mPathGridRoot->addChild(cellPathGrid);

View file

@ -9,6 +9,11 @@
#include <osgViewer/Viewer> #include <osgViewer/Viewer>
#include <components/settings/settings.hpp> #include <components/settings/settings.hpp>
#include <components/sceneutil/util.hpp>
#include <components/debug/debuglog.hpp>
#include "vismask.hpp"
#include "renderingmanager.hpp"
namespace namespace
{ {
@ -57,6 +62,8 @@ namespace
traverse(node, nv); traverse(node, nv);
} }
private:
MWRender::PostProcessor* mPostProcessor; MWRender::PostProcessor* mPostProcessor;
unsigned int mLastFrameNumber; unsigned int mLastFrameNumber;
}; };
@ -70,6 +77,7 @@ namespace
void resizedImplementation(osg::GraphicsContext* gc, int x, int y, int width, int height) override void resizedImplementation(osg::GraphicsContext* gc, int x, int y, int width, int height) override
{ {
gc->resizedImplementation(x, y, width, height);
mPostProcessor->resize(width, height); mPostProcessor->resize(width, height);
} }
@ -79,22 +87,55 @@ namespace
namespace MWRender namespace MWRender
{ {
PostProcessor::PostProcessor(osgViewer::Viewer* viewer, osg::Group* rootNode) PostProcessor::PostProcessor(RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode)
: mViewer(viewer) : mViewer(viewer)
, mRootNode(new osg::Group) , mRootNode(new osg::Group)
, mRendering(rendering)
{ {
osg::GraphicsContext* gc = viewer->getCamera()->getGraphicsContext();
unsigned int contextID = gc->getState()->getContextID();
osg::GLExtensions* ext = gc->getState()->get<osg::GLExtensions>();
constexpr char errPreamble[] = "Postprocessing and floating point depth buffers disabled: ";
if (!ext->isFrameBufferObjectSupported)
{
Log(Debug::Warning) << errPreamble << "FrameBufferObject unsupported.";
return;
}
if (Settings::Manager::getInt("antialiasing", "Video") > 1 && !ext->isRenderbufferMultisampleSupported())
{
Log(Debug::Warning) << errPreamble << "RenderBufferMultiSample unsupported. Disabling antialiasing will resolve this issue.";
return;
}
if (osg::isGLExtensionSupported(contextID, "GL_ARB_depth_buffer_float"))
mDepthFormat = GL_DEPTH_COMPONENT32F;
else if (osg::isGLExtensionSupported(contextID, "GL_NV_depth_buffer_float"))
mDepthFormat = GL_DEPTH_COMPONENT32F_NV;
else
{
// TODO: Once we have post-processing implemented we want to skip this return and continue with setup.
// Rendering to a FBO to fullscreen geometry has overhead (especially when MSAA is enabled) and there are no
// benefits if no floating point depth formats are supported.
mDepthFormat = GL_DEPTH_COMPONENT24;
Log(Debug::Warning) << errPreamble << "'GL_ARB_depth_buffer_float' and 'GL_NV_depth_buffer_float' unsupported.";
return;
}
int width = viewer->getCamera()->getViewport()->width(); int width = viewer->getCamera()->getViewport()->width();
int height = viewer->getCamera()->getViewport()->height(); int height = viewer->getCamera()->getViewport()->height();
createTexturesAndCamera(width, height); createTexturesAndCamera(width, height);
resize(width, height); resize(width, height, true);
mRootNode->addChild(mHUDCamera); mRootNode->addChild(mHUDCamera);
mRootNode->addChild(rootNode); mRootNode->addChild(rootNode);
mViewer->setSceneData(mRootNode); mViewer->setSceneData(mRootNode);
// Main camera is treated specially, we need to manually set the FBO and // We need to manually set the FBO and resolve FBO during the cull callback. If we were using a separate
// resolve FBO during the cull callback. // RTT camera this would not be needed.
mViewer->getCamera()->addCullCallback(new CullCallback(this)); mViewer->getCamera()->addCullCallback(new CullCallback(this));
mViewer->getCamera()->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); mViewer->getCamera()->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
mViewer->getCamera()->attach(osg::Camera::COLOR_BUFFER0, mSceneTex); mViewer->getCamera()->attach(osg::Camera::COLOR_BUFFER0, mSceneTex);
@ -103,12 +144,12 @@ namespace MWRender
mViewer->getCamera()->getGraphicsContext()->setResizedCallback(new ResizedCallback(this)); mViewer->getCamera()->getGraphicsContext()->setResizedCallback(new ResizedCallback(this));
} }
void PostProcessor::resize(int width, int height) void PostProcessor::resize(int width, int height, bool init)
{ {
mDepthTex->setTextureSize(width, height); mDepthTex->setTextureSize(width, height);
mSceneTex->setTextureSize(width, height); mSceneTex->setTextureSize(width, height);
mDepthTex->dirtyTextureObject(); mDepthTex->dirtyTextureObject();
mSceneTex->dirtyTextureObject(); mSceneTex->dirtyTextureObject();
int samples = Settings::Manager::getInt("antialiasing", "Video"); int samples = Settings::Manager::getInt("antialiasing", "Video");
@ -130,15 +171,13 @@ namespace MWRender
mMsaaFbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(depthRB)); mMsaaFbo->setAttachment(osg::Camera::DEPTH_BUFFER, osg::FrameBufferAttachment(depthRB));
} }
double prevWidth = mViewer->getCamera()->getViewport()->width(); if (init)
double prevHeight = mViewer->getCamera()->getViewport()->height(); return;
double scaleX = prevWidth / width;
double scaleY = prevHeight / height;
mViewer->getCamera()->resize(width,height); mViewer->getCamera()->resize(width, height);
mHUDCamera->resize(width,height); mHUDCamera->resize(width, height);
mViewer->getCamera()->getProjectionMatrix() *= osg::Matrix::scale(scaleX, scaleY, 1.0); mRendering.updateProjectionMatrix();
} }
void PostProcessor::createTexturesAndCamera(int width, int height) void PostProcessor::createTexturesAndCamera(int width, int height)
@ -146,8 +185,8 @@ namespace MWRender
mDepthTex = new osg::Texture2D; mDepthTex = new osg::Texture2D;
mDepthTex->setTextureSize(width, height); mDepthTex->setTextureSize(width, height);
mDepthTex->setSourceFormat(GL_DEPTH_COMPONENT); mDepthTex->setSourceFormat(GL_DEPTH_COMPONENT);
mDepthTex->setSourceType(GL_FLOAT); mDepthTex->setSourceType(SceneUtil::isFloatingPointDepthFormat(getDepthFormat()) ? GL_FLOAT : GL_UNSIGNED_INT);
mDepthTex->setInternalFormat(GL_DEPTH_COMPONENT32F); mDepthTex->setInternalFormat(mDepthFormat);
mDepthTex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); mDepthTex->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
mDepthTex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST); mDepthTex->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
mDepthTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); mDepthTex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
@ -206,6 +245,7 @@ namespace MWRender
program->addShader(fragShader); program->addShader(fragShader);
mHUDCamera->addChild(createFullScreenTri()); mHUDCamera->addChild(createFullScreenTri());
mHUDCamera->setNodeMask(Mask_RenderToTexture);
auto* stateset = mHUDCamera->getOrCreateStateSet(); auto* stateset = mHUDCamera->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0, mSceneTex, osg::StateAttribute::ON); stateset->setTextureAttributeAndModes(0, mSceneTex, osg::StateAttribute::ON);

View file

@ -18,15 +18,19 @@ namespace osgViewer
namespace MWRender namespace MWRender
{ {
class RenderingManager;
class PostProcessor class PostProcessor
{ {
public: public:
PostProcessor(osgViewer::Viewer* viewer, osg::Group* rootNode); PostProcessor(RenderingManager& rendering, osgViewer::Viewer* viewer, osg::Group* rootNode);
auto getMsaaFbo() { return mMsaaFbo; } auto getMsaaFbo() { return mMsaaFbo; }
auto getFbo() { return mFbo; } auto getFbo() { return mFbo; }
void resize(int width, int height); int getDepthFormat() { return mDepthFormat; }
void resize(int width, int height, bool init=false);
private: private:
osgViewer::Viewer* mViewer; osgViewer::Viewer* mViewer;
@ -39,7 +43,11 @@ namespace MWRender
osg::ref_ptr<osg::Texture2D> mSceneTex; osg::ref_ptr<osg::Texture2D> mSceneTex;
osg::ref_ptr<osg::Texture2D> mDepthTex; osg::ref_ptr<osg::Texture2D> mDepthTex;
int mDepthFormat;
void createTexturesAndCamera(int width, int height); void createTexturesAndCamera(int width, int height);
RenderingManager& mRendering;
}; };
} }

View file

@ -1,11 +1,15 @@
#include "recastmesh.hpp" #include "recastmesh.hpp"
#include <components/sceneutil/recastmesh.hpp> #include <components/sceneutil/recastmesh.hpp>
#include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <osg/PositionAttitudeTransform> #include <osg/PositionAttitudeTransform>
#include "vismask.hpp" #include "vismask.hpp"
#include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp"
namespace MWRender namespace MWRender
{ {
RecastMesh::RecastMesh(const osg::ref_ptr<osg::Group>& root, bool enabled) RecastMesh::RecastMesh(const osg::ref_ptr<osg::Group>& root, bool enabled)
@ -49,6 +53,7 @@ namespace MWRender
|| it->second.mRevision != tile->second->getRevision()) || it->second.mRevision != tile->second->getRevision())
{ {
const auto group = SceneUtil::createRecastMeshGroup(*tile->second, settings); const auto group = SceneUtil::createRecastMeshGroup(*tile->second, settings);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
group->setNodeMask(Mask_Debug); group->setNodeMask(Mask_Debug);
mRootNode->removeChild(it->second.mValue); mRootNode->removeChild(it->second.mValue);
mRootNode->addChild(group); mRootNode->addChild(group);
@ -66,6 +71,7 @@ namespace MWRender
if (mGroups.count(tile.first)) if (mGroups.count(tile.first))
continue; continue;
const auto group = SceneUtil::createRecastMeshGroup(*tile.second, settings); const auto group = SceneUtil::createRecastMeshGroup(*tile.second, settings);
MWBase::Environment::get().getResourceSystem()->getSceneManager()->recreateShaders(group, "debug");
group->setNodeMask(Mask_Debug); group->setNodeMask(Mask_Debug);
mGroups.emplace(tile.first, Group {tile.second->getGeneration(), tile.second->getRevision(), group}); mGroups.emplace(tile.first, Group {tile.second->getGeneration(), tile.second->getRevision(), group});
mRootNode->addChild(group); mRootNode->addChild(group);

View file

@ -74,6 +74,45 @@
namespace MWRender namespace MWRender
{ {
class SharedUniformStateUpdater : public SceneUtil::StateSetUpdater
{
public:
SharedUniformStateUpdater()
: mLinearFac(0.f)
{
}
void setDefaults(osg::StateSet *stateset) override
{
stateset->addUniform(new osg::Uniform("projectionMatrix", osg::Matrixf{}));
stateset->addUniform(new osg::Uniform("linearFac", 0.f));
}
void apply(osg::StateSet* stateset, osg::NodeVisitor* nv) override
{
auto* uProjectionMatrix = stateset->getUniform("projectionMatrix");
if (uProjectionMatrix)
uProjectionMatrix->set(mProjectionMatrix);
auto* uLinearFac = stateset->getUniform("linearFac");
if (uLinearFac)
uLinearFac->set(mLinearFac);
}
void setProjectionMatrix(const osg::Matrixf& projectionMatrix)
{
mProjectionMatrix = projectionMatrix;
}
void setLinearFac(float linearFac)
{
mLinearFac = linearFac;
}
private:
osg::Matrixf mProjectionMatrix;
float mLinearFac;
};
class StateUpdater : public SceneUtil::StateSetUpdater class StateUpdater : public SceneUtil::StateSetUpdater
{ {
@ -202,10 +241,7 @@ namespace MWRender
, mFieldOfViewOverride(0.f) , mFieldOfViewOverride(0.f)
{ {
auto ext = osg::GLExtensions::Get(0, false); auto ext = osg::GLExtensions::Get(0, false);
bool reverseZ = ext && ext->isClipControlSupported; bool reverseZ = Settings::Manager::getBool("reverse z", "Camera") && ext && ext->isClipControlSupported;
if (getenv("OPENMW_DISABLE_REVERSEZ") != nullptr)
reverseZ = false;
if (reverseZ) if (reverseZ)
Log(Debug::Info) << "Using reverse-z depth buffer"; Log(Debug::Info) << "Using reverse-z depth buffer";
@ -219,7 +255,8 @@ namespace MWRender
bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders") bool forceShaders = Settings::Manager::getBool("radial fog", "Shaders")
|| Settings::Manager::getBool("force shaders", "Shaders") || Settings::Manager::getBool("force shaders", "Shaders")
|| Settings::Manager::getBool("enable shadows", "Shadows") || Settings::Manager::getBool("enable shadows", "Shadows")
|| lightingMethod != SceneUtil::LightingMethod::FFP; || lightingMethod != SceneUtil::LightingMethod::FFP
|| reverseZ;
resourceSystem->getSceneManager()->setForceShaders(forceShaders); resourceSystem->getSceneManager()->setForceShaders(forceShaders);
// FIXME: calling dummy method because terrain needs to know whether lighting is clamped // FIXME: calling dummy method because terrain needs to know whether lighting is clamped
resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders")); resourceSystem->getSceneManager()->setClampLighting(Settings::Manager::getBool("clamp lighting", "Shaders"));
@ -370,6 +407,10 @@ namespace MWRender
// Use a stub grid to avoid splitting between chunks for active grid and chunks for distant cells. // Use a stub grid to avoid splitting between chunks for active grid and chunks for distant cells.
mGroundcoverWorld->setActiveGrid(osg::Vec4i(0, 0, 0, 0)); mGroundcoverWorld->setActiveGrid(osg::Vec4i(0, 0, 0, 0));
} }
mPostProcessor.reset(new PostProcessor(*this, viewer, mRootNode));
resourceSystem->getSceneManager()->setDepthFormat(mPostProcessor->getDepthFormat());
// water goes after terrain for correct waterculling order // water goes after terrain for correct waterculling order
mWater.reset(new Water(sceneRoot->getParent(0), sceneRoot, mResourceSystem, mViewer->getIncrementalCompileOperation(), resourcePath)); mWater.reset(new Water(sceneRoot->getParent(0), sceneRoot, mResourceSystem, mViewer->getIncrementalCompileOperation(), resourcePath));
@ -412,6 +453,9 @@ namespace MWRender
mStateUpdater = new StateUpdater; mStateUpdater = new StateUpdater;
sceneRoot->addUpdateCallback(mStateUpdater); sceneRoot->addUpdateCallback(mStateUpdater);
mSharedUniformStateUpdater = new SharedUniformStateUpdater;
rootNode->addUpdateCallback(mSharedUniformStateUpdater);
osg::Camera::CullingMode cullingMode = osg::Camera::DEFAULT_CULLING|osg::Camera::FAR_PLANE_CULLING; osg::Camera::CullingMode cullingMode = osg::Camera::DEFAULT_CULLING|osg::Camera::FAR_PLANE_CULLING;
if (!Settings::Manager::getBool("small feature culling", "Camera")) if (!Settings::Manager::getBool("small feature culling", "Camera"))
@ -433,7 +477,9 @@ namespace MWRender
NifOsg::Loader::setReverseZ(reverseZ); NifOsg::Loader::setReverseZ(reverseZ);
Nif::NIFFile::setLoadUnsupportedFiles(Settings::Manager::getBool("load unsupported nif files", "Models")); Nif::NIFFile::setLoadUnsupportedFiles(Settings::Manager::getBool("load unsupported nif files", "Models"));
mNearClip = Settings::Manager::getFloat("near clip", "Camera"); // TODO: Near clip should not need to be bounded like this, but too small values break OSG shadow calculations CPU-side.
// See issue: #6072
mNearClip = std::max(0.005f, Settings::Manager::getFloat("near clip", "Camera"));
mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); mViewDistance = Settings::Manager::getFloat("viewing distance", "Camera");
float fov = Settings::Manager::getFloat("field of view", "Camera"); float fov = Settings::Manager::getFloat("field of view", "Camera");
mFieldOfView = std::min(std::max(1.f, fov), 179.f); mFieldOfView = std::min(std::max(1.f, fov), 179.f);
@ -462,11 +508,6 @@ namespace MWRender
mRootNode->getOrCreateStateSet()->setAttributeAndModes(clipcontrol, osg::StateAttribute::ON); mRootNode->getOrCreateStateSet()->setAttributeAndModes(clipcontrol, osg::StateAttribute::ON);
} }
if (ext && ext->isFrameBufferObjectSupported)
mPostProcessor.reset(new PostProcessor(viewer, mRootNode));
else
Log(Debug::Warning) << "Disabling postprocessing and using default framebuffer for rendering: FrameBufferObjects not supported";
updateProjectionMatrix(); updateProjectionMatrix();
} }
@ -1100,19 +1141,15 @@ namespace MWRender
if (mFieldOfViewOverridden) if (mFieldOfViewOverridden)
fov = mFieldOfViewOverride; fov = mFieldOfViewOverride;
mViewer->getCamera()->setProjectionMatrixAsPerspective(fov, aspect, mNearClip, mViewDistance);
if (mResourceSystem->getSceneManager()->getReverseZ()) if (mResourceSystem->getSceneManager()->getReverseZ())
{ {
mViewer->getCamera()->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsPerspectiveInf(fov, aspect, mNearClip)); mSharedUniformStateUpdater->setLinearFac(-mNearClip / (mViewDistance - mNearClip) - 1.f);
float linearFac = -mNearClip / (mViewDistance - mNearClip) - 1.0; mSharedUniformStateUpdater->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsPerspective(fov, aspect, mNearClip, mViewDistance));
mRootNode->getOrCreateStateSet()->getOrCreateUniform("linearFac", osg::Uniform::FLOAT, 1)->set(linearFac);
osg::Matrix shadowProj = osg::Matrix::perspective(fov, aspect, mNearClip, mViewDistance);
mViewer->getCamera()->setUserValue("shadowProj", shadowProj);
mViewer->getCamera()->setUserValue("near", static_cast<double>(mNearClip));
mViewer->getCamera()->setUserValue("far", static_cast<double>(mViewDistance));
} }
else else
mViewer->getCamera()->setProjectionMatrixAsPerspective(fov, aspect, mNearClip, mViewDistance); mSharedUniformStateUpdater->setProjectionMatrix(mViewer->getCamera()->getProjectionMatrix());
mUniformNear->set(mNearClip); mUniformNear->set(mNearClip);
mUniformFar->set(mViewDistance); mUniformFar->set(mViewDistance);

View file

@ -72,6 +72,7 @@ namespace MWRender
{ {
class GroundcoverUpdater; class GroundcoverUpdater;
class StateUpdater; class StateUpdater;
class SharedUniformStateUpdater;
class EffectManager; class EffectManager;
class ScreenshotManager; class ScreenshotManager;
@ -241,8 +242,8 @@ namespace MWRender
bool pagingUnlockCache(); bool pagingUnlockCache();
void getPagedRefnums(const osg::Vec4i &activeGrid, std::set<ESM::RefNum> &out); void getPagedRefnums(const osg::Vec4i &activeGrid, std::set<ESM::RefNum> &out);
private:
void updateProjectionMatrix(); void updateProjectionMatrix();
private:
void updateTextureFiltering(); void updateTextureFiltering();
void updateAmbient(); void updateAmbient();
void setFogColor(const osg::Vec4f& color); void setFogColor(const osg::Vec4f& color);
@ -296,6 +297,7 @@ namespace MWRender
osg::Vec3f mCurrentCameraPos; osg::Vec3f mCurrentCameraPos;
osg::ref_ptr<StateUpdater> mStateUpdater; osg::ref_ptr<StateUpdater> mStateUpdater;
osg::ref_ptr<SharedUniformStateUpdater> mSharedUniformStateUpdater;
osg::Vec4f mAmbientColor; osg::Vec4f mAmbientColor;
float mMinimumAmbientLuminance; float mMinimumAmbientLuminance;

View file

@ -298,7 +298,7 @@ namespace MWRender
camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF);
camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT,osg::Camera::PIXEL_BUFFER_RTT); camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT,osg::Camera::PIXEL_BUFFER_RTT);
if (MWBase::Environment::get().getResourceSystem()->getSceneManager()->getReverseZ()) if (getReverseZ())
camera->setClearDepth(0.0); camera->setClearDepth(0.0);
camera->setViewport(0, 0, w, h); camera->setViewport(0, 0, w, h);
@ -336,7 +336,7 @@ namespace MWRender
float nearClip = Settings::Manager::getFloat("near clip", "Camera"); float nearClip = Settings::Manager::getFloat("near clip", "Camera");
float viewDistance = Settings::Manager::getFloat("viewing distance", "Camera"); float viewDistance = Settings::Manager::getFloat("viewing distance", "Camera");
// each cubemap side sees 90 degrees // each cubemap side sees 90 degrees
if (MWBase::Environment::get().getResourceSystem()->getSceneManager()->getReverseZ()) if (getReverseZ())
rttCamera->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsPerspectiveInf(90.0, w/float(h), nearClip)); rttCamera->setProjectionMatrix(SceneUtil::getReversedZProjectionMatrixAsPerspectiveInf(90.0, w/float(h), nearClip));
else else
rttCamera->setProjectionMatrixAsPerspective(90.0, w/float(h), nearClip, viewDistance); rttCamera->setProjectionMatrixAsPerspective(90.0, w/float(h), nearClip, viewDistance);

View file

@ -54,6 +54,7 @@
#include "vismask.hpp" #include "vismask.hpp"
#include "renderbin.hpp" #include "renderbin.hpp"
#include "util.hpp"
namespace namespace
{ {
@ -473,7 +474,7 @@ const float CelestialBody::mDistance = 1000.0f;
class Sun : public CelestialBody class Sun : public CelestialBody
{ {
public: public:
Sun(osg::Group* parentNode, Resource::ImageManager& imageManager, bool reverseZ) Sun(osg::Group* parentNode, Resource::ImageManager& imageManager)
: CelestialBody(parentNode, 1.0f, 1, Mask_Sun) : CelestialBody(parentNode, 1.0f, 1, Mask_Sun)
, mUpdater(new Updater) , mUpdater(new Updater)
{ {
@ -502,8 +503,8 @@ public:
mTransform->addChild(queryNode); mTransform->addChild(queryNode);
mOcclusionQueryVisiblePixels = createOcclusionQueryNode(queryNode, true, reverseZ); mOcclusionQueryVisiblePixels = createOcclusionQueryNode(queryNode, true);
mOcclusionQueryTotalPixels = createOcclusionQueryNode(queryNode, false, reverseZ); mOcclusionQueryTotalPixels = createOcclusionQueryNode(queryNode, false);
createSunFlash(imageManager); createSunFlash(imageManager);
createSunGlare(); createSunGlare();
@ -556,7 +557,7 @@ private:
}; };
/// @param queryVisible If true, queries the amount of visible pixels. If false, queries the total amount of pixels. /// @param queryVisible If true, queries the amount of visible pixels. If false, queries the total amount of pixels.
osg::ref_ptr<osg::OcclusionQueryNode> createOcclusionQueryNode(osg::Group* parent, bool queryVisible, bool reverseZ) osg::ref_ptr<osg::OcclusionQueryNode> createOcclusionQueryNode(osg::Group* parent, bool queryVisible)
{ {
osg::ref_ptr<osg::OcclusionQueryNode> oqn = new osg::OcclusionQueryNode; osg::ref_ptr<osg::OcclusionQueryNode> oqn = new osg::OcclusionQueryNode;
oqn->setQueriesEnabled(true); oqn->setQueriesEnabled(true);
@ -594,11 +595,11 @@ private:
osg::StateSet* queryStateSet = new osg::StateSet; osg::StateSet* queryStateSet = new osg::StateSet;
if (queryVisible) if (queryVisible)
{ {
auto depth = SceneUtil::createDepth(reverseZ); auto depth = SceneUtil::createDepth(getReverseZ());
// This is a trick to make fragments written by the query always use the maximum depth value, // This is a trick to make fragments written by the query always use the maximum depth value,
// without having to retrieve the current far clipping distance. // without having to retrieve the current far clipping distance.
// We want the sun glare to be "infinitely" far away. // We want the sun glare to be "infinitely" far away.
float far = reverseZ ? 0.0 : 1.0; double far = getReverseZ() ? 0.0 : 1.0;
depth->setZNear(far); depth->setZNear(far);
depth->setZFar(far); depth->setZFar(far);
depth->setWriteMask(false); depth->setWriteMask(false);
@ -1188,8 +1189,7 @@ void SkyManager::create()
mAtmosphereNightUpdater = new AtmosphereNightUpdater(mSceneManager->getImageManager()); mAtmosphereNightUpdater = new AtmosphereNightUpdater(mSceneManager->getImageManager());
atmosphereNight->addUpdateCallback(mAtmosphereNightUpdater); atmosphereNight->addUpdateCallback(mAtmosphereNightUpdater);
bool reverseZ = mSceneManager->getReverseZ(); mSun.reset(new Sun(mEarlyRenderBinRoot, *mSceneManager->getImageManager()));
mSun.reset(new Sun(mEarlyRenderBinRoot, *mSceneManager->getImageManager(), reverseZ));
mMasser.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getImageManager(), Fallback::Map::getFloat("Moons_Masser_Size")/125, Moon::Type_Masser)); mMasser.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getImageManager(), Fallback::Map::getFloat("Moons_Masser_Size")/125, Moon::Type_Masser));
mSecunda.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getImageManager(), Fallback::Map::getFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda)); mSecunda.reset(new Moon(mEarlyRenderBinRoot, *mSceneManager->getImageManager(), Fallback::Map::getFloat("Moons_Secunda_Size")/125, Moon::Type_Secunda));
@ -1210,7 +1210,7 @@ void SkyManager::create()
mCloudMesh2->addUpdateCallback(mCloudUpdater2); mCloudMesh2->addUpdateCallback(mCloudUpdater2);
mCloudMesh2->setNodeMask(0); mCloudMesh2->setNodeMask(0);
auto depth = SceneUtil::createDepth(reverseZ); auto depth = SceneUtil::createDepth(mSceneManager->getReverseZ());
depth->setWriteMask(false); depth->setWriteMask(false);
mEarlyRenderBinRoot->getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON); mEarlyRenderBinRoot->getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON);
mEarlyRenderBinRoot->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); mEarlyRenderBinRoot->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);

View file

@ -4,10 +4,13 @@
#include <osg/ValueObject> #include <osg/ValueObject>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/resource/imagemanager.hpp> #include <components/resource/imagemanager.hpp>
#include <components/misc/resourcehelpers.hpp> #include <components/misc/resourcehelpers.hpp>
#include <components/sceneutil/visitor.hpp> #include <components/sceneutil/visitor.hpp>
#include "../mwbase/environment.hpp"
namespace MWRender namespace MWRender
{ {
@ -64,4 +67,9 @@ void overrideTexture(const std::string &texture, Resource::ResourceSystem *resou
node->setStateSet(stateset); node->setStateSet(stateset);
} }
bool getReverseZ()
{
return MWBase::Environment::get().getResourceSystem()->getSceneManager()->getReverseZ();
}
} }

View file

@ -32,6 +32,8 @@ namespace MWRender
// no traverse() // no traverse()
} }
}; };
bool getReverseZ();
} }
#endif #endif

View file

@ -285,6 +285,16 @@ namespace Resource
return mReverseZ; return mReverseZ;
} }
void SceneManager::setDepthFormat(GLenum format)
{
mDepthFormat = format;
}
GLenum SceneManager::getDepthFormat() const
{
return mDepthFormat;
}
void SceneManager::setAutoUseNormalMaps(bool use) void SceneManager::setAutoUseNormalMaps(bool use)
{ {
mAutoUseNormalMaps = use; mAutoUseNormalMaps = use;

View file

@ -95,6 +95,9 @@ namespace Resource
void setReverseZ(bool reverseZ); void setReverseZ(bool reverseZ);
bool getReverseZ() const; bool getReverseZ() const;
void setDepthFormat(GLenum format);
GLenum getDepthFormat() const;
/// @see ShaderVisitor::setAutoUseNormalMaps /// @see ShaderVisitor::setAutoUseNormalMaps
void setAutoUseNormalMaps(bool use); void setAutoUseNormalMaps(bool use);
@ -206,6 +209,7 @@ namespace Resource
SceneUtil::LightManager::SupportedMethods mSupportedLightingMethods; SceneUtil::LightManager::SupportedMethods mSupportedLightingMethods;
bool mConvertAlphaTestToAlphaToCoverage; bool mConvertAlphaTestToAlphaToCoverage;
bool mReverseZ; bool mReverseZ;
GLenum mDepthFormat;
osg::ref_ptr<MultiObjectCache> mInstanceCache; osg::ref_ptr<MultiObjectCache> mInstanceCache;

View file

@ -28,8 +28,6 @@
#include <sstream> #include <sstream>
#include "shadowsbin.hpp" #include "shadowsbin.hpp"
#include <components/sceneutil/util.hpp>
namespace { namespace {
using namespace osgShadow; using namespace osgShadow;
@ -350,11 +348,6 @@ void VDSMCameraCullCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
_projectionMatrix = cv->getProjectionMatrix(); _projectionMatrix = cv->getProjectionMatrix();
} }
bool isOrthographicViewFrustum(const osg::Matrix& m)
{
return m(0,3)==0.0 && m(1,3)==0.0 && m(2,3)==0.0;
}
} // namespace } // namespace
MWShadowTechnique::ComputeLightSpaceBounds::ComputeLightSpaceBounds(osg::Viewport* viewport, const osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix) : MWShadowTechnique::ComputeLightSpaceBounds::ComputeLightSpaceBounds(osg::Viewport* viewport, const osg::Matrixd& projectionMatrix, osg::Matrixd& viewMatrix) :
@ -988,9 +981,6 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
return; return;
} }
osg::Matrix shadowProj;
cv.getCurrentCamera()->getUserValue("shadowProj", shadowProj);
ViewDependentData* vdd = getViewDependentData(&cv); ViewDependentData* vdd = getViewDependentData(&cv);
if (!vdd) if (!vdd)
@ -1006,41 +996,34 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
osg::CullSettings::ComputeNearFarMode cachedNearFarMode = cv.getComputeNearFarMode(); osg::CullSettings::ComputeNearFarMode cachedNearFarMode = cv.getComputeNearFarMode();
osg::RefMatrix& viewProjectionMatrix = *cv.getProjectionMatrix();
// check whether this main views projection is perspective or orthographic
bool orthographicViewFrustum = viewProjectionMatrix(0,3)==0.0 &&
viewProjectionMatrix(1,3)==0.0 &&
viewProjectionMatrix(2,3)==0.0;
double minZNear = 0.0; double minZNear = 0.0;
double maxZFar = dbl_max; double maxZFar = dbl_max;
bool orthographicViewFrustum;
if (_reverseZ) if (cachedNearFarMode==osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
{ {
cv.getCurrentCamera()->getUserValue("near", minZNear); double left, right, top, bottom;
cv.getCurrentCamera()->getUserValue("far", maxZFar); if (orthographicViewFrustum)
orthographicViewFrustum = isOrthographicViewFrustum(shadowProj); {
viewProjectionMatrix.getOrtho(left, right, bottom, top, minZNear, maxZFar);
}
else
{
viewProjectionMatrix.getFrustum(left, right, bottom, top, minZNear, maxZFar);
}
OSG_INFO<<"minZNear="<<minZNear<<", maxZFar="<<maxZFar<<std::endl;
} }
else
// set the compute near/far mode to the highest quality setting to ensure we push the near plan out as far as possible
if (settings->getComputeNearFarModeOverride()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
{ {
osg::RefMatrix& viewProjectionMatrix = *cv.getProjectionMatrix(); cv.setComputeNearFarMode(settings->getComputeNearFarModeOverride());
// check whether this main views projection is perspective or orthographic
orthographicViewFrustum = isOrthographicViewFrustum(viewProjectionMatrix);
if (cachedNearFarMode==osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
{
double left, right, top, bottom;
if (orthographicViewFrustum)
{
viewProjectionMatrix.getOrtho(left, right, bottom, top, minZNear, maxZFar);
}
else
{
viewProjectionMatrix.getFrustum(left, right, bottom, top, minZNear, maxZFar);
}
}
// set the compute near/far mode to the highest quality setting to ensure we push the near plan out as far as possible
if (settings->getComputeNearFarModeOverride()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
{
cv.setComputeNearFarMode(settings->getComputeNearFarModeOverride());
}
} }
// 1. Traverse main scene graph // 1. Traverse main scene graph
@ -1052,9 +1035,6 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
cv.popStateSet(); cv.popStateSet();
if (_reverseZ)
cv.pushProjectionMatrix(new osg::RefMatrix(shadowProj));
if (cv.getComputeNearFarMode()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR) if (cv.getComputeNearFarMode()!=osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR)
{ {
OSG_INFO<<"Just done main subgraph traversak"<<std::endl; OSG_INFO<<"Just done main subgraph traversak"<<std::endl;
@ -1094,8 +1074,7 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
} }
// return compute near far mode back to it's original settings // return compute near far mode back to it's original settings
if (!_reverseZ) cv.setComputeNearFarMode(cachedNearFarMode);
cv.setComputeNearFarMode(cachedNearFarMode);
OSG_INFO<<"frustum.eye="<<frustum.eye<<", frustum.centerNearPlane, "<<frustum.centerNearPlane<<" distance = "<<(frustum.eye-frustum.centerNearPlane).length()<<std::endl; OSG_INFO<<"frustum.eye="<<frustum.eye<<", frustum.centerNearPlane, "<<frustum.centerNearPlane<<" distance = "<<(frustum.eye-frustum.centerNearPlane).length()<<std::endl;
@ -1480,8 +1459,6 @@ void MWShadowTechnique::cull(osgUtil::CullVisitor& cv)
prepareStateSetForRenderingShadow(*vdd, cv.getTraversalNumber()); prepareStateSetForRenderingShadow(*vdd, cv.getTraversalNumber());
} }
if (_reverseZ)
cv.popProjectionMatrix();
// OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()<<std::endl; // OSG_NOTICE<<"End of shadow setup Projection matrix "<<*cv.getProjectionMatrix()<<std::endl;
} }
@ -1670,9 +1647,11 @@ void MWShadowTechnique::createShaders()
_shadowCastingStateSet->addUniform(new osg::Uniform("alphaTestShadows", false)); _shadowCastingStateSet->addUniform(new osg::Uniform("alphaTestShadows", false));
osg::ref_ptr<osg::Depth> depth = new osg::Depth; osg::ref_ptr<osg::Depth> depth = new osg::Depth;
depth->setWriteMask(true); depth->setWriteMask(true);
osg::ref_ptr<osg::ClipControl> clipcontrol = new osg::ClipControl(osg::ClipControl::LOWER_LEFT, osg::ClipControl::NEGATIVE_ONE_TO_ONE);
if (_reverseZ) if (_reverseZ)
{
osg::ref_ptr<osg::ClipControl> clipcontrol = new osg::ClipControl(osg::ClipControl::LOWER_LEFT, osg::ClipControl::NEGATIVE_ONE_TO_ONE);
_shadowCastingStateSet->setAttribute(clipcontrol, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); _shadowCastingStateSet->setAttribute(clipcontrol, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
}
_shadowCastingStateSet->setAttribute(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); _shadowCastingStateSet->setAttribute(depth, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);
_shadowCastingStateSet->setMode(GL_DEPTH_CLAMP, osg::StateAttribute::ON); _shadowCastingStateSet->setMode(GL_DEPTH_CLAMP, osg::StateAttribute::ON);

View file

@ -95,8 +95,8 @@ namespace SceneUtil
} }
ShadowManager::ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager, bool reverseZ) ShadowManager::ShadowManager(osg::ref_ptr<osg::Group> sceneRoot, osg::ref_ptr<osg::Group> rootNode, unsigned int outdoorShadowCastingMask, unsigned int indoorShadowCastingMask, Shader::ShaderManager &shaderManager, bool reverseZ)
: mShadowedScene(new osgShadow::ShadowedScene) : mReverseZ(reverseZ)
, mReverseZ(reverseZ) , mShadowedScene(new osgShadow::ShadowedScene)
, mShadowTechnique(new MWShadowTechnique) , mShadowTechnique(new MWShadowTechnique)
, mOutdoorShadowCastingMask(outdoorShadowCastingMask) , mOutdoorShadowCastingMask(outdoorShadowCastingMask)
, mIndoorShadowCastingMask(indoorShadowCastingMask) , mIndoorShadowCastingMask(indoorShadowCastingMask)

View file

@ -9,6 +9,7 @@
#include <osg/TexGen> #include <osg/TexGen>
#include <osg/TexEnvCombine> #include <osg/TexEnvCombine>
#include <osg/Version> #include <osg/Version>
#include <osg/Fog>
#include <components/resource/imagemanager.hpp> #include <components/resource/imagemanager.hpp>
#include <components/resource/scenemanager.hpp> #include <components/resource/scenemanager.hpp>
@ -314,8 +315,7 @@ bool attachAlphaToCoverageFriendlyFramebufferToCamera(osg::Camera* camera, osg::
osg::ref_ptr<osg::Depth> createDepth(bool reverseZ) osg::ref_ptr<osg::Depth> createDepth(bool reverseZ)
{ {
static osg::Depth::Function func = reverseZ ? osg::Depth::GEQUAL : osg::Depth::LEQUAL; return new osg::Depth(reverseZ ? osg::Depth::GEQUAL : osg::Depth::LEQUAL);
return new osg::Depth(func);
} }
osg::Matrix getReversedZProjectionMatrixAsPerspectiveInf(double fov, double aspect, double near) osg::Matrix getReversedZProjectionMatrixAsPerspectiveInf(double fov, double aspect, double near)
@ -350,5 +350,9 @@ osg::Matrix getReversedZProjectionMatrixAsOrtho(double left, double right, doubl
); );
} }
bool isFloatingPointDepthFormat(GLenum format)
{
return format == GL_DEPTH_COMPONENT32F || format == GL_DEPTH_COMPONENT32F_NV;
}
} }

View file

@ -50,7 +50,7 @@ namespace SceneUtil
}; };
// Allows camera to render to a color and floating point depth texture with a multisampled framebuffer. // Allows camera to render to a color and floating point depth texture with a multisampled framebuffer.
// Must be set on a cameras cull callback. // Must be set on a camera's cull callback.
// When the depth texture isn't needed as a sampler, use osg::Camera::attach(osg::Camera::DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F) instead. // When the depth texture isn't needed as a sampler, use osg::Camera::attach(osg::Camera::DEPTH_COMPONENT, GL_DEPTH_COMPONENT32F) instead.
// If multisampling is not being used on the color buffer attachment, use the osg::Camera::attach() method. // If multisampling is not being used on the color buffer attachment, use the osg::Camera::attach() method.
class AttachMultisampledDepthColorCallback : public osg::NodeCallback class AttachMultisampledDepthColorCallback : public osg::NodeCallback
@ -99,6 +99,8 @@ namespace SceneUtil
// Returns an orthographic projection matrix for use with a reversed z-buffer. // Returns an orthographic projection matrix for use with a reversed z-buffer.
osg::Matrix getReversedZProjectionMatrixAsOrtho(double left, double right, double bottom, double top, double near, double far); osg::Matrix getReversedZProjectionMatrixAsOrtho(double left, double right, double bottom, double top, double near, double far);
// Returns true if the GL format is a floating point depth format
bool isFloatingPointDepthFormat(GLenum format);
} }
#endif #endif

View file

@ -8,13 +8,16 @@
#include "world.hpp" #include "world.hpp"
#include "../esm/loadland.hpp" #include "../esm/loadland.hpp"
#include <components/resource/scenemanager.hpp>
namespace Terrain namespace Terrain
{ {
CellBorder::CellBorder(Terrain::World *world, osg::Group *root, int borderMask): CellBorder::CellBorder(Terrain::World *world, osg::Group *root, int borderMask, Resource::SceneManager* sceneManager)
mWorld(world), : mWorld(world)
mRoot(root), , mSceneManager(sceneManager)
mBorderMask(borderMask) , mRoot(root)
, mBorderMask(borderMask)
{ {
} }
@ -73,6 +76,8 @@ void CellBorder::createCellBorderGeometry(int x, int y)
polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); polygonmode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON); stateSet->setAttributeAndModes(polygonmode,osg::StateAttribute::ON);
mSceneManager->recreateShaders(borderGeode, "debug");
borderGeode->setNodeMask(mBorderMask); borderGeode->setNodeMask(mBorderMask);
mRoot->addChild(borderGeode); mRoot->addChild(borderGeode);

View file

@ -4,6 +4,11 @@
#include <map> #include <map>
#include <osg/Group> #include <osg/Group>
namespace Resource
{
class SceneManager;
}
namespace Terrain namespace Terrain
{ {
class World; class World;
@ -16,7 +21,7 @@ namespace Terrain
public: public:
typedef std::map<std::pair<int, int>, osg::ref_ptr<osg::Node> > CellGrid; typedef std::map<std::pair<int, int>, osg::ref_ptr<osg::Node> > CellGrid;
CellBorder(Terrain::World *world, osg::Group *root, int borderMask); CellBorder(Terrain::World *world, osg::Group *root, int borderMask, Resource::SceneManager* sceneManager);
void createCellBorderGeometry(int x, int y); void createCellBorderGeometry(int x, int y);
void destroyCellBorderGeometry(int x, int y); void destroyCellBorderGeometry(int x, int y);
@ -28,6 +33,7 @@ namespace Terrain
protected: protected:
Terrain::World *mWorld; Terrain::World *mWorld;
Resource::SceneManager* mSceneManager;
osg::Group *mRoot; osg::Group *mRoot;
CellGrid mCellBorderNodes; CellGrid mCellBorderNodes;

View file

@ -4,6 +4,7 @@
#include <osg/Camera> #include <osg/Camera>
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include <components/resource/scenemanager.hpp>
#include "storage.hpp" #include "storage.hpp"
#include "texturemanager.hpp" #include "texturemanager.hpp"
@ -43,7 +44,7 @@ World::World(osg::Group* parent, osg::Group* compileRoot, Resource::ResourceSyst
mTextureManager.reset(new TextureManager(mResourceSystem->getSceneManager())); mTextureManager.reset(new TextureManager(mResourceSystem->getSceneManager()));
mChunkManager.reset(new ChunkManager(mStorage, mResourceSystem->getSceneManager(), mTextureManager.get(), mCompositeMapRenderer)); mChunkManager.reset(new ChunkManager(mStorage, mResourceSystem->getSceneManager(), mTextureManager.get(), mCompositeMapRenderer));
mChunkManager->setNodeMask(nodeMask); mChunkManager->setNodeMask(nodeMask);
mCellBorder.reset(new CellBorder(this,mTerrainRoot.get(),borderMask)); mCellBorder.reset(new CellBorder(this,mTerrainRoot.get(),borderMask,mResourceSystem->getSceneManager()));
mResourceSystem->addResourceManager(mChunkManager.get()); mResourceSystem->addResourceManager(mChunkManager.get());
mResourceSystem->addResourceManager(mTextureManager.get()); mResourceSystem->addResourceManager(mTextureManager.get());

View file

@ -5,8 +5,8 @@ near clip
--------- ---------
:Type: floating point :Type: floating point
:Range: > 0 :Range: >= 0.005
:Default: 3.0 :Default: 1.0
This setting controls the distance to the near clipping plane. The value must be greater than zero. This setting controls the distance to the near clipping plane. The value must be greater than zero.
Values greater than approximately 18.0 will occasionally clip objects in the world in front of the character. Values greater than approximately 18.0 will occasionally clip objects in the world in front of the character.
@ -235,3 +235,23 @@ Maximum roll angle in degrees.
This setting can only be configured by editing the settings configuration file. This setting can only be configured by editing the settings configuration file.
reverse z
---------
:Type: boolean
:Range: True/False
:Default: True
Enables a reverse-z depth buffer in which the depth range is reversed. This
allows for small :ref:`near clip` values and removes almost all z-fighting with
terrain and even tightly coupled meshes at extreme view distances. For this to
be useful, a floating point depth buffer is required. These features require
driver and hardware support, but should work on any semi-modern desktop hardware
through OpenGL extensions. The exception is macOS, which has since dropped
development of OpenGL drivers. If unsupported, this setting has no effect.
Note, this will force OpenMW to use shaders as if :ref:`force shaders` was enabled.
The performance impact of this feature should be negligible.
This setting can only be configured by editing the settings configuration file.

View file

@ -15,7 +15,7 @@
[Camera] [Camera]
# Near clipping plane (>0.0, e.g. 0.01 to 18.0). # Near clipping plane (>0.0, e.g. 0.01 to 18.0).
near clip = 3 near clip = 1
# Cull objects that occupy less than 'small feature culling pixel size' on the screen. # Cull objects that occupy less than 'small feature culling pixel size' on the screen.
small feature culling = true small feature culling = true
@ -67,6 +67,9 @@ head bobbing height = 3.0
# Maximum camera roll angle (degrees) # Maximum camera roll angle (degrees)
head bobbing roll = 0.2 head bobbing roll = 0.2
# Reverse the depth range from [0,1] to [1,0].
reverse z = true
[Cells] [Cells]
# Preload cells in a background thread. All settings starting with 'preload' have no effect unless this is enabled. # Preload cells in a background thread. All settings starting with 'preload' have no effect unless this is enabled.

View file

@ -34,6 +34,8 @@ set(SHADER_FILES
nv_nolighting_fragment.glsl nv_nolighting_fragment.glsl
gui_vertex.glsl gui_vertex.glsl
gui_fragment.glsl gui_fragment.glsl
debug_vertex.glsl
debug_fragment.glsl
) )
copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_SHADERS_ROOT} ${DDIRRELATIVE} "${SHADER_FILES}") copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_SHADERS_ROOT} ${DDIRRELATIVE} "${SHADER_FILES}")

View file

@ -0,0 +1,8 @@
#version 120
varying vec4 passColor;
void main()
{
gl_FragData[0] = passColor;
}

View file

@ -0,0 +1,12 @@
#version 120
uniform mat4 projectionMatrix;
varying vec4 passColor;
void main()
{
gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
passColor = gl_Color;
}

View file

@ -2,11 +2,11 @@
uniform float linearFac; uniform float linearFac;
#endif #endif
float getLinearDepth(in vec4 viewPos) float getLinearDepth(in float z, in float viewZ)
{ {
#if @reverseZ #if @reverseZ
return linearFac*viewPos.z; return linearFac*viewZ;
#else #else
return gl_Position.z; return z;
#endif #endif
} }

View file

@ -46,6 +46,7 @@ uniform mat4 osg_ViewMatrixInverse;
uniform mat4 osg_ViewMatrix; uniform mat4 osg_ViewMatrix;
uniform float windSpeed; uniform float windSpeed;
uniform vec3 playerPos; uniform vec3 playerPos;
uniform mat4 projectionMatrix;
#if @groundcoverStompMode == 0 #if @groundcoverStompMode == 0
#else #else
@ -142,9 +143,9 @@ void main(void)
if (length(gl_ModelViewMatrix * vec4(position, 1.0)) > @groundcoverFadeEnd) if (length(gl_ModelViewMatrix * vec4(position, 1.0)) > @groundcoverFadeEnd)
gl_Position = vec4(0.0, 0.0, 0.0, 1.0); gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
else else
gl_Position = gl_ProjectionMatrix * viewPos; gl_Position = projectionMatrix * viewPos;
linearDepth = getLinearDepth(viewPos); linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
#if (!PER_PIXEL_LIGHTING || @shadows_enabled) #if (!PER_PIXEL_LIGHTING || @shadows_enabled)
vec3 viewNormal = normalize((gl_NormalMatrix * rotation3(rotation) * gl_Normal).xyz); vec3 viewNormal = normalize((gl_NormalMatrix * rotation3(rotation) * gl_Normal).xyz);

View file

@ -8,6 +8,8 @@
#extension GL_EXT_gpu_shader4: require #extension GL_EXT_gpu_shader4: require
#endif #endif
uniform mat4 projectionMatrix;
#if @diffuseMap #if @diffuseMap
varying vec2 diffuseMapUV; varying vec2 diffuseMapUV;
#endif #endif
@ -36,12 +38,12 @@ varying vec3 passNormal;
void main(void) void main(void)
{ {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex); vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
gl_ClipVertex = viewPos; gl_ClipVertex = viewPos;
euclideanDepth = length(viewPos.xyz); euclideanDepth = length(viewPos.xyz);
linearDepth = getLinearDepth(viewPos); linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
#if @diffuseMap #if @diffuseMap
diffuseMapUV = (gl_TextureMatrix[@diffuseMapUV] * gl_MultiTexCoord@diffuseMapUV).xy; diffuseMapUV = (gl_TextureMatrix[@diffuseMapUV] * gl_MultiTexCoord@diffuseMapUV).xy;

View file

@ -1,5 +1,7 @@
#version 120 #version 120
uniform mat4 projectionMatrix;
#if @diffuseMap #if @diffuseMap
varying vec2 diffuseMapUV; varying vec2 diffuseMapUV;
#endif #endif
@ -21,14 +23,14 @@ varying float passFalloff;
void main(void) void main(void)
{ {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex); vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
gl_ClipVertex = viewPos; gl_ClipVertex = viewPos;
#if @radialFog #if @radialFog
euclideanDepth = length(viewPos.xyz); euclideanDepth = length(viewPos.xyz);
#else #else
linearDepth = getLinearDepth(viewPos); linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
#endif #endif
#if @diffuseMap #if @diffuseMap

View file

@ -8,6 +8,8 @@
#extension GL_EXT_gpu_shader4: require #extension GL_EXT_gpu_shader4: require
#endif #endif
uniform mat4 projectionMatrix;
#if @diffuseMap #if @diffuseMap
varying vec2 diffuseMapUV; varying vec2 diffuseMapUV;
#endif #endif
@ -66,12 +68,13 @@ varying vec3 passNormal;
void main(void) void main(void)
{ {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex); vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
gl_ClipVertex = viewPos; gl_ClipVertex = viewPos;
euclideanDepth = length(viewPos.xyz); euclideanDepth = length(viewPos.xyz);
linearDepth = getLinearDepth(viewPos); linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
#if (@envMap || !PER_PIXEL_LIGHTING || @shadows_enabled) #if (@envMap || !PER_PIXEL_LIGHTING || @shadows_enabled)
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz); vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);

View file

@ -8,6 +8,8 @@
#extension GL_EXT_gpu_shader4: require #extension GL_EXT_gpu_shader4: require
#endif #endif
uniform mat4 projectionMatrix;
varying vec2 uv; varying vec2 uv;
varying float euclideanDepth; varying float euclideanDepth;
varying float linearDepth; varying float linearDepth;
@ -29,12 +31,12 @@ varying vec3 passNormal;
void main(void) void main(void)
{ {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex); vec4 viewPos = (gl_ModelViewMatrix * gl_Vertex);
gl_ClipVertex = viewPos; gl_ClipVertex = viewPos;
euclideanDepth = length(viewPos.xyz); euclideanDepth = length(viewPos.xyz);
linearDepth = getLinearDepth(viewPos); linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
#if (!PER_PIXEL_LIGHTING || @shadows_enabled) #if (!PER_PIXEL_LIGHTING || @shadows_enabled)
vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz); vec3 viewNormal = normalize((gl_NormalMatrix * gl_Normal).xyz);

View file

@ -1,5 +1,7 @@
#version 120 #version 120
uniform mat4 projectionMatrix;
varying vec3 screenCoordsPassthrough; varying vec3 screenCoordsPassthrough;
varying vec4 position; varying vec4 position;
varying float linearDepth; varying float linearDepth;
@ -9,7 +11,7 @@ varying float linearDepth;
void main(void) void main(void)
{ {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_Position = projectionMatrix * (gl_ModelViewMatrix * gl_Vertex);
mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.0, mat4 scalemat = mat4(0.5, 0.0, 0.0, 0.0,
0.0, -0.5, 0.0, 0.0, 0.0, -0.5, 0.0, 0.0,
@ -22,7 +24,7 @@ void main(void)
position = gl_Vertex; position = gl_Vertex;
vec4 viewPos = gl_ModelViewMatrix * gl_Vertex; vec4 viewPos = gl_ModelViewMatrix * gl_Vertex;
linearDepth = getLinearDepth(viewPos); linearDepth = getLinearDepth(gl_Position.z, viewPos.z);
setupShadowCoords(viewPos, normalize((gl_NormalMatrix * gl_Normal).xyz)); setupShadowCoords(viewPos, normalize((gl_NormalMatrix * gl_Normal).xyz));
} }