diff --git a/apps/openmw_test_suite/nifosg/testnifloader.cpp b/apps/openmw_test_suite/nifosg/testnifloader.cpp index a82fba15ca..5c37cb375f 100644 --- a/apps/openmw_test_suite/nifosg/testnifloader.cpp +++ b/apps/openmw_test_suite/nifosg/testnifloader.cpp @@ -156,6 +156,16 @@ osg::Group { StateSet TRUE { osg::StateSet { UniqueID 9 + ModeList 1 { + GL_DEPTH_TEST ON + } + AttributeList 1 { + osg::Depth { + UniqueID 10 + WriteMask FALSE + } + Value OFF + } } } } diff --git a/components/nif/property.hpp b/components/nif/property.hpp index da908f2eab..eaaa972c39 100644 --- a/components/nif/property.hpp +++ b/components/nif/property.hpp @@ -109,6 +109,12 @@ namespace Nif { BSSFlag1_Specular = 0x00000001, BSSFlag1_Decal = 0x04000000, + BSSFlag1_DepthTest = 0x80000000, + }; + + enum BSShaderFlags2 + { + BSSFlag2_DepthWrite = 0x00000001, }; struct BSSPParallaxParams @@ -140,6 +146,8 @@ namespace Nif // Shader-specific flag methods must be handled on per-record basis bool specular() const { return mShaderFlags1 & BSSFlag1_Specular; } bool decal() const { return mShaderFlags1 & BSSFlag1_Decal; } + bool depthTest() const { return mShaderFlags1 & BSSFlag1_DepthTest; } + bool depthWrite() const { return mShaderFlags2 & BSSFlag2_DepthWrite; } }; struct BSShaderLightingProperty : BSShaderProperty diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index 9945a8c40e..5b98f54599 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -1964,6 +1964,15 @@ namespace NifOsg return texEnv; } + void handleDepthFlags(osg::StateSet* stateset, bool depthTest, bool depthWrite, + osg::Depth::Function depthFunction = osg::Depth::LESS) + { + stateset->setMode(GL_DEPTH_TEST, depthTest ? osg::StateAttribute::ON : osg::StateAttribute::OFF); + osg::ref_ptr depth = new osg::Depth(depthFunction, 0.0, 1.0, depthWrite); + depth = shareAttribute(depth); + stateset->setAttributeAndModes(depth, osg::StateAttribute::ON); + } + void handleTextureProperty(const Nif::NiTexturingProperty* texprop, const std::string& nodeName, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector& boundTextures, int animflags) @@ -2319,16 +2328,10 @@ namespace NifOsg { const Nif::NiZBufferProperty* zprop = static_cast(property); osg::StateSet* stateset = node->getOrCreateStateSet(); - stateset->setMode( - GL_DEPTH_TEST, zprop->depthTest() ? osg::StateAttribute::ON : osg::StateAttribute::OFF); - osg::ref_ptr depth = new osg::Depth; - depth->setWriteMask(zprop->depthWrite()); // Morrowind ignores depth test function, unless a NiStencilProperty is present, in which case it // uses a fixed depth function of GL_ALWAYS. - if (hasStencilProperty) - depth->setFunction(osg::Depth::ALWAYS); - depth = shareAttribute(depth); - stateset->setAttributeAndModes(depth, osg::StateAttribute::ON); + osg::Depth::Function depthFunction = hasStencilProperty ? osg::Depth::ALWAYS : osg::Depth::LESS; + handleDepthFlags(stateset, zprop->depthTest(), zprop->depthWrite(), depthFunction); break; } // OSG groups the material properties that NIFs have separate, so we have to parse them all again when @@ -2367,6 +2370,7 @@ namespace NifOsg textureSet, texprop->mClamp, node->getName(), stateset, imageManager, boundTextures); } handleTextureControllers(texprop, composite, imageManager, stateset, animflags); + handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite()); break; } case Nif::RC_BSShaderNoLightingProperty: @@ -2405,6 +2409,7 @@ namespace NifOsg } stateset->addUniform(new osg::Uniform("useFalloff", useFalloff)); handleTextureControllers(texprop, composite, imageManager, stateset, animflags); + handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite()); break; } case Nif::RC_BSLightingShaderProperty: @@ -2422,6 +2427,7 @@ namespace NifOsg stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); if (texprop->treeAnim()) stateset->addUniform(new osg::Uniform("useTreeAnim", true)); + handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite()); break; } case Nif::RC_BSEffectShaderProperty: @@ -2477,6 +2483,7 @@ namespace NifOsg handleTextureControllers(texprop, composite, imageManager, stateset, animflags); if (texprop->doubleSided()) stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); + handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite()); break; } // unused by mw