|
|
|
@ -5,13 +5,14 @@
|
|
|
|
|
#include <OgreBillboardSet.h>
|
|
|
|
|
#include <OgreHardwareOcclusionQuery.h>
|
|
|
|
|
#include <OgreEntity.h>
|
|
|
|
|
#include <OgreSubEntity.h>
|
|
|
|
|
|
|
|
|
|
using namespace MWRender;
|
|
|
|
|
using namespace Ogre;
|
|
|
|
|
|
|
|
|
|
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) :
|
|
|
|
|
mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0),
|
|
|
|
|
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
|
|
|
|
|
mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false),
|
|
|
|
|
mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false),
|
|
|
|
|
mBBNode(0)
|
|
|
|
|
{
|
|
|
|
@ -84,7 +85,6 @@ OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNod
|
|
|
|
|
mRendering->getScene()->addRenderObjectListener(this);
|
|
|
|
|
mRendering->getScene()->addRenderQueueListener(this);
|
|
|
|
|
mDoQuery = true;
|
|
|
|
|
mDoQuery2 = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OcclusionQuery::~OcclusionQuery()
|
|
|
|
@ -100,7 +100,7 @@ bool OcclusionQuery::supported()
|
|
|
|
|
return mSupported;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
|
|
|
|
|
void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
|
|
|
|
|
const LightList* pLightList, bool suppressRenderStateChanges)
|
|
|
|
|
{
|
|
|
|
|
// The following code activates and deactivates the occlusion queries
|
|
|
|
@ -134,7 +134,7 @@ void OcclusionQuery::notifyRenderSingleObject(Renderable* rend, const Pass* pass
|
|
|
|
|
mActiveQuery = mSingleObjectQuery;
|
|
|
|
|
mObjectWasVisible = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (mActiveQuery != NULL)
|
|
|
|
|
mActiveQuery->beginOcclusionQuery();
|
|
|
|
|
}
|
|
|
|
@ -195,7 +195,6 @@ void OcclusionQuery::update(float duration)
|
|
|
|
|
// Stop occlusion queries until we get their information
|
|
|
|
|
// (may not happen on the same frame they are requested in)
|
|
|
|
|
mDoQuery = false;
|
|
|
|
|
mDoQuery2 = false;
|
|
|
|
|
|
|
|
|
|
if (!mSunTotalAreaQuery->isStillOutstanding()
|
|
|
|
|
&& !mSunVisibleAreaQuery->isStillOutstanding()
|
|
|
|
@ -264,3 +263,40 @@ bool OcclusionQuery::getTestResult()
|
|
|
|
|
|
|
|
|
|
return mTestResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool OcclusionQuery::isPotentialOccluder(Ogre::SceneNode* node)
|
|
|
|
|
{
|
|
|
|
|
bool result = false;
|
|
|
|
|
for (unsigned int i=0; i < node->numAttachedObjects(); ++i)
|
|
|
|
|
{
|
|
|
|
|
MovableObject* ob = node->getAttachedObject(i);
|
|
|
|
|
std::string type = ob->getMovableType();
|
|
|
|
|
if (type == "Entity")
|
|
|
|
|
{
|
|
|
|
|
Entity* ent = static_cast<Entity*>(ob);
|
|
|
|
|
for (unsigned int j=0; j < ent->getNumSubEntities(); ++j)
|
|
|
|
|
{
|
|
|
|
|
// if any sub entity has a material with depth write off,
|
|
|
|
|
// consider the object as not an occluder
|
|
|
|
|
MaterialPtr mat = ent->getSubEntity(j)->getMaterial();
|
|
|
|
|
|
|
|
|
|
Material::TechniqueIterator techIt = mat->getTechniqueIterator();
|
|
|
|
|
while (techIt.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Technique* tech = techIt.getNext();
|
|
|
|
|
Technique::PassIterator passIt = tech->getPassIterator();
|
|
|
|
|
while (passIt.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Pass* pass = passIt.getNext();
|
|
|
|
|
|
|
|
|
|
if (pass->getDepthWriteEnabled() == false)
|
|
|
|
|
return false;
|
|
|
|
|
else
|
|
|
|
|
result = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|