diff --git a/apps/openmw/mwrender/sky.cpp b/apps/openmw/mwrender/sky.cpp index 78b1aba70..63a041579 100644 --- a/apps/openmw/mwrender/sky.cpp +++ b/apps/openmw/mwrender/sky.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -375,17 +376,20 @@ public: 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 queryTransform (new osg::PositionAttitudeTransform); - queryTransform->setScale(osg::Vec3f(0.4f, 0.4f, 0.4f)); + osg::ref_ptr queryNode (new osg::Group); // Need to render after the world geometry so we can correctly test for occlusions - queryTransform->getOrCreateStateSet()->setRenderBinDetails(RenderBin_OcclusionQuery, "RenderBin"); - queryTransform->getOrCreateStateSet()->setNestRenderBins(false); + queryNode->getOrCreateStateSet()->setRenderBinDetails(RenderBin_OcclusionQuery, "RenderBin"); + queryNode->getOrCreateStateSet()->setNestRenderBins(false); + // Set up alpha testing on the occlusion testing subgraph, that way we can get the occlusion tested fragments to match the circular shape of the sun + osg::ref_ptr alphaFunc (new osg::AlphaFunc); + alphaFunc->setFunction(osg::AlphaFunc::GREATER, 0.8); + queryNode->getOrCreateStateSet()->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); + queryNode->getOrCreateStateSet()->setTextureAttributeAndModes(0, sunTex, osg::StateAttribute::ON); - mTransform->addChild(queryTransform); + mTransform->addChild(queryNode); - mOcclusionQueryVisiblePixels = createOcclusionQueryNode(queryTransform, true); - mOcclusionQueryTotalPixels = createOcclusionQueryNode(queryTransform, false); + mOcclusionQueryVisiblePixels = createOcclusionQueryNode(queryNode, true); + mOcclusionQueryTotalPixels = createOcclusionQueryNode(queryNode, false); createSunFlash(textureManager); createSunGlare(); @@ -441,6 +445,26 @@ private: oqn->addChild(queryGeode); + // Remove the default OFF|PROTECTED setting for texturing. We *want* to enable texturing for alpha testing purposes + oqn->getQueryStateSet()->removeTextureMode(0, GL_TEXTURE_2D); + + // Need to add texture coordinates so that texturing works. A bit ugly, relies on the vertex ordering + // used within OcclusionQueryNode. + osg::ref_ptr texCoordArray (new osg::Vec2Array); + for (int i=0; i<8; ++i) + { + texCoordArray->push_back(osg::Vec2(0,0)); + texCoordArray->push_back(osg::Vec2(1,0)); + texCoordArray->push_back(osg::Vec2(0,0)); + texCoordArray->push_back(osg::Vec2(1,0)); + texCoordArray->push_back(osg::Vec2(1,1)); + texCoordArray->push_back(osg::Vec2(0,1)); + texCoordArray->push_back(osg::Vec2(0,1)); + texCoordArray->push_back(osg::Vec2(1,1)); + } + + oqn->getQueryGeometry()->setTexCoordArray(0, texCoordArray, osg::Array::BIND_PER_VERTEX); + if (queryVisible) { osg::ref_ptr depth (new osg::Depth); @@ -626,8 +650,7 @@ private: if (visibleRatio > 0.f) { - // rescale into [0.35, 1.0] range - const float threshold = 0.35; + const float threshold = 0.6; visibleRatio = visibleRatio * (1.f - threshold) + threshold; }