occlusion query

how does it exactly work?

looking at the spec

Here is the previous example, enhanced using occlusion queries.
GLuint queries[N];
GLuint sampleCount;
glGenQueriesARB(N, queries);

// First rendering pass plus almost-free visibility checks
actually this will not work for what they want

u need to
A/ render depth buffer
B/ rerender depth buffer again (with glBeginQueryARB(GL_SAMPLES_PASSED_ARB, queries[i]); etc
C/ get result

it seems as if theyve skipped step A in the spec.
am i correct? if so ive gotta rethink my depth pass :frowning:

Well, assuming it’s reasonably well-sorted in front-to-back order their approach is OK. Otherwise you need to do a depth pass first. Then you can do occlusion culling even on the first non-depth pass.

We can assume the … means render the other objects.
Then you render the target object (the object who’s results you want with the queries)

Also, they should put glDepthFunc(GL_LEQUAL); instead and never change that during program execution.

Personally, I don’t understand why they put glDepthMask(GL_FALSE); in the first example.

My interpretation of the spec is that occlusion query counts samples that pass the depth test. It doesn’t require you to enable depth testing, or even have a depth buffer (in this case, the depth test always passes.)

i.e. you should be able to draw 2D quads and count how many fragments were drawn.

Well, assuming it’s reasonably well-sorted in front-to-back order their approach is OK.
its not ok, its gonna return results saying that meshX is visable when it is in fact occluded (this is whats its doing with my front to back sorted scene)

part of the problem is the wording
// First rendering pass plus almost-free visibility checks
it should say ‘Second’ rendering pass, as u have to render the depth info first

V-man u should use glDepthMask(GL_FALSE); whenever possible its a performance win

i think ill follow humus’es advice + change my app to do the occlusion test at the same time it does the directional sunlight shaded pass (no major problem)

If you have your scene subdivided into some kind of sectors (BSP tree or other approach), then you can first render the sector you’re in, then start rendering neighbour sectors and so on.
Count samples rendered for each sector - keep this information for next frame.
A simple approach:
-visible sector - render in next frame
-invisible sector adjacent to visible sector - render it’s bounding box (color mask = FALSE)
-invisible sector not adjacent to any visible sector - skip

This solution works in single pass but has one major disadvantage - if you turn around sectors will start to appear one per frame. This could be solved if you would check occlusion query result at end of frame and see if you need to render additional sector to fill empty space. If yes, render it and perform occlusion query on invisible sectors adjacent to it - repeat checking occlusion query until all sectors are correct.
To avoid waiting for query results you could start rendering next frame before displaying previous one. If application uses HDR then it renders offscreen anyway. If additional sectors need to be rendered you render them into both frames, and you should get updated query result for frame A before you finish rendering these sectors to frame B - you can re-check results again.
Of course when rendering to frame B you also collect query results for later use (at end of frame B/beginning of frame C).

Or if you have two-pass approach, then you can render visible sectors + bounding boxes for adjacent invisible sectors, and after performing second pass for visible sectors you should have occlusion query results ready. You can then perform first pass again for newly appeared sectors and their invisible neighbours. While performing 2nd pass for them you will get further updated query results, and so on. All in 1 frame without passing query results to next one.

Originally posted by zed:
its not ok, its gonna return results saying that meshX is visable when it is in fact occluded
Which is fine if it’s only used as an optimization. It’s a conservative check that in some cases may say that meshX is visible when it isn’t, but often enough will report occluded objects as occluded and hence be able to speed things up even if it’s not a perfect test. The important thing is that it never says it’s occluded when it’s not, which would break rendering.