<p>If what you are interested in is the area, you could downsize the stencil buffer until you reach one pixel and deduce that area from its color.</p>

<p>Steps would be:</p>

<ul>
<li>Copy the stencil to a texture, using a format with enough precision.</li>
<li>Load a shader that outputs a color proportional to the number of texels with a given color.</li>
<li>Ping-pong between to framebuffers to reduce the size by half until reaching one pixel.</li>
<li>The color of the pixel is the percentage of the viewport covered by the area: just multiply it by the area of the viewport.</li>
</ul>

CC BY-SA 3.0
2015-08-05T02:23:49.107Z
2015-08-05T02:23:49.107Z
Julien Guertault
<p>One possible approach could be the use of Hardware Occlusion Query.</p>

<p>You can use the facts that, by specification, the Stencil Test is executed before the depth test, and only the fragments that pass the depth test are counted by the Occlusion Query.</p>

<p>A simple example (not tested) would be like:</p>

<pre><code>    GLuint samples_query = 0;
    GLuint samples_passed = 0;
    glGenQueries(1, &amp;samples_query);
    // Initialize your buffers and textures ...
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Set up the values on the stencil buffer ...

    // Now we count the fragments that pass the stencil test
    glDepthFunc(GL_ALWAYS); // Set up the depth test to always pass
    glBeginQuery(GL_SAMPLES_PASSED, samples_query);
    // Render your meshes here
    glEndQuery(GL_SAMPLES_PASSED);
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT, &amp;samples_passed);
    // samples_passed holds the number of fragments that passed the stencil test (if any)

    // Release your resources ...
    glDeleteQueries(1, &amp;samples_query);
</code></pre>

<p>Note that the call to obtain the number of samples will call forcibly the flush of the pipeline and wait for the query to finish.
If you need a more asynchronous approach you can query wether the occlusion query is done or not by using:</p>

<pre><code>    GLuint query_done = 0;
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT_AVAILABLE, &amp;query_done);
    if (query_done != 0)
        // Your query result is ready
    else
        // Maybe check the next frame?
</code></pre>

CC BY-SA 3.0
2015-08-06T19:04:26.033Z
2015-08-07T09:06:45.063Z
2015-08-07T09:06:45.063Z
Matteo Bertello
<p>I have an OpenGL application which uses stencil tests quite extensively to render irregular shapes (a bit like a simple 2-D <a href="https://en.wikipedia.org/wiki/Constructive_solid_geometry">CSG</a>). If I could find out how many fragments passed the stencil test and were actually rendered, this would be very helpful in simplifying some computations down the line. Specifically, it would allow me to determine the area of the rendered shape for free instead of having to approximate it with a Monte Carlo simulation later on.</p>

<p>I know that there is a similar concept for primitives emitted from the geometry shader, called <a href="https://www.opengl.org/wiki/Transform_Feedback">transform feedback</a>. I'd like to know if a similar concept exists for fragments and the stencil test.</p>

