source: trunk/VUT/Ogre/src/OgrePlatformQueryManager.cpp @ 136

Revision 136, 5.5 KB checked in by mattausch, 19 years ago (diff)

fixed from camera visibility queries.
deletion of (previously) rendered queue items now before rendering the node (more intuitive)
improved octree implementation (tighter boxes)
added boxes for visibility queries

Line 
1#include "OgrePlatformQueryManager.h"
2#include "OcclusionQuery.h"
3#include <OgreSceneManager.h>
4#include <OgreLogManager.h>
5
6#include <vector>
7
8
9namespace Ogre {
10//-----------------------------------------------------------------------
11PlatformQueryManager::PlatformQueryManager(PlatformHierarchyInterface *hierarchyInterface, Viewport *vp):
12QueryManager(hierarchyInterface), mViewport(vp)
13{
14}
15//-----------------------------------------------------------------------
16bool PlatformQueryManager::ShootRay(const Ray &ray, std::vector<Mesh *> *visibleMeshes, bool isGlobalLine)
17{
18    // run OGRE ray shooting query
19    return false;
20}
21//-----------------------------------------------------------------------
22void PlatformQueryManager::ComputeCameraVisibility(const Camera &camera,
23                            InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
24                            InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
25                            bool relativeVisibility)
26{
27        // we need access to the scene manager and the rendersystem
28        PlatformHierarchyInterface *pfHierarchyInterface =
29                dynamic_cast<PlatformHierarchyInterface *>(mHierarchyInterface);
30
31        //-- Render scene to get conservative visibility and fill depth buffer
32
33        // can do const_cast because Camera no changed in renderScene
34        Camera *pCam = const_cast<Camera *>(&camera);
35
36        bool overlayEnabled = mViewport->getOverlaysEnabled();
37        mViewport->setOverlaysEnabled(false);
38        pfHierarchyInterface->GetSceneManager()->_renderScene(pCam, mViewport, false);
39
40        /*
41                Two query lists:
42                We test two to get exact visibility with regard to the current camera and
43                issue all queries at once to avoid starvation & stalls.
44        */
45        GtpVisibility::QueryList queryList[2];
46       
47        // get rendered hierarchy nodes
48        GtpVisibility::HierarchyNodeList *nodeList = mHierarchyInterface->GetRenderedNodes();
49        // vector for storing entities of meshes
50        GtpVisibility::GeometryList geometryList;
51       
52        GtpVisibility::HierarchyNodeList::iterator nodeIt, nodeIt_end = nodeList->end();
53        // geometry list has still do be built
54        GtpVisibility::GeometryList::iterator geometryIt, geometryIt_end;
55
56        // to obtain the correct number of projected pixels, depth write must be disabled
57        bool enableDepthWrite = false;
58
59        // this option must be provided by the scene manager
60        pfHierarchyInterface->GetSceneManager()->setOption("DepthWrite", &enableDepthWrite);
61
62        /* relative visiblity:
63                1) get visible pixels count of objects
64                2) clear frame buffer
65                3) get projected visible pixels count:
66                   test all objects again without depth write (set as option in scene manager)
67                4) calculate ratio between visible vs. projected pixels
68        */
69        // for relative visibility we need 2 rendering passes
70        int n = relativeVisibility ? 2 : 1;
71       
72        for (int i=0; i<n; ++i)
73        {
74                //-- queries for hierarchy nodes
75                for (nodeIt = nodeList->begin(); nodeIt != nodeIt_end; ++nodeIt)               
76                {
77                        // TODO: DELETE QUERIES FROM PREVIOUS RENDER
78                        queryList[i].push_back(mHierarchyInterface->IssueOcclusionQuery(*nodeIt, false));
79                       
80                        // store geometry of the hierarchy node in a geometry list (only once!)
81                        if (i == 0)
82                        {
83                                mHierarchyInterface->GetGeometry(*nodeIt, &geometryList, false);
84                        }
85                }
86
87                geometryIt_end = geometryList.end();
88
89                //-- add queries for geometry
90                for (geometryIt = geometryList.begin(); geometryIt != geometryIt_end; ++geometryIt)
91                {
92                        queryList[i].push_back(mHierarchyInterface->IssueOcclusionQuery(*geometryIt));
93                }
94
95       
96                pfHierarchyInterface->GetRenderSystem()->clearFrameBuffer(FBT_DEPTH);
97        }
98
99        enableDepthWrite = true;
100        // this option must be provided by the scene manager
101        pfHierarchyInterface->GetSceneManager()->setOption("DepthWrite", &enableDepthWrite);
102       
103        mViewport->setOverlaysEnabled(overlayEnabled);
104
105        //---- collect results
106        unsigned int visiblePixels = 0;
107
108        GtpVisibility::QueryList::iterator visQueryIt, projQueryIt;
109
110        visQueryIt = queryList[0].begin();
111        projQueryIt = queryList[1].begin();
112
113       
114        for (nodeIt = nodeList->begin(); nodeIt != nodeIt_end; ++nodeIt)
115        {
116                (*visQueryIt)->GetQueryResult(visiblePixels, true);
117       
118               
119                float vis = (float)visiblePixels;
120
121                if (relativeVisibility)
122                {
123                        (*projQueryIt)->GetQueryResult(visiblePixels, true);
124       
125                        if (visiblePixels > 0)
126                        {                               
127                                vis /= (float) visiblePixels;
128                        }
129                        ++projQueryIt;
130                }
131
132                ++visQueryIt;
133               
134                // leave nodes with visibilty 0 in queue:
135                // happens if node is intersected by near plane
136                visibleNodes->push_back(GtpVisibility::NodeInfo(*nodeIt, vis));
137        }
138
139        //---- queries for geometry
140        geometryIt_end = geometryList.end();
141       
142        for (geometryIt = geometryList.begin(); geometryIt != geometryIt_end; ++geometryIt)
143        {
144                (*visQueryIt)->GetQueryResult(visiblePixels, true);
145               
146
147                float vis = (float)visiblePixels;
148                bool isVisible = visiblePixels > 0;
149               
150                if (relativeVisibility)
151                {
152                        (*projQueryIt)->GetQueryResult(visiblePixels, true);
153
154                        if (visiblePixels)
155                        {
156                                vis /= (float) visiblePixels;
157                        }
158                        ++projQueryIt;
159                }
160
161                ++visQueryIt;
162
163                // approximate depth ordering during rendering =>
164                // geometry maybe occluded
165                if (isVisible)
166                {
167                        visibleGeometry->push_back(GtpVisibility::MeshInfo(*geometryIt, vis));
168                }
169        }
170
171}
172//-----------------------------------------------------------------------
173void PlatformQueryManager::ComputeFromPointVisibility(const Vector3 &point,
174                               InfoContainer<GtpVisibility::NodeInfo> *visibleNodes,
175                               InfoContainer<GtpVisibility::MeshInfo> *visibleGeometry,
176                               bool relativeVisibility)
177{
178       
179}
180//-----------------------------------------------------------------------
181void PlatformQueryManager::SetViewport(Viewport *vp)
182{
183        mViewport = vp;
184}
185} // namespace Ogre
Note: See TracBrowser for help on using the repository browser.