source: GTP/trunk/Lib/Vis/OnlineCullingCHC/OGRE/src/OgreOcclusionQueriesQueryManager.cpp @ 2168

Revision 2168, 15.7 KB checked in by mattausch, 17 years ago (diff)
RevLine 
[154]1#include "OgreOcclusionQueriesQueryManager.h"
2#include <OgreLogManager.h>
3#include <OgreStringConverter.h>
4#include <vector>
[171]5#include <OgreSubEntity.h>
[925]6#include "OgrePlatformHierarchyInterface.h"
[154]7
8namespace Ogre {
[171]9
10//-----------------------------------------------------------------------
11OcclusionQueriesQueryManager::OcclusionQueriesQueryManager(
[925]12                                                        GtpVisibility::HierarchyInterface *hierarchyInterface,
[171]13                                                        Viewport *vp,
[174]14                                                        int queryModes,
15                                                        int itemBufferMode):
16PlatformQueryManager(hierarchyInterface, vp, queryModes),
17mItemBufferMode(itemBufferMode)
[154]18{
19}
20//-----------------------------------------------------------------------
21void OcclusionQueriesQueryManager::ComputeCameraVisibility(const Camera &camera,
[931]22                                                                                                                   GtpVisibility::NodeInfoContainer *visibleNodes,
23                                                                                                                   GtpVisibility::MeshInfoContainer *visibleGeometry,
24                                                                                                                   GtpVisibility::PatchInfoContainer *visiblePatches,
25                                                                                                                   bool relativeVisibility)
[154]26{
[174]27        // we need access to the scene manager and the rendersystem
[154]28        PlatformHierarchyInterface *pfHierarchyInterface =
[2066]29                //static_cast<PlatformHierarchyInterface *>(mHierarchyInterface);
[726]30                static_cast<PlatformHierarchyInterface *>(mHierarchyInterface);
[154]31
32        // disable overlays, reset them later
33        bool overlayEnabled = mViewport->getOverlaysEnabled();
[2168]34Ogre::LogManager::getSingleton().logMessage("here020202");
[1602]35        ///////////
[171]36        //-- render scene with item buffer (i.e., objects with their id as color codes)
[175]37//mItemBufferMode = 0;
[174]38        if ((mItemBufferMode && mQueryModes) != 0)
[171]39        {
[174]40                int savedQueryModes = mQueryModes;
41                mQueryModes = mItemBufferMode;
42               
[171]43                PlatformQueryManager::ComputeCameraVisibility(camera, visibleNodes,
44                            visibleGeometry, visiblePatches, relativeVisibility);
[174]45               
46                // overlays cause false visibility
[171]47                mViewport->setOverlaysEnabled(false);
[174]48                mQueryModes = savedQueryModes;
[171]49        }
50        else
51        {
52                // const_cast allowed because camera is not changed in renderScene
53                Camera *pCam = const_cast<Camera *>(&camera);
54                mViewport->setOverlaysEnabled(false);
55
56                //-- Render scene to get conservative visibility and fill depth buffer
57                pfHierarchyInterface->GetSceneManager()->_renderScene(pCam, mViewport, false);
58        }
59
60       
61        /*      Two query lists for projected pixels and for visibile pixels:
[154]62                We test queries after a rendering pass
63                to get exact visibility with regard to the current camera.
64                We issue all queries at once to avoid starvation & stalls.
65        */
66        GtpVisibility::QueryList queryList[2];
67       
[174]68        // rendered visibile hierarchy nodes from previous rendering
[370]69        GtpVisibility::NodeVector *visNodes = mHierarchyInterface->GetVisibleNodes();
70        GtpVisibility::NodeVector::iterator visNodesIt, visNodesIt_end = visNodes->end();
[171]71
[370]72    GtpVisibility::NodeVector nodeList;
[174]73
[175]74        if (mQueryModes & NODE_VISIBILITY)
[174]75        {
76                for (visNodesIt = visNodes->begin(); visNodesIt != visNodesIt_end; ++visNodesIt)
77                {
78                        nodeList.push_back((*visNodesIt));
79                }
80        }
81
[370]82        GtpVisibility::NodeVector::iterator nodeIt, nodeIt_end = nodeList.end();
[174]83
[154]84        // vector for storing entities of meshes
[370]85        GtpVisibility::GeometryVector geometryList;
[154]86       
[174]87        // store geometry of the hierarchy nodes in a geometry list
[175]88        if (mQueryModes & GEOMETRY_VISIBILITY)
[174]89        {       
90                for (visNodesIt = visNodes->begin(); visNodesIt != visNodesIt_end; ++visNodesIt)       
91                {
92                        mHierarchyInterface->GetNodeGeometryList(*visNodesIt, &geometryList, false);
93                }
[171]94        }
[174]95       
[171]96        // geometry list iterator
[370]97        GtpVisibility::GeometryVector::iterator geometryIt, geometryIt_end = geometryList.end();
[171]98
[173]99        // vector for storing subentities of meshes
[370]100        GtpVisibility::PatchVector patchList;
[174]101
102        // store patchges of the geometries in a patch list
[175]103        if (mQueryModes & PATCH_VISIBILITY)
[174]104        {
105                for (visNodesIt = visNodes->begin(); visNodesIt != visNodesIt_end; ++visNodesIt)       
106                {
107                        GetNodePatchList(*visNodesIt, &patchList);
108                }
109        }
110
[370]111        GtpVisibility::PatchVector::iterator patchIt, patchIt_end = patchList.end();
[171]112
[154]113        // to obtain the correct number of projected pixels, depth write must be disabled
114        bool enableDepthWrite = false;
115        // this option must be provided by the scene manager
116        pfHierarchyInterface->GetSceneManager()->setOption("DepthWrite", &enableDepthWrite);
117
[171]118
[154]119        /* relative visiblity:
[171]120           1) get visible pixels count of objects
121           2) clear frame buffer
122           3) get projected visible pixels count:
123              test all objects again without depth write (set as option in scene manager)
124           4) calculate ratio between visible vs. projected pixels
[154]125        */
[171]126               
[154]127        // for relative visibility we need 2 rendering passes
128        int n = relativeVisibility ? 2 : 1;
[175]129        if (mItemBufferMode > 0)
130                LogManager::getSingleton().logMessage("item buffer");
131
[171]132        for (int i = 0; i < n; ++i)
[154]133        {
134                //-- queries for hierarchy nodes
[174]135                for (nodeIt = nodeList.begin(); nodeIt != nodeIt_end; ++nodeIt)         
[154]136                {
137                        // TODO: DELETE QUERIES FROM PREVIOUS RENDER
[175]138                        queryList[i].push_back(mHierarchyInterface->IssueNodeOcclusionQuery(*nodeIt, false));
[154]139                }
140
[171]141                //-- queries for geometry: if item buffer, capture only projected visibility
[174]142                if ((mItemBufferMode != GEOMETRY_VISIBILITY) || (i == 1))
[175]143                {                       
[174]144                        for (geometryIt = geometryList.begin(); geometryIt != geometryIt_end; ++geometryIt)
145                        {
[175]146                                queryList[i].push_back(pfHierarchyInterface->IssueMeshOcclusionQuery(*geometryIt));
[174]147                        }
[173]148                }
149               
150                //-- queries for patches: if item buffer, capture only projected visibility
[174]151                if ((mItemBufferMode != PATCH_VISIBILITY) || (i == 1))
[154]152                {
[173]153                        for (patchIt = patchList.begin(); patchIt != patchIt_end; ++patchIt)
[171]154                        {
[175]155                                queryList[i].push_back(pfHierarchyInterface->IssuePatchOcclusionQuery(*patchIt));
[171]156                        }
[154]157                }
158
159                pfHierarchyInterface->GetRenderSystem()->clearFrameBuffer(FBT_DEPTH);
160        }
161
[171]162       
163        //-- collect results
164        GtpVisibility::QueryList::iterator visQueryIt = queryList[0].begin();
165        GtpVisibility::QueryList::iterator projQueryIt = queryList[1].begin();
166       
[174]167        // collect occlusion queries for hierarchy nodes
168        CollectNodeVisibility(visQueryIt, projQueryIt, &nodeList, visibleNodes, relativeVisibility);
[171]169
[174]170
171        // collect occlusion queries for geometry
172        if ((mItemBufferMode == GEOMETRY_VISIBILITY) && relativeVisibility)
[171]173        {
[174]174                // if visibility was established using the item buffer,
175                // the array is organized different (e.g., ordered by id, all possible objects)
176                CollectRelativeGeometryVisibilityForItemBuffer(projQueryIt, &geometryList, visibleGeometry);
177        }
[175]178        else if (mItemBufferMode != GEOMETRY_VISIBILITY)
[171]179        {
[174]180                CollectGeometryVisibility(visQueryIt, projQueryIt, &geometryList, visibleGeometry,
181                                                                  relativeVisibility);
182        }
183
184
185        // collect occlusion queries for patches
186        if ((mItemBufferMode == PATCH_VISIBILITY) && relativeVisibility)
187        {
188                CollectRelativePatchVisibilityForItemBuffer(projQueryIt, &patchList, visiblePatches);
189        }
[175]190        else if (mItemBufferMode != PATCH_VISIBILITY)
[174]191        {
[173]192                CollectPatchVisibility(visQueryIt, projQueryIt, &patchList, visiblePatches, relativeVisibility);
193        }       
[174]194
[173]195               
[2066]196        //-- reset options
[154]197        enableDepthWrite = true;
198        // this option must be provided by the scene manager
199        pfHierarchyInterface->GetSceneManager()->setOption("DepthWrite", &enableDepthWrite);
200        // reset old overlay status
[2066]201        mViewport->setOverlaysEnabled(overlayEnabled);
202
203        mWasInitialised = false;
[171]204}
205//-----------------------------------------------------------------------
206void OcclusionQueriesQueryManager::ComputeFromPointVisibility(const Vector3 &point,
[316]207                               GtpVisibility::NodeInfoContainer *visibleNodes,
208                               GtpVisibility::MeshInfoContainer *visibleGeometry,
209                                   GtpVisibility::PatchInfoContainer *visiblePatches,
[171]210                               bool relativeVisibility)
[2168]211{Ogre::LogManager::getSingleton().logMessage("here5");
[171]212        PlatformQueryManager::ComputeFromPointVisibility(point, visibleNodes,
213                visibleGeometry, visiblePatches, relativeVisibility);
[154]214
[175]215        // adds up their visibility and removes duplicates
216        // (duplicates occur if an object is on the edge of the viewport)
[171]217        RemoveDuplicateNodes(visibleNodes);
[2168]218        Ogre::LogManager::getSingleton().logMessage("here6");
[174]219        if (mItemBufferMode != GEOMETRY_VISIBILITY)
[154]220        {
[171]221                RemoveDuplicateGeometry(visibleGeometry);
222        }
[2168]223        Ogre::LogManager::getSingleton().logMessage("here7");
[174]224        if (mItemBufferMode != PATCH_VISIBILITY)
225        {
226                RemoveDuplicatePatches(visiblePatches);
227        }
[171]228}
[645]229//------------------------------------------------------------------------
[171]230void  OcclusionQueriesQueryManager::CollectNodeVisibility(
231                                                GtpVisibility::QueryList::iterator &visQueryIt,
232                                                GtpVisibility::QueryList::iterator &projQueryIt,
[370]233                                                GtpVisibility::NodeVector *nodeList, 
[316]234                                                GtpVisibility::NodeInfoContainer *visibleNodes,
[171]235                                                bool relativeVisibility)
236{
[370]237        GtpVisibility::NodeVector::iterator nodeIt;
[171]238
239        //-- queries for nodes
240        for (nodeIt = nodeList->begin(); nodeIt != nodeList->end(); ++nodeIt)
241        {
[154]242                unsigned int visiblePixels = 0;
243                (*visQueryIt)->GetQueryResult(visiblePixels, true);
244       
245                unsigned int projectedPixels = 0;
246
247                if (relativeVisibility)
248                {
249                        (*projQueryIt)->GetQueryResult(projectedPixels, true);
250               
251                        ++projQueryIt;
252                }
253
254                ++visQueryIt;
255               
256                // node with visibilty 0 in queue (e.g., if node is intersected by near plane)
257                if (visiblePixels > 0)
258                {
[171]259                        visibleNodes->push_back(GtpVisibility::NodeInfo(*nodeIt, visiblePixels,
260                                projectedPixels));
[154]261                }
[2066]262        }
263}
[171]264//-----------------------------------------------------------------------
265void OcclusionQueriesQueryManager::CollectRelativeGeometryVisibilityForItemBuffer(
[2066]266                                                                        GtpVisibility::QueryList::iterator &projQueryIt,
267                                                                        GtpVisibility::GeometryVector *geometryList,
268                                                                        GtpVisibility::MeshInfoContainer *visibleGeometry)
269{
270        GtpVisibility::GeometryVector::iterator geometryIt;
271
[171]272        //-- queries for geometry
273        for (geometryIt = geometryList->begin(); geometryIt != geometryList->end(); ++ geometryIt)
[154]274        {
[171]275                unsigned int projectedPixels = 0;
276
277                (*projQueryIt)->GetQueryResult(projectedPixels, true);
278
279                ++projQueryIt;
280                int id = (*geometryIt)->getSubEntity(0)->getId();
281
282                if ((id > 0) && (id < (int)visibleGeometry->size()))
283                {
284                        (*visibleGeometry)[id].AddVisibility(0, projectedPixels);
285                }
[2066]286        }
287}
[171]288//-----------------------------------------------------------------------
289void OcclusionQueriesQueryManager::CollectRelativePatchVisibilityForItemBuffer(
[2066]290                                                                        GtpVisibility::QueryList::iterator &projQueryIt,
291                                                                        GtpVisibility::PatchVector *patchList,
292                                                                        GtpVisibility::PatchInfoContainer *visiblePatches)
293{
294        GtpVisibility::PatchVector::iterator patchIt;
295
[171]296        //-- queries for geometry
297        for (patchIt = patchList->begin(); patchIt != patchList->end(); ++ patchIt)
298        {
299                unsigned int projectedPixels = 0;
300
301                (*projQueryIt)->GetQueryResult(projectedPixels, true);
302
303                ++projQueryIt;
304                int id = (*patchIt)->getId();
305
306                if ((id > 0) && (id < (int)visiblePatches->size()))
307                {
308                        (*visiblePatches)[id].AddVisibility(0, projectedPixels);
309                }
[2066]310        }
311}
[171]312//-----------------------------------------------------------------------
313void  OcclusionQueriesQueryManager::CollectGeometryVisibility(
314                                                        GtpVisibility::QueryList::iterator &visQueryIt,
315                                                        GtpVisibility::QueryList::iterator &projQueryIt,
[370]316                                                        GtpVisibility::GeometryVector *geometryList,
[316]317                                                        GtpVisibility::MeshInfoContainer *visibleGeometry,
[171]318                                                        bool relativeVisibility)
[2066]319{
320        GtpVisibility::GeometryVector::iterator geometryIt;
321
[171]322        //-- queries for geometry
323        for (geometryIt = geometryList->begin(); geometryIt != geometryList->end(); ++ geometryIt)
324        {
[154]325                unsigned int visiblePixels = 0;
326                (*visQueryIt)->GetQueryResult(visiblePixels, true);
327               
328                unsigned int projectedPixels = 0;
329
330                if (relativeVisibility)
331                {
332                        (*projQueryIt)->GetQueryResult(projectedPixels, true);
[171]333                        ++ projQueryIt;
[154]334                }
335
[171]336                ++ visQueryIt;
[154]337
[155]338                // WARNING: approximate depth ordering during rendering =>
[154]339                // geometry maybe occluded
340                if (visiblePixels > 0)
[2066]341                {                       
[154]342                        visibleGeometry->push_back(GtpVisibility::MeshInfo(*geometryIt, visiblePixels,
343                                projectedPixels));
344                }
[2066]345        }
[154]346}
347//-----------------------------------------------------------------------
[171]348void  OcclusionQueriesQueryManager::CollectPatchVisibility(
349                                                        GtpVisibility::QueryList::iterator &visQueryIt,
350                                                        GtpVisibility::QueryList::iterator &projQueryIt,
[370]351                                                        GtpVisibility::PatchVector *patchList,
[316]352                                                        GtpVisibility::PatchInfoContainer *visiblePatches,
[171]353                                                        bool relativeVisibility)
[2066]354{
355        GtpVisibility::PatchVector::iterator patchIt;
356
[171]357        //-- queries for patch
358        for (patchIt = patchList->begin(); patchIt != patchList->end(); ++ patchIt)
359        {
360                unsigned int visiblePixels = 0;
361                (*visQueryIt)->GetQueryResult(visiblePixels, true);
362               
363                unsigned int projectedPixels = 0;
364
365                if (relativeVisibility)
366                {
367                        (*projQueryIt)->GetQueryResult(projectedPixels, true);
368                        ++ projQueryIt;
369                }
370
371                ++ visQueryIt;
372
373                // WARNING: approximate depth ordering during rendering =>
374                // patch maybe occluded
375                if (visiblePixels > 0)
[2066]376                {                       
[171]377                        visiblePatches->push_back(GtpVisibility::PatchInfo(*patchIt, visiblePixels,
378                                projectedPixels));
379                }
[2066]380        }
[154]381}
382//-----------------------------------------------------------------------
[171]383void  OcclusionQueriesQueryManager::RemoveDuplicateNodes(
[316]384                                        GtpVisibility::NodeInfoContainer *visibleNodes)
[154]385{
[318]386        stable_sort(visibleNodes->begin(), visibleNodes->end()/*, nodeinfo_lt*/);
[316]387
388        GtpVisibility::NodeInfoContainer::iterator visibleNodesIt,
[154]389                visibleNodesIt_end = visibleNodes->end();
390       
391        GtpVisibility::NodeInfo *nodeInfo = NULL;
392
393        for (visibleNodesIt = visibleNodes->begin(); visibleNodesIt != visibleNodesIt_end;
394                ++visibleNodesIt)
395        {
[316]396                if (!nodeInfo || (nodeInfo->GetSource() != (*visibleNodesIt).GetSource()))
[154]397                {
398                        nodeInfo = &(*visibleNodesIt);
399                }
400                else // add visibility
401                {                       
402                        nodeInfo->AddVisibility(*visibleNodesIt);
403                }
404        }
405       
406        // physically delete duplicates
[318]407        visibleNodes->erase(std::unique(visibleNodes->begin(), visibleNodes->end()),
[316]408                                                visibleNodes->end());
[171]409}
410//-----------------------------------------------------------------------
411void  OcclusionQueriesQueryManager::RemoveDuplicateGeometry(
[316]412                                GtpVisibility::MeshInfoContainer *visibleGeometry)
[171]413{
[318]414        stable_sort(visibleGeometry->begin(), visibleGeometry->end());
[171]415       
[316]416        GtpVisibility::MeshInfoContainer::iterator visibleGeomIt,
[171]417                        visibleGeomIt_end = visibleGeometry->end();
[154]418
419        GtpVisibility::MeshInfo *geomInfo = NULL;
420
421        for (visibleGeomIt = visibleGeometry->begin(); visibleGeomIt != visibleGeomIt_end;
422                ++visibleGeomIt)
423        {
[316]424                if (!geomInfo || (geomInfo->GetSource() != (*visibleGeomIt).GetSource()))
[154]425                {
426                        geomInfo = &(*visibleGeomIt);
427                }
428                else // info points to same mesh, just add visibility
429                {
430                        geomInfo->AddVisibility(*visibleGeomIt);
431                }
432        }
433
434        // physically delete duplicates
[318]435        visibleGeometry->erase(std::unique(visibleGeometry->begin(), visibleGeometry->end()),
[316]436                                                   visibleGeometry->end());
[154]437}
[173]438//-----------------------------------------------------------------------
439void  OcclusionQueriesQueryManager::RemoveDuplicatePatches(
[316]440                                GtpVisibility::PatchInfoContainer *visiblePatches)
[173]441{
[318]442        stable_sort(visiblePatches->begin(), visiblePatches->end());
[173]443       
[316]444        GtpVisibility::PatchInfoContainer::iterator visiblePatchIt,
[173]445                        visiblePatchIt_end = visiblePatches->end();
[154]446
[173]447        GtpVisibility::PatchInfo *patchInfo = NULL;
448
449        for (visiblePatchIt = visiblePatches->begin(); visiblePatchIt != visiblePatchIt_end;
450                ++visiblePatchIt)
451        {
[316]452                if (!patchInfo || (patchInfo->GetSource() != (*visiblePatchIt).GetSource()))
[173]453                {
454                        patchInfo = &(*visiblePatchIt);
455                }
456                else // info points to same mesh, just add visibility
457                {
458                        patchInfo->AddVisibility(*visiblePatchIt);
459                }
460        }
461
462        // physically delete duplicates
[318]463        visiblePatches->erase(std::unique(visiblePatches->begin(), visiblePatches->end()),
[316]464                                                  visiblePatches->end());
[2066]465}
[174]466//-----------------------------------------------------------------------
[2066]467void OcclusionQueriesQueryManager::GetNodePatchList(GtpVisibility::HierarchyNode *node,
[370]468                                                                                                        GtpVisibility::PatchVector *patchList)
[174]469{
[370]470        GtpVisibility::GeometryVector geomList;
[174]471        mHierarchyInterface->GetNodeGeometryList(node, &geomList, false);
472
473        // geometry list iterator
[370]474        GtpVisibility::GeometryVector::iterator geomIt, geomIt_end = geomList.end();
[174]475
476        for (geomIt = geomList.begin(); geomIt != geomIt_end; ++geomIt)
477        {
[2066]478                for     (int i = 0; i < (int)(*geomIt)->getNumSubEntities(); ++i)
479                {
480                        patchList->push_back((*geomIt)->getSubEntity(i));
[174]481                }
482        }
[173]483}
[174]484
[154]485} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.