mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Create occlusion query nodes for the sun flash
This commit is contained in:
parent
6bafa564d4
commit
d191a52847
1 changed files with 57 additions and 0 deletions
|
@ -11,6 +11,9 @@
|
||||||
#include <osg/TexEnvCombine>
|
#include <osg/TexEnvCombine>
|
||||||
#include <osg/TexMat>
|
#include <osg/TexMat>
|
||||||
#include <osg/Version>
|
#include <osg/Version>
|
||||||
|
#include <osg/OcclusionQueryNode>
|
||||||
|
#include <osg/ColorMask>
|
||||||
|
#include <osg/MatrixTransform>
|
||||||
|
|
||||||
#include <osgParticle/ParticleSystem>
|
#include <osgParticle/ParticleSystem>
|
||||||
#include <osgParticle/ParticleSystemUpdater>
|
#include <osgParticle/ParticleSystemUpdater>
|
||||||
|
@ -368,6 +371,18 @@ public:
|
||||||
osg::Texture::CLAMP);
|
osg::Texture::CLAMP);
|
||||||
|
|
||||||
mGeode->getOrCreateStateSet()->setTextureAttributeAndModes(0, sunTex, osg::StateAttribute::ON);
|
mGeode->getOrCreateStateSet()->setTextureAttributeAndModes(0, sunTex, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
// Slightly downscale the query geometry since the sun quad has a transparent texture that doesn't cover the whole area
|
||||||
|
osg::ref_ptr<osg::PositionAttitudeTransform> queryTransform (new osg::PositionAttitudeTransform);
|
||||||
|
queryTransform->setScale(osg::Vec3f(0.5f, 0.5f, 0.5f));
|
||||||
|
// Need to render after the world geometry so we can correctly test for occlusions
|
||||||
|
queryTransform->getOrCreateStateSet()->setRenderBinDetails(10, "RenderBin");
|
||||||
|
queryTransform->getOrCreateStateSet()->setNestRenderBins(false);
|
||||||
|
|
||||||
|
mTransform->addChild(queryTransform);
|
||||||
|
|
||||||
|
mOcclusionQueryVisiblePixels = createOcclusionQueryNode(queryTransform, true);
|
||||||
|
mOcclusionQueryTotalPixels = createOcclusionQueryNode(queryTransform, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Sun()
|
~Sun()
|
||||||
|
@ -391,6 +406,46 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// @param queryVisible If true, queries the amount of visible pixels. If false, queries the total amount of pixels.
|
||||||
|
osg::ref_ptr<osg::OcclusionQueryNode> createOcclusionQueryNode(osg::Group* parent, bool queryVisible)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::OcclusionQueryNode> oqn = new osg::OcclusionQueryNode;
|
||||||
|
oqn->setQueriesEnabled(true);
|
||||||
|
|
||||||
|
// Make it fast! A DYNAMIC query geometry means we can't break frame until the flare is rendered (which is rendered after all the other geometry,
|
||||||
|
// so that would be pretty bad). STATIC should be safe, since our node's local bounds are static, thus computeBounds() which modifies the queryGeometry
|
||||||
|
// is only called once.
|
||||||
|
// Note the debug geometry setDebugDisplay(true) is always DYNAMIC and that can't be changed, not a big deal.
|
||||||
|
oqn->getQueryGeometry()->setDataVariance(osg::Object::STATIC);
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Geode> queryGeode = osg::clone(mGeode.get(), osg::CopyOp::DEEP_COPY_ALL);
|
||||||
|
// Disable writing to the color buffer. We are using this geode for visibility tests only.
|
||||||
|
osg::ref_ptr<osg::ColorMask> colormask (new osg::ColorMask(0, 0, 0, 0));
|
||||||
|
queryGeode->getOrCreateStateSet()->setAttributeAndModes(colormask, osg::StateAttribute::ON);
|
||||||
|
|
||||||
|
oqn->addChild(queryGeode);
|
||||||
|
|
||||||
|
if (queryVisible)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Depth> depth (new osg::Depth);
|
||||||
|
depth->setFunction(osg::Depth::LESS);
|
||||||
|
// This is a trick to make fragments written by the query always use the maximum depth value,
|
||||||
|
// without having to retrieve the current far clipping distance.
|
||||||
|
// We want the sun glare to be "infinitely" far away.
|
||||||
|
depth->setZNear(1.0);
|
||||||
|
depth->setZFar(1.0);
|
||||||
|
oqn->getQueryStateSet()->setAttributeAndModes(depth, osg::StateAttribute::ON);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
oqn->getQueryStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent->addChild(oqn);
|
||||||
|
|
||||||
|
return oqn;
|
||||||
|
}
|
||||||
|
|
||||||
struct Updater : public SceneUtil::StateSetUpdater
|
struct Updater : public SceneUtil::StateSetUpdater
|
||||||
{
|
{
|
||||||
osg::Vec4f mColor;
|
osg::Vec4f mColor;
|
||||||
|
@ -414,6 +469,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
osg::ref_ptr<Updater> mUpdater;
|
osg::ref_ptr<Updater> mUpdater;
|
||||||
|
osg::ref_ptr<osg::OcclusionQueryNode> mOcclusionQueryVisiblePixels;
|
||||||
|
osg::ref_ptr<osg::OcclusionQueryNode> mOcclusionQueryTotalPixels;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Moon : public CelestialBody
|
class Moon : public CelestialBody
|
||||||
|
|
Loading…
Reference in a new issue