Skip to content

Commit 1dd386e

Browse files
committed
Samples: Lighting - refactor occlusion query code
1 parent 3880567 commit 1dd386e

File tree

1 file changed

+78
-110
lines changed

1 file changed

+78
-110
lines changed

Samples/Simple/include/Lighting.h

Lines changed: 78 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,48 @@
77
using namespace Ogre;
88
using namespace OgreBites;
99

10-
class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderObjectListener
10+
struct OcclusionQueryActivator : public RenderObjectListener
11+
{
12+
HardwareOcclusionQuery* mActiveQuery = NULL;
13+
14+
std::map<Renderable*, HardwareOcclusionQuery*> mQueryMap;
15+
16+
// Event raised when render single object started.
17+
void notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
18+
const LightList* pLightList, bool suppressRenderStateChanges) override
19+
{
20+
//
21+
// The following code activates and deactivates the occlusion queries
22+
// so that the queries only include the rendering of their intended targets
23+
//
24+
25+
// Close the last occlusion query
26+
// Each occlusion query should only last a single rendering
27+
if (mActiveQuery)
28+
{
29+
mActiveQuery->end();
30+
mActiveQuery = NULL;
31+
}
32+
33+
// Open a new occlusion query
34+
35+
// Check if a the object being rendered needs
36+
// to be occlusion queried, and by which query instance.
37+
auto it = mQueryMap.find(rend);
38+
if(it == mQueryMap.end())
39+
return;
40+
41+
// Stop occlusion query until we get the information
42+
// (may not happen on the same frame they are requested in)
43+
if(!it->second->resultReady())
44+
return;
45+
46+
mActiveQuery = it->second;
47+
mActiveQuery->begin();
48+
}
49+
};
50+
51+
class _OgreSampleClassExport Sample_Lighting : public SdkSample
1152
{
1253
static const uint8 cPriorityMain = 50;
1354
static const uint8 cPriorityQuery = 51;
@@ -25,11 +66,7 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb
2566
mLight1QueryArea(NULL),
2667
mLight1QueryVisible(NULL),
2768
mLight2QueryArea(NULL),
28-
mLight2QueryVisible(NULL),
29-
mActiveQuery(NULL),
30-
mUseOcclusionQuery(false),
31-
mDoOcclusionQuery(false)
32-
69+
mLight2QueryVisible(NULL)
3370
{
3471
mInfo["Title"] = "Lighting";
3572
mInfo["Description"] = "Shows OGRE's lighting support. Also demonstrates "
@@ -41,40 +78,24 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb
4178

4279
bool frameRenderingQueued(const FrameEvent& evt) override
4380
{
44-
// Modulate the light flare according to performed occlusion queries
45-
if (mUseOcclusionQuery)
81+
if (mLight1QueryArea)
4682
{
47-
// Stop occlusion queries until we get their information
48-
// (may not happen on the same frame they are requested in)
49-
mDoOcclusionQuery = false;
83+
// Modulate the lights according to the query data
84+
unsigned int lightAreaCount;
85+
unsigned int lightVisibleCount;
86+
float ratio;
5087

51-
// Check if all query information available
52-
if ((mLight1QueryArea->isStillOutstanding() == false) &&
53-
(mLight1QueryVisible->isStillOutstanding() == false) &&
54-
(mLight2QueryArea->isStillOutstanding() == false) &&
55-
(mLight2QueryVisible->isStillOutstanding() == false))
56-
{
57-
// Modulate the lights according to the query data
58-
unsigned int lightAreaCount;
59-
unsigned int lightVisibleCount;
60-
float ratio;
61-
62-
mLight1QueryArea->pullOcclusionQuery(&lightAreaCount);
63-
mLight1QueryVisible->pullOcclusionQuery(&lightVisibleCount);
64-
ratio = float(lightVisibleCount) / float(lightAreaCount);
65-
mLight1BBFlare->setColour(mTrail->getInitialColour(0) * ratio);
66-
67-
mLight2QueryArea->pullOcclusionQuery(&lightAreaCount);
68-
mLight2QueryVisible->pullOcclusionQuery(&lightVisibleCount);
69-
ratio = float(lightVisibleCount) / float(lightAreaCount);
70-
mLight2BBFlare->setColour(mTrail->getInitialColour(1) * ratio);
71-
72-
// Request new query data
73-
mDoOcclusionQuery = true;
74-
}
88+
lightAreaCount = mLight1QueryArea->getLastResult();
89+
lightVisibleCount = mLight1QueryVisible->getLastResult();
90+
ratio = float(lightVisibleCount) / float(lightAreaCount);
91+
mLight1BBFlare->setColour(mTrail->getInitialColour(0) * ratio);
92+
93+
lightAreaCount = mLight2QueryArea->getLastResult();
94+
lightVisibleCount = mLight2QueryVisible->getLastResult();
95+
ratio = float(lightVisibleCount) / float(lightAreaCount);
96+
mLight2BBFlare->setColour(mTrail->getInitialColour(1) * ratio);
7597
}
7698

77-
7899
return SdkSample::frameRenderingQueued(evt); // don't forget the parent class updates!
79100
}
80101

@@ -112,26 +133,15 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb
112133
mTrail->setRenderQueueGroup(cPriorityLights);
113134

114135
// Create the occlusion queries to be used in this sample
115-
try {
116-
RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem();
117-
mLight1QueryArea = renderSystem->createHardwareOcclusionQuery();
118-
mLight1QueryVisible = renderSystem->createHardwareOcclusionQuery();
119-
mLight2QueryArea = renderSystem->createHardwareOcclusionQuery();
120-
mLight2QueryVisible = renderSystem->createHardwareOcclusionQuery();
121-
122-
mUseOcclusionQuery = (mLight1QueryArea != NULL) &&
123-
(mLight1QueryVisible != NULL) &&
124-
(mLight2QueryArea != NULL) &&
125-
(mLight2QueryVisible != NULL);
126-
}
127-
catch (Exception& e)
128-
{
129-
mUseOcclusionQuery = false;
130-
}
136+
RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem();
137+
mLight1QueryArea = renderSystem->createHardwareOcclusionQuery();
138+
mLight1QueryVisible = renderSystem->createHardwareOcclusionQuery();
139+
mLight2QueryArea = renderSystem->createHardwareOcclusionQuery();
140+
mLight2QueryVisible = renderSystem->createHardwareOcclusionQuery();
131141

132-
if (mUseOcclusionQuery == false)
142+
if (!mLight1QueryArea)
133143
{
134-
LogManager::getSingleton().logError("Sample_Lighting - failed to create hardware occlusion query");
144+
LogManager::getSingleton().logWarning("Sample_Lighting - hardware occlusion query not available");
135145
}
136146

137147
// Create the materials to be used by the objects used fo the occlusion query
@@ -195,7 +205,7 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb
195205
bbs->setRenderQueueGroup(cPriorityLights);
196206
node->attachObject(bbs);
197207

198-
if (mUseOcclusionQuery)
208+
if (mLight1QueryArea)
199209
{
200210
// Attach a billboard which will be used to get a relative area occupied by the light
201211
mLight1BBQueryArea = mSceneMgr->createBillboardSet(1);
@@ -254,7 +264,7 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb
254264
bbs->setRenderQueueGroup(cPriorityLights);
255265
node->attachObject(bbs);
256266

257-
if (mUseOcclusionQuery)
267+
if (mLight1QueryArea)
258268
{
259269
// Attach a billboard which will be used to get a relative area occupied by the light
260270
mLight2BBQueryArea = mSceneMgr->createBillboardSet(1);
@@ -271,65 +281,23 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb
271281
mLight2BBQueryVisible->setMaterial(matQueryVisible);
272282
mLight2BBQueryVisible->setRenderQueueGroup(cPriorityQuery);
273283
node->attachObject(mLight2BBQueryVisible);
274-
}
275-
276-
// Setup the listener for the occlusion query
277-
if (mUseOcclusionQuery)
278-
{
279-
mSceneMgr->addRenderObjectListener(this);
280-
mDoOcclusionQuery = true;
281-
}
282-
}
283-
284-
// Event raised when render single object started.
285-
void notifyRenderSingleObject(Renderable* rend, const Pass* pass, const AutoParamDataSource* source,
286-
const LightList* pLightList, bool suppressRenderStateChanges) override
287-
{
288-
//
289-
// The following code activates and deactivates the occlusion queries
290-
// so that the queries only include the rendering of their intended targets
291-
//
292-
293-
// Close the last occlusion query
294-
// Each occlusion query should only last a single rendering
295-
if (mActiveQuery != NULL)
296-
{
297-
mActiveQuery->endOcclusionQuery();
298-
mActiveQuery = NULL;
299-
}
300284

301-
// Open a new occlusion query
302-
if (mDoOcclusionQuery == true)
303-
{
304-
// Check if a the object being rendered needs
305-
// to be occlusion queried, and by which query instance.
306-
if (rend == mLight1BBQueryArea)
307-
mActiveQuery = mLight1QueryArea;
308-
else if (rend == mLight1BBQueryVisible)
309-
mActiveQuery = mLight1QueryVisible;
310-
else if (rend == mLight2BBQueryArea)
311-
mActiveQuery = mLight2QueryArea;
312-
else if (rend == mLight2BBQueryVisible)
313-
mActiveQuery = mLight2QueryVisible;
314-
315-
if (mActiveQuery != NULL)
316-
{
317-
mActiveQuery->beginOcclusionQuery();
318-
}
285+
mOcclusionQueryActivator.mQueryMap[mLight2BBQueryArea] = mLight2QueryArea;
286+
mOcclusionQueryActivator.mQueryMap[mLight2BBQueryVisible] = mLight2QueryVisible;
287+
mOcclusionQueryActivator.mQueryMap[mLight1BBQueryArea] = mLight1QueryArea;
288+
mOcclusionQueryActivator.mQueryMap[mLight1BBQueryVisible] = mLight1QueryVisible;
289+
// Setup the listener for the occlusion query
290+
mSceneMgr->addRenderObjectListener(&mOcclusionQueryActivator);
319291
}
320292
}
321293

322294
void cleanupContent() override
323295
{
324296
RenderSystem* renderSystem = Ogre::Root::getSingleton().getRenderSystem();
325-
if (mLight1QueryArea != NULL)
326-
renderSystem->destroyHardwareOcclusionQuery(mLight1QueryArea);
327-
if (mLight1QueryVisible != NULL)
328-
renderSystem->destroyHardwareOcclusionQuery(mLight1QueryVisible);
329-
if (mLight2QueryArea != NULL)
330-
renderSystem->destroyHardwareOcclusionQuery(mLight2QueryArea);
331-
if (mLight2QueryVisible != NULL)
332-
renderSystem->destroyHardwareOcclusionQuery(mLight2QueryVisible);
297+
for (const auto& it : mOcclusionQueryActivator.mQueryMap)
298+
{
299+
renderSystem->destroyHardwareOcclusionQuery(it.second);
300+
}
333301
}
334302

335303
RibbonTrail* mTrail;
@@ -345,10 +313,10 @@ class _OgreSampleClassExport Sample_Lighting : public SdkSample, public RenderOb
345313
HardwareOcclusionQuery* mLight1QueryVisible;
346314
HardwareOcclusionQuery* mLight2QueryArea;
347315
HardwareOcclusionQuery* mLight2QueryVisible;
348-
HardwareOcclusionQuery* mActiveQuery;
316+
317+
OcclusionQueryActivator mOcclusionQueryActivator;
349318

350319
bool mUseOcclusionQuery;
351-
bool mDoOcclusionQuery;
352320
};
353321

354322
#endif

0 commit comments

Comments
 (0)