diff --git a/apps/openmw/mwrender/localmap.cpp b/apps/openmw/mwrender/localmap.cpp index 66d41a47e4..a3c8d6b2ce 100644 --- a/apps/openmw/mwrender/localmap.cpp +++ b/apps/openmw/mwrender/localmap.cpp @@ -187,7 +187,7 @@ osg::ref_ptr LocalMap::createOrthographicCamera(float x, float y, f camera->setReferenceFrame(osg::Camera::ABSOLUTE_RF_INHERIT_VIEWPOINT); camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT); camera->setClearColor(osg::Vec4(0.f, 0.f, 0.f, 1.f)); - camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); camera->setRenderOrder(osg::Camera::PRE_RENDER); camera->setCullMask(Mask_Scene | Mask_SimpleWater | Mask_Terrain | Mask_Object | Mask_Static); diff --git a/apps/openmw/mwrender/screenshotmanager.cpp b/apps/openmw/mwrender/screenshotmanager.cpp index 5c3d925c9b..90e6eec124 100644 --- a/apps/openmw/mwrender/screenshotmanager.cpp +++ b/apps/openmw/mwrender/screenshotmanager.cpp @@ -348,7 +348,7 @@ namespace MWRender rttCamera->setCullMask(mViewer->getCamera()->getCullMask() & ~(Mask_GUI|Mask_FirstPerson)); - rttCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + rttCamera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); renderCameraToImage(rttCamera.get(),image,w,h); } diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index db1dbc4d2c..87ffeb232c 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -310,17 +310,9 @@ namespace NifOsg if (mHasHerbalismLabel) created->getOrCreateUserDataContainer()->addDescription(Constants::HerbalismLabel); - // Morrowind is particular about draw order with stenciling, there is no real way around not using traversal order drawing. - static osg::ref_ptr traversalOrderBin; - - if (!traversalOrderBin) - { - traversalOrderBin = new osgUtil::RenderBin(osgUtil::RenderBin::TRAVERSAL_ORDER); - osgUtil::RenderBin::addRenderBinPrototype("TraversalOrder", traversalOrderBin); - } - + // When dealing with stencil buffer, draw order is especially sensitive. Make sure such objects are drawn with traversal order. if (mHasStencilProperty) - created->getOrCreateStateSet()->setRenderBinDetails(2, "TraversalOrder"); + created->getOrCreateStateSet()->setRenderBinDetails(2, "TraversalOrderBin"); // Attach particle emitters to their nodes which should all be loaded by now. handleQueuedParticleEmitters(created, nif); diff --git a/components/sceneutil/rtt.cpp b/components/sceneutil/rtt.cpp index 0765a2e835..9fe9a44516 100644 --- a/components/sceneutil/rtt.cpp +++ b/components/sceneutil/rtt.cpp @@ -50,7 +50,7 @@ namespace SceneUtil osg::Texture* RTTNode::getDepthTexture(osgUtil::CullVisitor* cv) { - return getViewDependentData(cv)->mCamera->getBufferAttachmentMap()[osg::Camera::DEPTH_BUFFER]._texture; + return getViewDependentData(cv)->mCamera->getBufferAttachmentMap()[osg::Camera::PACKED_DEPTH_STENCIL_BUFFER]._texture; } RTTNode::ViewDependentData* RTTNode::getViewDependentData(osgUtil::CullVisitor* cv) @@ -67,7 +67,7 @@ namespace SceneUtil mViewDependentDataMap[cv]->mCamera = camera; camera->setRenderOrder(osg::Camera::PRE_RENDER, mRenderOrderNum); - camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); camera->setViewport(0, 0, mTextureWidth, mTextureHeight); SceneUtil::setCameraClearDepth(camera); @@ -88,18 +88,18 @@ namespace SceneUtil SceneUtil::attachAlphaToCoverageFriendlyFramebufferToCamera(camera, osg::Camera::COLOR_BUFFER, colorBuffer); } - if (camera->getBufferAttachmentMap().count(osg::Camera::DEPTH_BUFFER) == 0) + if (camera->getBufferAttachmentMap().count(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER) == 0) { auto depthBuffer = new osg::Texture2D; depthBuffer->setTextureSize(mTextureWidth, mTextureHeight); - depthBuffer->setSourceFormat(GL_DEPTH_COMPONENT); - depthBuffer->setInternalFormat(GL_DEPTH_COMPONENT24); + depthBuffer->setSourceFormat(GL_DEPTH_STENCIL_EXT); + depthBuffer->setInternalFormat(GL_DEPTH24_STENCIL8_EXT); depthBuffer->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); depthBuffer->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); - depthBuffer->setSourceType(GL_UNSIGNED_INT); + depthBuffer->setSourceType(GL_UNSIGNED_INT_24_8_EXT); depthBuffer->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); depthBuffer->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); - camera->attach(osg::Camera::DEPTH_BUFFER, depthBuffer); + camera->attach(osg::Camera::PACKED_DEPTH_STENCIL_BUFFER, depthBuffer); } } diff --git a/components/sceneutil/rtt.hpp b/components/sceneutil/rtt.hpp index 7adfa098eb..c587006c96 100644 --- a/components/sceneutil/rtt.hpp +++ b/components/sceneutil/rtt.hpp @@ -27,7 +27,7 @@ namespace SceneUtil /// @par Camera settings should be effectuated by overriding the setDefaults() and apply() methods, following a pattern similar to SceneUtil::StateSetUpdater /// @par When using the RTT texture in your statesets, it is recommended to use SceneUtil::StateSetUpdater as a cull callback to handle this as the appropriate /// textures can be retrieved during SceneUtil::StateSetUpdater::Apply() - /// @par For any of COLOR_BUFFER or DEPTH_BUFFER not added during setDefaults(), RTTNode will attach a default buffer. The default color buffer has an internal format of GL_RGB. + /// @par For any of COLOR_BUFFER or PACKED_DEPTH_STENCIL_BUFFER not added during setDefaults(), RTTNode will attach a default buffer. The default color buffer has an internal format of GL_RGB. /// The default depth buffer has internal format GL_DEPTH_COMPONENT24, source format GL_DEPTH_COMPONENT, and source type GL_UNSIGNED_INT. Default wrap is CLAMP_TO_EDGE and filter LINEAR. class RTTNode : public osg::Node {