|
|
|
@ -1210,80 +1210,8 @@ namespace NifOsg
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleProperty(const Nif::Property *property,
|
|
|
|
|
osg::Node *node, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<int>& boundTextures, int animflags)
|
|
|
|
|
{
|
|
|
|
|
switch (property->recType)
|
|
|
|
|
{
|
|
|
|
|
case Nif::RC_NiStencilProperty:
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiStencilProperty* stencilprop = static_cast<const Nif::NiStencilProperty*>(property);
|
|
|
|
|
osg::FrontFace* frontFace = new osg::FrontFace;
|
|
|
|
|
switch (stencilprop->data.drawMode)
|
|
|
|
|
{
|
|
|
|
|
case 2:
|
|
|
|
|
frontFace->setMode(osg::FrontFace::CLOCKWISE);
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
|
default:
|
|
|
|
|
frontFace->setMode(osg::FrontFace::COUNTER_CLOCKWISE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
|
|
|
|
stateset->setAttribute(frontFace, osg::StateAttribute::ON);
|
|
|
|
|
stateset->setMode(GL_CULL_FACE, stencilprop->data.drawMode == 3 ? osg::StateAttribute::OFF
|
|
|
|
|
: osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
|
|
if (stencilprop->data.enabled != 0)
|
|
|
|
|
{
|
|
|
|
|
osg::Stencil* stencil = new osg::Stencil;
|
|
|
|
|
stencil->setFunction(getStencilFunction(stencilprop->data.compareFunc), stencilprop->data.stencilRef, stencilprop->data.stencilMask);
|
|
|
|
|
stencil->setStencilFailOperation(getStencilOperation(stencilprop->data.failAction));
|
|
|
|
|
stencil->setStencilPassAndDepthFailOperation(getStencilOperation(stencilprop->data.zFailAction));
|
|
|
|
|
stencil->setStencilPassAndDepthPassOperation(getStencilOperation(stencilprop->data.zPassAction));
|
|
|
|
|
|
|
|
|
|
stateset->setAttributeAndModes(stencil, osg::StateAttribute::ON);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiWireframeProperty:
|
|
|
|
|
void handleTextureProperty(const Nif::NiTexturingProperty* texprop, osg::StateSet* stateset, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<int>& boundTextures, int animflags)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiWireframeProperty* wireprop = static_cast<const Nif::NiWireframeProperty*>(property);
|
|
|
|
|
osg::PolygonMode* mode = new osg::PolygonMode;
|
|
|
|
|
mode->setMode(osg::PolygonMode::FRONT_AND_BACK, wireprop->flags == 0 ? osg::PolygonMode::FILL
|
|
|
|
|
: osg::PolygonMode::LINE);
|
|
|
|
|
node->getOrCreateStateSet()->setAttributeAndModes(mode, osg::StateAttribute::ON);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiZBufferProperty:
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiZBufferProperty* zprop = static_cast<const Nif::NiZBufferProperty*>(property);
|
|
|
|
|
// VER_MW doesn't support a DepthFunction according to NifSkope
|
|
|
|
|
osg::Depth* depth = new osg::Depth;
|
|
|
|
|
depth->setWriteMask((zprop->flags>>1)&1);
|
|
|
|
|
node->getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// OSG groups the material properties that NIFs have separate, so we have to parse them all again when one changed
|
|
|
|
|
case Nif::RC_NiMaterialProperty:
|
|
|
|
|
case Nif::RC_NiVertexColorProperty:
|
|
|
|
|
case Nif::RC_NiSpecularProperty:
|
|
|
|
|
{
|
|
|
|
|
// Handled on drawable level so we know whether vertex colors are available
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiAlphaProperty:
|
|
|
|
|
{
|
|
|
|
|
// Handled on drawable level to prevent RenderBin nesting issues
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiTexturingProperty:
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTexturingProperty* texprop = static_cast<const Nif::NiTexturingProperty*>(property);
|
|
|
|
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
|
|
|
|
|
|
|
|
|
if (boundTextures.size())
|
|
|
|
|
{
|
|
|
|
|
// overriding a parent NiTexturingProperty, so remove what was previously bound
|
|
|
|
@ -1392,6 +1320,82 @@ namespace NifOsg
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
handleTextureControllers(texprop, composite, imageManager, stateset, animflags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleProperty(const Nif::Property *property,
|
|
|
|
|
osg::Node *node, SceneUtil::CompositeStateSetUpdater* composite, Resource::ImageManager* imageManager, std::vector<int>& boundTextures, int animflags)
|
|
|
|
|
{
|
|
|
|
|
switch (property->recType)
|
|
|
|
|
{
|
|
|
|
|
case Nif::RC_NiStencilProperty:
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiStencilProperty* stencilprop = static_cast<const Nif::NiStencilProperty*>(property);
|
|
|
|
|
osg::FrontFace* frontFace = new osg::FrontFace;
|
|
|
|
|
switch (stencilprop->data.drawMode)
|
|
|
|
|
{
|
|
|
|
|
case 2:
|
|
|
|
|
frontFace->setMode(osg::FrontFace::CLOCKWISE);
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
case 1:
|
|
|
|
|
default:
|
|
|
|
|
frontFace->setMode(osg::FrontFace::COUNTER_CLOCKWISE);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
|
|
|
|
stateset->setAttribute(frontFace, osg::StateAttribute::ON);
|
|
|
|
|
stateset->setMode(GL_CULL_FACE, stencilprop->data.drawMode == 3 ? osg::StateAttribute::OFF
|
|
|
|
|
: osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
|
|
if (stencilprop->data.enabled != 0)
|
|
|
|
|
{
|
|
|
|
|
osg::Stencil* stencil = new osg::Stencil;
|
|
|
|
|
stencil->setFunction(getStencilFunction(stencilprop->data.compareFunc), stencilprop->data.stencilRef, stencilprop->data.stencilMask);
|
|
|
|
|
stencil->setStencilFailOperation(getStencilOperation(stencilprop->data.failAction));
|
|
|
|
|
stencil->setStencilPassAndDepthFailOperation(getStencilOperation(stencilprop->data.zFailAction));
|
|
|
|
|
stencil->setStencilPassAndDepthPassOperation(getStencilOperation(stencilprop->data.zPassAction));
|
|
|
|
|
|
|
|
|
|
stateset->setAttributeAndModes(stencil, osg::StateAttribute::ON);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiWireframeProperty:
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiWireframeProperty* wireprop = static_cast<const Nif::NiWireframeProperty*>(property);
|
|
|
|
|
osg::PolygonMode* mode = new osg::PolygonMode;
|
|
|
|
|
mode->setMode(osg::PolygonMode::FRONT_AND_BACK, wireprop->flags == 0 ? osg::PolygonMode::FILL
|
|
|
|
|
: osg::PolygonMode::LINE);
|
|
|
|
|
node->getOrCreateStateSet()->setAttributeAndModes(mode, osg::StateAttribute::ON);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiZBufferProperty:
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiZBufferProperty* zprop = static_cast<const Nif::NiZBufferProperty*>(property);
|
|
|
|
|
// VER_MW doesn't support a DepthFunction according to NifSkope
|
|
|
|
|
osg::Depth* depth = new osg::Depth;
|
|
|
|
|
depth->setWriteMask((zprop->flags>>1)&1);
|
|
|
|
|
node->getOrCreateStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// OSG groups the material properties that NIFs have separate, so we have to parse them all again when one changed
|
|
|
|
|
case Nif::RC_NiMaterialProperty:
|
|
|
|
|
case Nif::RC_NiVertexColorProperty:
|
|
|
|
|
case Nif::RC_NiSpecularProperty:
|
|
|
|
|
{
|
|
|
|
|
// Handled on drawable level so we know whether vertex colors are available
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiAlphaProperty:
|
|
|
|
|
{
|
|
|
|
|
// Handled on drawable level to prevent RenderBin nesting issues
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Nif::RC_NiTexturingProperty:
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTexturingProperty* texprop = static_cast<const Nif::NiTexturingProperty*>(property);
|
|
|
|
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
|
|
|
|
handleTextureProperty(texprop, stateset, composite, imageManager, boundTextures, animflags);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// unused by mw
|
|
|
|
|