diff --git a/apps/openmw/mwrender/occlusionquery.cpp b/apps/openmw/mwrender/occlusionquery.cpp index 6c74561e95..baf55b0249 100644 --- a/apps/openmw/mwrender/occlusionquery.cpp +++ b/apps/openmw/mwrender/occlusionquery.cpp @@ -45,19 +45,21 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod matQueryVisible->setColourWriteEnabled(false); matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects + mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode(); + mBBQueryTotal = mRendering->getScene()->createBillboardSet(1); mBBQueryTotal->setDefaultDimensions(150, 150); mBBQueryTotal->createBillboard(Vector3::ZERO); mBBQueryTotal->setMaterialName("QueryTotalPixels"); mBBQueryTotal->setRenderQueueGroup(queue); - mSunNode->attachObject(mBBQueryTotal); + mBBNode->attachObject(mBBQueryTotal); mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); mBBQueryVisible->setDefaultDimensions(150, 150); mBBQueryVisible->createBillboard(Vector3::ZERO); mBBQueryVisible->setMaterialName("QueryVisiblePixels"); mBBQueryVisible->setRenderQueueGroup(queue); - mSunNode->attachObject(mBBQueryVisible); + mBBNode->attachObject(mBBQueryVisible); mRendering->getScene()->addRenderObjectListener(this); mDoQuery = true; @@ -110,6 +112,15 @@ void OcclusionQuery::update() { if (!mSupported) return; + // Adjust the position of the sun billboards according to camera viewing distance + // we need to do this to make sure that _everything_ can occlude the sun + float dist = mRendering->getCamera()->getFarClipDistance(); + if (dist==0) dist = 10000000; + dist -= 1000; // bias + dist /= 1000.f; + mBBNode->setPosition(mSunNode->getPosition() * dist); + mBBNode->setScale(dist, dist, dist); + // Stop occlusion queries until we get their information // (may not happen on the same frame they are requested in) mDoQuery = false; diff --git a/apps/openmw/mwrender/occlusionquery.hpp b/apps/openmw/mwrender/occlusionquery.hpp index e6adc0d4b3..2545e590e9 100644 --- a/apps/openmw/mwrender/occlusionquery.hpp +++ b/apps/openmw/mwrender/occlusionquery.hpp @@ -17,11 +17,32 @@ namespace MWRender OcclusionQuery(OEngine::Render::OgreRenderer*, Ogre::SceneNode* sunNode); ~OcclusionQuery(); + /** + * @return true if occlusion queries are supported on the user's hardware + */ bool supported(); - ///< returns true if occlusion queries are supported on the user's hardware + /** + * per-frame update + */ void update(); - ///< per-frame update + + /** + * request occlusion test for a billboard at the given position, omitting an entity + * @param position of the billboard in ogre coordinates + * @param entity to exclude from the occluders + */ + void occlusionTest(const Ogre::Vector3& position, Ogre::Entity* entity); + + /** + * @return true if a request is still outstanding + */ + bool occlusionTestPending(); + + /** + * @return true if the object tested in the last request was occluded + */ + bool getTestResult(); float getSunVisibility() const {return mSunVisibility;}; @@ -35,8 +56,12 @@ namespace MWRender Ogre::SceneNode* mSunNode; + Ogre::SceneNode* mBBNode; + float mSunVisibility; + bool mTestResult; + bool mSupported; bool mDoQuery;