Contents
- Dependencies
- Overview
- New Procedures and Functions
- New Tokens
- Errors
- New State
- New Implementation Dependent State
Dependencies
Written based on the wording of the OpenGL 1.4 specification.
GL_HP_occlusion_test affects the definition of this extension.
Overview
This extension defines a mechanism whereby an application can query the number of pixels (or, more precisely, samples) drawn by a primitive or group of primitives.
The primary purpose of such a query (hereafter referred to as an "occlusion query") is to determine the visibility of an object. Typically, the application will render the major occluders in the scene, then perform an occlusion query for the bounding box of each detail object in the scene. Only if said bounding box is visible, i.e., if at least one sample is drawn, should the corresponding object be drawn.
The earlier GL_HP_occlusion_test extension defined a similar mechanism, but it had two major shortcomings.
It returned the result as a simple GL_TRUE/GL_FALSE result, when in fact it is often useful to know exactly how many samples were drawn.
It provided only a simple "stop-and-wait" model for using multiple queries. The application begins an occlusion test and ends it; then, at some later point, it asks for the result, at which point the driver must stop and wait until the result from the previous test is back before the application can even begin the next one. This is a very simple model, but its performance is mediocre when an application wishes to perform many queries, and it eliminates most of the opportunities for parallelism between the CPU and GPU.
This extension solves both of those problems. It returns as its result the number of samples that pass the depth and stencil tests, and it encapsulates occlusion queries in "query objects" that allow applications to issue many queries before asking for the result of any one. As a result, they can overlap the time it takes for the occlusion query results to be returned with other, more useful work, such as rendering other parts of the scene or performing other computations on the CPU.
There are many situations where a pixel/sample count, rather than a boolean result, is useful.
Objects that are visible but cover only a very small number of pixels can be skipped at a minimal reduction of image quality.
Knowing exactly how many pixels an object might cover may help the application decide which level-of-detail model should be used. If only a few pixels are visible, a low-detail model may be acceptable.
"Depth peeling" techniques, such as order-independent transparency, need to know when to stop rendering more layers; it is difficult to determine a priori how many layers are needed. A boolean result allows applications to stop when more layers will not affect the image at all, but this will likely result in unacceptable performance. Instead, it makes more sense to stop rendering when the number of pixels in each layer falls below a given threshold.
Occlusion queries can replace glReadPixels of the depth buffer to determine whether (for example) a light source is visible for the purposes of a lens flare effect or a halo to simulate glare. Pixel counts allow you to compute the percentage of the light source that is visible, and the brightness of these effects can be modulated accordingly.
New Procedures and Functions
void GenQueriesARB(sizei n, uint *ids);
void DeleteQueriesARB(sizei n, const uint *ids);
boolean IsQueryARB(uint id);
void BeginQueryARB(enum target, uint id);
void EndQueryARB(enum target);
void GetQueryivARB(enum target, enum pname, int *params);
void GetQueryObjectivARB(uint id, enum pname, int *params);
void GetQueryObjectuivARB(uint id, enum pname, uint *params);
New Tokens
Accepted by the
<target>
parameter of BeginQueryARB, EndQueryARB, and GetQueryivARB:
|SAMPLES_PASSED_ARB |0x8914| |:--------------------|:-----|
Accepted by the
<pname>
parameter of GetQueryivARB:
|QUERY_COUNTER_BITS_ARB| 0x8864| |:------------------------|:------| |CURRENT_QUERY_ARB |0x8865 |
Accepted by the
<pname>
parameter of GetQueryObjectivARB and GetQueryObjectuivARB:
|QUERY_RESULT_ARB | 0x8866| |:--------------------|:-------| |QUERY_RESULT_AVAILABLE_ARB |0x8867 |
Errors
The error INVALID_VALUE is generated if GenQueriesARB is called where
<n>
is negative.
The error INVALID_VALUE is generated if DeleteQueriesARB is called where
<n>
is negative.
The error INVALID_OPERATION is generated if GenQueriesARB or DeleteQueriesARB is called when a query of any target is active.
The error INVALID_ENUM is generated if BeginQueryARB, EndQueryARB, or GetQueryivARB is called where
<target>
is not SAMPLES_PASSED_ARB.
The error INVALID_OPERATION is generated if BeginQueryARB is called when a query of the given
<target>
is already active.
The error INVALID_OPERATION is generated if EndQueryARB is called when a query of the given
<target>
is not active.
The error INVALID_OPERATION is generated if BeginQueryARB is called where
<id>
is zero.
The error INVALID_OPERATION is generated if BeginQueryARB is called where
<id>
is is the name of a query currently in progress.
The error INVALID_ENUM is generated if GetQueryivARB is called where
<pname>
is not QUERY_COUNTER_BITS_ARB or CURRENT_QUERY_ARB.
The error INVALID_OPERATION is generated if GetQueryObjectivARB or GetQueryObjectuivARB is called where
<id>
is not the name of a query object.
The error INVALID_OPERATION is generated if GetQueryObjectivARB or GetQueryObjectuivARB is called where
<id>
is the name of a currently active query object.
The error INVALID_ENUM is generated if GetQueryObjectivARB or GetQueryObjectuivARB is called where
<pname>
is not QUERY_RESULT_ARB or QUERY_RESULT_AVAILABLE_ARB.
The error INVALID_OPERATION is generated if any of the commands defined in this extension is executed between the execution of Begin and the corresponding execution of End.