Skip to content

Commit

Permalink
Merge branch 'nifogproperty' into 'master'
Browse files Browse the repository at this point in the history
Handle NiFogProperty (feature #5173)

Closes #5173

See merge request OpenMW/openmw!3642
  • Loading branch information
jvoisin committed Dec 12, 2023
2 parents 78da1eb + 9cdaf2c commit abbb620
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
Bug #7679: Scene luminance value flashes when toggling shaders
Bug #7712: Casting doesn't support spells and enchantments with no effects
Feature #3537: Shader-based water ripples
Feature #5173: Support for NiFogProperty
Feature #5492: Let rain and snow collide with statics
Feature #6149: Dehardcode Lua API_REVISION
Feature #6152: Playing music via lua scripts
Expand Down
2 changes: 1 addition & 1 deletion components/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ add_component_dir (nif
)

add_component_dir (nifosg
nifloader controller particle matrixtransform
nifloader controller particle matrixtransform fog
)

add_component_dir (nifbullet
Expand Down
11 changes: 11 additions & 0 deletions components/nif/property.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,11 +461,22 @@ namespace Nif

struct NiFogProperty : NiProperty
{
enum Flags : uint16_t
{
Enabled = 0x02,
Radial = 0x08,
VertexAlpha = 0x10,
};

uint16_t mFlags;
float mFogDepth;
osg::Vec3f mColour;

void read(NIFStream* nif) override;

bool enabled() const { return mFlags & Flags::Enabled; }
bool radial() const { return mFlags & Flags::Radial; }
bool vertexAlpha() const { return mFlags & Flags::VertexAlpha; }
};

struct NiMaterialProperty : NiProperty
Expand Down
31 changes: 31 additions & 0 deletions components/nifosg/fog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "fog.hpp"

#include <osg/Matrix>
#include <osg/State>

namespace NifOsg
{

Fog::Fog()
: osg::Fog()
{
}

Fog::Fog(const Fog& copy, const osg::CopyOp& copyop)
: osg::Fog(copy, copyop)
, mDepth(copy.mDepth)
{
}

void Fog::apply(osg::State& state) const
{
osg::Fog::apply(state);
#ifdef OSG_GL_FIXED_FUNCTION_AVAILABLE
float fov, aspect, near, far;
state.getProjectionMatrix().getPerspective(fov, aspect, near, far);
glFogf(GL_FOG_START, near * mDepth + far * (1.f - mDepth));
glFogf(GL_FOG_END, far);
#endif
}

}
29 changes: 29 additions & 0 deletions components/nifosg/fog.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef OPENMW_COMPONENTS_NIFOSG_FOG_H
#define OPENMW_COMPONENTS_NIFOSG_FOG_H

#include <osg/Fog>

namespace NifOsg
{

// osg::Fog-based wrapper for NiFogProperty that autocalculates the fog start and end distance.
class Fog : public osg::Fog
{
public:
Fog();
Fog(const Fog& copy, const osg::CopyOp& copyop);

META_StateAttribute(NifOsg, Fog, FOG)

void setDepth(float depth) { mDepth = depth; }
float getDepth() const { return mDepth; }

void apply(osg::State& state) const override;

private:
float mDepth{ 1.f };
};

}

#endif
28 changes: 27 additions & 1 deletion components/nifosg/nifloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
#include <components/sceneutil/riggeometry.hpp>
#include <components/sceneutil/skeleton.hpp>

#include "fog.hpp"
#include "matrixtransform.hpp"
#include "particle.hpp"

Expand Down Expand Up @@ -2495,10 +2496,35 @@ namespace NifOsg
handleDepthFlags(stateset, texprop->depthTest(), texprop->depthWrite());
break;
}
case Nif::RC_NiFogProperty:
{
const Nif::NiFogProperty* fogprop = static_cast<const Nif::NiFogProperty*>(property);
osg::StateSet* stateset = node->getOrCreateStateSet();
// Vertex alpha mode appears to be broken
if (!fogprop->vertexAlpha() && fogprop->enabled())
{
osg::ref_ptr<NifOsg::Fog> fog = new NifOsg::Fog;
fog->setMode(osg::Fog::LINEAR);
fog->setColor(osg::Vec4f(fogprop->mColour, 1.f));
fog->setDepth(fogprop->mFogDepth);
stateset->setAttributeAndModes(fog, osg::StateAttribute::ON);
// Intentionally ignoring radial fog flag
// We don't really want to override the global setting
}
else
{
osg::ref_ptr<osg::Fog> fog = new osg::Fog;
// Shaders don't respect glDisable(GL_FOG)
fog->setMode(osg::Fog::LINEAR);
fog->setStart(10000000);
fog->setEnd(10000000);
stateset->setAttributeAndModes(fog, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
}
break;
}
// unused by mw
case Nif::RC_NiShadeProperty:
case Nif::RC_NiDitherProperty:
case Nif::RC_NiFogProperty:
{
break;
}
Expand Down
15 changes: 15 additions & 0 deletions components/sceneutil/serialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <osgDB/ObjectWrapper>
#include <osgDB/Registry>

#include <components/nifosg/fog.hpp>
#include <components/nifosg/matrixtransform.hpp>

#include <components/sceneutil/morphgeometry.hpp>
Expand Down Expand Up @@ -123,6 +124,19 @@ namespace SceneUtil
}
};

class FogSerializer : public osgDB::ObjectWrapper
{
public:
FogSerializer()
: osgDB::ObjectWrapper(
createInstanceFunc<osg::Fog>, "NifOsg::Fog", "osg::Object osg::StateAttribute osg::Fog NifOsg::Fog")
{
addSerializer(new osgDB::PropByValSerializer<NifOsg::Fog, float>(
"Depth", 1.f, &NifOsg::Fog::getDepth, &NifOsg::Fog::setDepth),
osgDB::BaseSerializer::RW_FLOAT);
}
};

osgDB::ObjectWrapper* makeDummySerializer(const std::string& classname)
{
return new osgDB::ObjectWrapper(createInstanceFunc<osg::DummyObject>, classname, "osg::Object");
Expand Down Expand Up @@ -153,6 +167,7 @@ namespace SceneUtil
mgr->addWrapper(new LightManagerSerializer);
mgr->addWrapper(new CameraRelativeTransformSerializer);
mgr->addWrapper(new MatrixTransformSerializer);
mgr->addWrapper(new FogSerializer);

// Don't serialize Geometry data as we are more interested in the overall structure rather than tons of
// vertex data that would make the file large and hard to read.
Expand Down

0 comments on commit abbb620

Please sign in to comment.