Create occlusion query nodes for the sun flash

sceneinput
scrawl 9 years ago
parent 6bafa564d4
commit d191a52847

@ -11,6 +11,9 @@
#include <osg/TexEnvCombine>
#include <osg/TexMat>
#include <osg/Version>
#include <osg/OcclusionQueryNode>
#include <osg/ColorMask>
#include <osg/MatrixTransform>
#include <osgParticle/ParticleSystem>
#include <osgParticle/ParticleSystemUpdater>
@ -368,6 +371,18 @@ public:
osg::Texture::CLAMP);
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()
@ -391,6 +406,46 @@ public:
}
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
{
osg::Vec4f mColor;
@ -414,6 +469,8 @@ private:
};
osg::ref_ptr<Updater> mUpdater;
osg::ref_ptr<osg::OcclusionQueryNode> mOcclusionQueryVisiblePixels;
osg::ref_ptr<osg::OcclusionQueryNode> mOcclusionQueryTotalPixels;
};
class Moon : public CelestialBody

Loading…
Cancel
Save