Exemple #1
0
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;
}