Support BSShader/BSLightingShader depth flags

macos_ci_fix
Alexei Kotov 1 year ago
parent 3baefdf29e
commit af08205f19

@ -156,6 +156,16 @@ osg::Group {
StateSet TRUE { StateSet TRUE {
osg::StateSet { osg::StateSet {
UniqueID 9 UniqueID 9
ModeList 1 {
GL_DEPTH_TEST ON
}
AttributeList 1 {
osg::Depth {
UniqueID 10
WriteMask FALSE
}
Value OFF
}
} }
} }
} }

@ -109,6 +109,12 @@ namespace Nif
{ {
BSSFlag1_Specular = 0x00000001, BSSFlag1_Specular = 0x00000001,
BSSFlag1_Decal = 0x04000000, BSSFlag1_Decal = 0x04000000,
BSSFlag1_DepthTest = 0x80000000,
};
enum BSShaderFlags2
{
BSSFlag2_DepthWrite = 0x00000001,
}; };
struct BSSPParallaxParams struct BSSPParallaxParams
@ -140,6 +146,8 @@ namespace Nif
// Shader-specific flag methods must be handled on per-record basis // Shader-specific flag methods must be handled on per-record basis
bool specular() const { return mShaderFlags1 & BSSFlag1_Specular; } bool specular() const { return mShaderFlags1 & BSSFlag1_Specular; }
bool decal() const { return mShaderFlags1 & BSSFlag1_Decal; } bool decal() const { return mShaderFlags1 & BSSFlag1_Decal; }
bool depthTest() const { return mShaderFlags1 & BSSFlag1_DepthTest; }
bool depthWrite() const { return mShaderFlags2 & BSSFlag2_DepthWrite; }
}; };
struct BSShaderLightingProperty : BSShaderProperty struct BSShaderLightingProperty : BSShaderProperty

@ -1964,6 +1964,15 @@ namespace NifOsg
return texEnv; 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<osg::Depth> 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, void handleTextureProperty(const Nif::NiTexturingProperty* texprop, const std::string& nodeName,
osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite,
Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags) Resource::ImageManager* imageManager, std::vector<unsigned int>& boundTextures, int animflags)
@ -2319,16 +2328,10 @@ namespace NifOsg
{ {
const Nif::NiZBufferProperty* zprop = static_cast<const Nif::NiZBufferProperty*>(property); const Nif::NiZBufferProperty* zprop = static_cast<const Nif::NiZBufferProperty*>(property);
osg::StateSet* stateset = node->getOrCreateStateSet(); osg::StateSet* stateset = node->getOrCreateStateSet();
stateset->setMode(
GL_DEPTH_TEST, zprop->depthTest() ? osg::StateAttribute::ON : osg::StateAttribute::OFF);
osg::ref_ptr<osg::Depth> depth = new osg::Depth;
depth->setWriteMask(zprop->depthWrite());
// Morrowind ignores depth test function, unless a NiStencilProperty is present, in which case it // Morrowind ignores depth test function, unless a NiStencilProperty is present, in which case it
// uses a fixed depth function of GL_ALWAYS. // uses a fixed depth function of GL_ALWAYS.
if (hasStencilProperty) osg::Depth::Function depthFunction = hasStencilProperty ? osg::Depth::ALWAYS : osg::Depth::LESS;
depth->setFunction(osg::Depth::ALWAYS); handleDepthFlags(stateset, zprop->depthTest(), zprop->depthWrite(), depthFunction);
depth = shareAttribute(depth);
stateset->setAttributeAndModes(depth, osg::StateAttribute::ON);
break; break;
} }
// OSG groups the material properties that NIFs have separate, so we have to parse them all again when // 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); textureSet, texprop->mClamp, node->getName(), stateset, imageManager, boundTextures);
} }
handleTextureControllers(texprop, composite, imageManager, stateset, animflags); handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite());
break; break;
} }
case Nif::RC_BSShaderNoLightingProperty: case Nif::RC_BSShaderNoLightingProperty:
@ -2405,6 +2409,7 @@ namespace NifOsg
} }
stateset->addUniform(new osg::Uniform("useFalloff", useFalloff)); stateset->addUniform(new osg::Uniform("useFalloff", useFalloff));
handleTextureControllers(texprop, composite, imageManager, stateset, animflags); handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite());
break; break;
} }
case Nif::RC_BSLightingShaderProperty: case Nif::RC_BSLightingShaderProperty:
@ -2422,6 +2427,7 @@ namespace NifOsg
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
if (texprop->treeAnim()) if (texprop->treeAnim())
stateset->addUniform(new osg::Uniform("useTreeAnim", true)); stateset->addUniform(new osg::Uniform("useTreeAnim", true));
handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite());
break; break;
} }
case Nif::RC_BSEffectShaderProperty: case Nif::RC_BSEffectShaderProperty:
@ -2477,6 +2483,7 @@ namespace NifOsg
handleTextureControllers(texprop, composite, imageManager, stateset, animflags); handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
if (texprop->doubleSided()) if (texprop->doubleSided())
stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF); stateset->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite());
break; break;
} }
// unused by mw // unused by mw

Loading…
Cancel
Save