OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mActiveQuery(0), mDoQuery(0), mSunVisibility(0), mWasVisible(false), mActive(false), mFirstFrame(true) { mRendering = renderer; mSunNode = sunNode; try { RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); mSunTotalAreaQuery = renderSystem->createHardwareOcclusionQuery(); mSunVisibleAreaQuery = renderSystem->createHardwareOcclusionQuery(); mSupported = (mSunTotalAreaQuery != 0) && (mSunVisibleAreaQuery != 0); } catch (Ogre::Exception& e) { mSupported = false; } if (!mSupported) { std::cout << "Hardware occlusion queries not supported." << std::endl; return; } mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); static Ogre::Mesh* plane = MeshManager::getSingleton().createPlane("occlusionbillboard", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::Plane(Ogre::Vector3(0,0,1), 0), 1, 1, 1, 1, true, 1, 1, 1, Vector3::UNIT_Y).get(); plane->_setBounds(Ogre::AxisAlignedBox::BOX_INFINITE); mBBQueryTotal = mRendering->getScene()->createEntity("occlusionbillboard"); mBBQueryTotal->setCastShadows(false); mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery); mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBQueryTotal->setMaterialName("QueryTotalPixels"); mBBNodeReal->attachObject(mBBQueryTotal); mBBQueryVisible = mRendering->getScene()->createEntity("occlusionbillboard"); mBBQueryVisible->setCastShadows(false); mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery); mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBQueryVisible->setMaterialName("QueryVisiblePixels"); mBBNodeReal->attachObject(mBBQueryVisible); mRendering->getScene()->addRenderObjectListener(this); mRendering->getScene()->addRenderQueueListener(this); mDoQuery = true; }
OcclusionQuery::OcclusionQuery(OEngine::Render::OgreRenderer* renderer, SceneNode* sunNode) : mSunTotalAreaQuery(0), mSunVisibleAreaQuery(0), mSingleObjectQuery(0), mActiveQuery(0), mDoQuery(0), mSunVisibility(0), mQuerySingleObjectStarted(false), mTestResult(false), mQuerySingleObjectRequested(false), mWasVisible(false), mObjectWasVisible(false), mDoQuery2(false), mBBNode(0) { mRendering = renderer; mSunNode = sunNode; try { RenderSystem* renderSystem = Root::getSingleton().getRenderSystem(); mSunTotalAreaQuery = renderSystem->createHardwareOcclusionQuery(); mSunVisibleAreaQuery = renderSystem->createHardwareOcclusionQuery(); mSingleObjectQuery = renderSystem->createHardwareOcclusionQuery(); mSupported = (mSunTotalAreaQuery != 0) && (mSunVisibleAreaQuery != 0) && (mSingleObjectQuery != 0); } catch (Ogre::Exception e) { mSupported = false; } if (!mSupported) { std::cout << "Hardware occlusion queries not supported." << std::endl; return; } MaterialPtr matBase = MaterialManager::getSingleton().getByName("BaseWhiteNoLighting"); MaterialPtr matQueryArea = matBase->clone("QueryTotalPixels"); matQueryArea->setDepthWriteEnabled(false); matQueryArea->setColourWriteEnabled(false); matQueryArea->setDepthCheckEnabled(false); // Not occluded by objects MaterialPtr matQueryVisible = matBase->clone("QueryVisiblePixels"); matQueryVisible->setDepthWriteEnabled(false); matQueryVisible->setColourWriteEnabled(false); // Uncomment this to visualize the occlusion query matQueryVisible->setDepthCheckEnabled(true); // Occluded by objects matQueryVisible->setCullingMode(CULL_NONE); matQueryVisible->setManualCullingMode(MANUAL_CULL_NONE); if (sunNode) mBBNode = mSunNode->getParentSceneNode()->createChildSceneNode(); mObjectNode = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); mBBNodeReal = mRendering->getScene()->getRootSceneNode()->createChildSceneNode(); mBBQueryTotal = mRendering->getScene()->createBillboardSet(1); mBBQueryTotal->setCastShadows(false); mBBQueryTotal->setDefaultDimensions(150, 150); mBBQueryTotal->createBillboard(Vector3::ZERO); mBBQueryTotal->setMaterialName("QueryTotalPixels"); mBBQueryTotal->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBQueryTotal->setVisibilityFlags(RV_OcclusionQuery); mBBNodeReal->attachObject(mBBQueryTotal); mBBQueryVisible = mRendering->getScene()->createBillboardSet(1); mBBQueryVisible->setCastShadows(false); mBBQueryVisible->setDefaultDimensions(150, 150); mBBQueryVisible->createBillboard(Vector3::ZERO); mBBQueryVisible->setMaterialName("QueryVisiblePixels"); mBBQueryVisible->setRenderQueueGroup(RQG_OcclusionQuery+1); mBBQueryVisible->setVisibilityFlags(RV_OcclusionQuery); mBBNodeReal->attachObject(mBBQueryVisible); mBBQuerySingleObject = mRendering->getScene()->createBillboardSet(1); /// \todo ideally this should occupy exactly 1 pixel on the screen mBBQuerySingleObject->setCastShadows(false); mBBQuerySingleObject->setDefaultDimensions(0.003, 0.003); mBBQuerySingleObject->createBillboard(Vector3::ZERO); mBBQuerySingleObject->setMaterialName("QueryVisiblePixels"); mBBQuerySingleObject->setRenderQueueGroup(RQG_OcclusionQuery); mBBQuerySingleObject->setVisibilityFlags(RV_OcclusionQuery); mObjectNode->attachObject(mBBQuerySingleObject); mRendering->getScene()->addRenderObjectListener(this); mRendering->getScene()->addRenderQueueListener(this); mDoQuery = true; }