#include #include #include #include #include #include #include "OgreSolidBoundingBox.h" #include "OgrePlatformHierarchyInterface.h" #include "OgrePlatformOcclusionQuery.h" namespace Ogre { //----------------------------------------------------------------------- PlatformHierarchyInterface::PlatformHierarchyInterface(SceneManager *sm, RenderSystem *rsys): mSceneManager(sm), mRenderSystem(rsys), mSolidBoundingBox(NULL), mCamera(NULL), mCullCamera(NULL), mOnlyShadowCasters(false), mLeavePassesInQueue(0), mIsBoundingBoxQuery(false), mCameraPosition(Vector3(0, 0, 0)) { } //----------------------------------------------------------------------- void PlatformHierarchyInterface::CreateNodeVizMaterials() { // material for frustum culled nodes MaterialPtr mat = MaterialManager::getSingleton().getByName("FrustumCulledNodesMaterial"); if (mat.isNull()) { mat = MaterialManager::getSingleton().create("FrustumCulledNodesMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mat->createTechnique()->createPass(); mat->getTechnique(0)->getPass(0)->setAmbient(1, 0, 0); mat->getTechnique(0)->getPass(0)->setLightingEnabled(true); //mat->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); mat->load(); } // material for query culled nodes mat = MaterialManager::getSingleton().getByName("QueryCulledNodesMaterial"); if (mat.isNull()) { mat = MaterialManager::getSingleton().create("QueryCulledNodesMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mat->createTechnique()->createPass(); mat->getTechnique(0)->getPass(0)->setAmbient(0, 0, 1); mat->getTechnique(0)->getPass(0)->setLightingEnabled(true); mat->load(); } // material for scene nodes /*mat = MaterialManager::getSingleton().getByName("SceneNodesMaterial"); if (mat.isNull()) { mat = MaterialManager::getSingleton().create("SceneNodesMaterial", ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); mat->createTechnique()->createPass(); mat->getTechnique(0)->getPass(0)->setAmbient(1, 1, 0); mat->getTechnique(0)->getPass(0)->setLightingEnabled(true); mat->load(); }*/ } //----------------------------------------------------------------------- PlatformHierarchyInterface::~PlatformHierarchyInterface() { ResetQueries(); OGRE_DELETE(mSolidBoundingBox); } //----------------------------------------------------------------------- void PlatformHierarchyInterface::ResetQueries() { OcclusionQueryContainer::iterator it, it_end = mOcclusionQueries.end(); for (it = mOcclusionQueries.begin(); it != it_end; ++ it) { PlatformOcclusionQuery *query = *it; OGRE_DELETE(query); } mCurrentTestIdx = 0; mOcclusionQueries.clear(); } //----------------------------------------------------------------------- void PlatformHierarchyInterface::RenderBoundingBox(AxisAlignedBox *box) { static RenderOperation ro; SolidBoundingBox *solidBox = GetSolidBoundingBox(); mRenderSystem->_setWorldMatrix(Ogre::Matrix4::IDENTITY); mSceneManager->useRenderableViewProjModeWrapper(solidBox); // HACK! (mySetPass should be setPass) // set no depth write, no color, no lighting material mSceneManager->setPassWrapper(solidBox->getTechnique()->getPass(0)); //mSceneManager->_setPass(solidBox->getTechnique()->getPass(0)); //SetOcclusionPass(); solidBox->SetupBoundingBoxVertices(*box); solidBox->getRenderOperation(ro); ro.srcRenderable = solidBox; mRenderSystem->_render(ro); } //----------------------------------------------------------------------- void PlatformHierarchyInterface::SetCamera(Ogre::Camera *cam) { mCamera = cam; } //----------------------------------------------------------------------- void PlatformHierarchyInterface::SetCullCamera(Ogre::Camera *cullCam) { mCullCamera = cullCam; } //----------------------------------------------------------------------- GtpVisibility::OcclusionQuery *PlatformHierarchyInterface::GetNextOcclusionQuery() { // create new query if there is no query left if (mCurrentTestIdx == (int)mOcclusionQueries.size()) { mOcclusionQueries.push_back(new PlatformOcclusionQuery(mRenderSystem)); /*std::stringstream d; d << "resizing queries: " << (int)mOcclusionQueries.size() << std::endl; LogManager::getSingleton().logMessage(d.str());*/ } return mOcclusionQueries[mCurrentTestIdx ++]; } //----------------------------------------------------------------------- void PlatformHierarchyInterface::InitTraversal(Camera *cam, Camera *cullCam, int leavePassesInQueue) { GtpVisibility::HierarchyInterface::InitTraversal(); mSavedNode = NULL; mLeavePassesInQueue = leavePassesInQueue; mCamera = cam; // set culling camera for visualization mCullCamera = cullCam ? cullCam : cam; mCameraPosition = mCullCamera->getDerivedPosition(); // create materials for node visualization CreateNodeVizMaterials(); } //----------------------------------------------------------------------- void PlatformHierarchyInterface::SetSceneManager(SceneManager *sm) { mSceneManager = sm; } //----------------------------------------------------------------------- void PlatformHierarchyInterface::SetRenderSystem(RenderSystem *rsys) { mRenderSystem = rsys; } //----------------------------------------------------------------------- bool PlatformHierarchyInterface::CheckFrustumVisible(GtpVisibility::HierarchyNode *node, bool &intersects) { #ifdef GTP_VISIBILITY_MODIFIED_OGRE return mCullCamera->isVisible(*GetBoundingBox(node), intersects); #else return true; #endif } //----------------------------------------------------------------------- GtpVisibility::OcclusionQuery *PlatformHierarchyInterface::IssueNodeOcclusionQuery( GtpVisibility::HierarchyNode *node, const bool wasVisible) { // get next available test id GtpVisibility::OcclusionQuery *query = GetNextOcclusionQuery(); //-- the actual query test query->BeginQuery(); // if node is leaf and was visible => will be rendered anyway. // In this case we can also test with the real geometry. // If camera for culling is different from camera for rendering or only solids // will be rendereded => cannot optimize if (mTestGeometryForVisibleLeaves && (mCamera == mCullCamera) && wasVisible && IsLeaf(node)) { RenderNode(node); } else { // this information is used e.g., by the scene graph, because the bounding box // must be treated differently to the scene geometry during rendering mIsBoundingBoxQuery = true; RenderBoundingBox(GetBoundingBox(node)); mIsBoundingBoxQuery = false; } query->EndQuery(); return query; } //----------------------------------------------------------------------- GtpVisibility::OcclusionQuery *PlatformHierarchyInterface::IssuePatchOcclusionQuery( GtpVisibility::Patch *patch) { // get next available test id GtpVisibility::OcclusionQuery *query = GetNextOcclusionQuery(); //-- the actual query test query->BeginQuery(); RenderPatch(patch); query->EndQuery(); return query; } //----------------------------------------------------------------------- GtpVisibility::OcclusionQuery *PlatformHierarchyInterface::IssueMeshOcclusionQuery( GtpVisibility::Mesh *mesh) { // get next available test id GtpVisibility::OcclusionQuery *query = GetNextOcclusionQuery(); //////// //-- the actual query test query->BeginQuery(); RenderGeometry(mesh); query->EndQuery(); return query; } //----------------------------------------------------------------------- /*void PlatformHierarchyInterface::SetOcclusionPass() { // disable vertex and fragment program mRenderSystem->unbindGpuProgram(GPT_VERTEX_PROGRAM); mRenderSystem->unbindGpuProgram(GPT_FRAGMENT_PROGRAM); // disable lighting mRenderSystem->setLightingEnabled(false); // Disable remaining texture units mRenderSystem->_disableTextureUnitsFrom(0); //--Set up non-texture related material settings // Depth buffer settings mRenderSystem->_setDepthBufferParams(true, false, CMPF_LESS_EQUAL); // Set colour write mode off mRenderSystem->_setColourBufferWriteEnabled(false, false, false, false); }*/ //----------------------------------------------------------------------- SolidBoundingBox *PlatformHierarchyInterface::GetSolidBoundingBox() { if (!mSolidBoundingBox) mSolidBoundingBox = new SolidBoundingBox; return mSolidBoundingBox; } //----------------------------------------------------------------------- void PlatformHierarchyInterface::SetOnlyShadowCasters(bool onlyShadowCasters) { mOnlyShadowCasters = onlyShadowCasters; } //----------------------------------------------------------------------- bool PlatformHierarchyInterface::GetOnlyShadowCasters() { return mOnlyShadowCasters; } //----------------------------------------------------------------------- bool PlatformHierarchyInterface::GetTestGeometryForVisibleLeaves() { return mTestGeometryForVisibleLeaves; } //----------------------------------------------------------------------- bool PlatformHierarchyInterface::IsBoundingBoxQuery() { return mIsBoundingBoxQuery; } //----------------------------------------------------------------------- void PlatformHierarchyInterface::RenderGeometry(GtpVisibility::Mesh *geom) { mSceneManager->_renderMovableObject(geom, mLeavePassesInQueue); } //----------------------------------------------------------------------- void PlatformHierarchyInterface::RenderPatch(GtpVisibility::Patch *patch) { mSceneManager->_renderSingleRenderable(patch); } //----------------------------------------------------------------------- SceneManager *PlatformHierarchyInterface::GetSceneManager() { return mSceneManager; } //----------------------------------------------------------------------- RenderSystem *PlatformHierarchyInterface::GetRenderSystem() { return mRenderSystem; } } // namespace Ogre