CC BY-SA 3.0
2015-12-03T09:02:28.797Z
@Llamageddon To be honest, I had this actual problem maybe two years ago or so and just dug it up from a past CG projects to come up with decent questions during the private beta. I haven't yet revisited said project, so I didn't get around to trying out the answer.
Martin Ender
CC BY-SA 3.0
2015-08-04T18:28:55.233Z
A crude solution would be to just paint one contrasting color onto another through the stencil, save that buffer out, and count the number of pixels that were altered.
TheBuzzSaw
CC BY-SA 3.0
2015-08-04T18:33:09.697Z
Hmm, the specification says *occulsion queries* count the number of fragments that pass the *depth test*, but off the top of my head I'm not sure how that interacts with the stencil test right now.
Christian Rau
CC BY-SA 3.0
2015-08-04T22:54:39.427Z
@ChristianRau It seems that only the fragments that pass the depth tests will be counted, but stencil, discard and alpha tests are ignored.
Maurice
CC BY-SA 3.0
2015-08-05T06:19:36.760Z
@ChristianRau and Maurice, the original [ARB_occlusion_query](https://www.opengl.org/registry/specs/ARB/occlusion_query.txt) spec explicitly says it counts samples passing both depth *and* stencil tests, though. See also [this StackOverflow question](https://stackoverflow.com/questions/26410637/occlusion-queries-with-stencil-test-only).
Nathan Reed
CC BY-SA 3.0
2015-08-05T14:00:55.260Z
@NathanReed Sounds like you're about to write an answer.
Christian Rau
<opengl><stencil-test>
Is it possible to find out how many fragments made it through the stencil test?
Martin Ender
# Is it possible to find out how many fragments made it through the stencil test?

(Asked by: username_0 on 2015-08-04)

I have an OpenGL application which uses stencil tests quite extensively to render irregular shapes (a bit like a simple 2-D [CSG](https://en.wikipedia.org/wiki/Constructive_solid_geometry)). If I could find out how many fragments passed the stencil test and were actually rendered, this would be very helpful in simplifying some computations down the line. Specifically, it would allow me to determine the area of the rendered shape for free instead of having to approximate it with a Monte Carlo simulation later on.

I know that there is a similar concept for primitives emitted from the geometry shader, called [transform feedback](https://www.opengl.org/wiki/Transform_Feedback). I'd like to know if a similar concept exists for fragments and the stencil test.

**Tags:** opengl, stencil-test

> **Comments:**
> **username_1**: A crude solution would be to just paint one contrasting color onto another through the stencil, save that buffer out, and count the number of pixels that were altered.  
> **username_2**: Hmm, the specification says *occulsion queries* count the number of fragments that pass the *depth test*, but off the top of my head I'm not sure how that interacts with the stencil test right now.  
> **username_3**: @username_2 It seems that only the fragments that pass the depth tests will be counted, but stencil, discard and alpha tests are ignored.  
> **username_4**: @username_2 and username_3, the original [ARB_occlusion_query](https://www.opengl.org/registry/specs/ARB/occlusion_query.txt) spec explicitly says it counts samples passing both depth *and* stencil tests, though. See also [this StackOverflow question](https://stackoverflow.com/questions/26410637/occlusion-queries-with-stencil-test-only).  
> **username_2**: @username_4 Sounds like you're about to write an answer.  
> **username_0**: @Llamageddon To be honest, I had this actual problem maybe two years ago or so and just dug it up from a past CG projects to come up with decent questions during the private beta. I haven't yet revisited said project, so I didn't get around to trying out the answer.  

---

## 2 answers

### Answer by username_6 on 2015-08-06. Score: 10 | Accepted answer

One possible approach could be the use of Hardware Occlusion Query.

You can use the facts that, by specification, the Stencil Test is executed before the depth test, and only the fragments that pass the depth test are counted by the Occlusion Query.

A simple example (not tested) would be like:

```
    GLuint samples_query = 0;
    GLuint samples_passed = 0;
    glGenQueries(1, &samples_query);
    // Initialize your buffers and textures ...
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_STENCIL_TEST);

    // Set up the values on the stencil buffer ...

    // Now we count the fragments that pass the stencil test
    glDepthFunc(GL_ALWAYS); // Set up the depth test to always pass
    glBeginQuery(GL_SAMPLES_PASSED, samples_query);
    // Render your meshes here
    glEndQuery(GL_SAMPLES_PASSED);
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT, &samples_passed);
    // samples_passed holds the number of fragments that passed the stencil test (if any)

    // Release your resources ...
    glDeleteQueries(1, &samples_query);

```

Note that the call to obtain the number of samples will call forcibly the flush of the pipeline and wait for the query to finish.
If you need a more asynchronous approach you can query wether the occlusion query is done or not by using:

```
    GLuint query_done = 0;
    glGetQueryObjectuiv(samples_query, GL_QUERY_RESULT_AVAILABLE, &query_done);
    if (query_done != 0)
        // Your query result is ready
    else
        // Maybe check the next frame?

```


---

### Answer by username_5 on 2015-08-05. Score: 2

If what you are interested in is the area, you could downsize the stencil buffer until you reach one pixel and deduce that area from its color.

Steps would be:

* Copy the stencil to a texture, using a format with enough precision.
* Load a shader that outputs a color proportional to the number of texels with a given color.
* Ping-pong between to framebuffers to reduce the size by half until reaching one pixel.
* The color of the pixel is the percentage of the viewport covered by the area: just multiply it by the area of the viewport.


---

