0

I'm trying to use stencil test in my android opengl application.

The code is pretty usual. Smth like that:

gl.glStencilFunc(GL10.GL_ALWAYS, 1, 0xff);
gl.glStencilOp(GL10.GL_KEEP, GL10.GL_REPLACE, GL10.GL_REPLACE);

//...drawing a thing to stencil buffer

gl.glStencilFunc(GL10.GL_EQUAL, 1, 0xff); 
gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_KEEP);

//...drawing using stencil buffer bits

But somewhy when I draw to the stencil buffer it is being drawn several times in different places of the screen. I have no idea why. I only draw to the stencil once but it somehow... multiplies... . It's on Sony device. Then i took my chinese tab and ran the app there. I got another picture - it is drawn only once and at the right place, BUT the stencil buffer is being cleared up between the calls of onDrawFrame - despite I DON't DO IT. It's being cleared up by itself.

Any thoughts? Device problems possibly?

genpfault
  • 51,148
  • 11
  • 85
  • 139
T.Vert
  • 279
  • 2
  • 13

1 Answers1

0

BUT the stencil buffer is being cleared up between the calls of onDrawFrame - despite I DON't DO IT. It's being cleared up by itself.

That is valid behavior. The content of depth and stencil buffers do not necessarily survive between frames.

GLSurfaceView uses the EGL API under the hood, which serves as the OpenGL window system interface on Android (similar to WGL on Windows, CGL on Mac OS, EAGL on iOS). The function that is called under the hood at the end of a frame is eglSwapBuffers(). From its man page:

The contents of ancillary buffers are always undefined after calling eglSwapBuffers.

If you need stencil buffers that keep their content beyond frame boundaries, you'll have to use off screen rendering to FBOs.

As for the stencil buffer not working at all on some devices, it's impossible to tell if that could be a device problem, or a problem in your code. One thing to look out for is that you request a stencil buffer when creating the view/renderer.

For example, if you're using the default EGLConfigChooser, the call you make during setup of your GLSurfaceView could look like this:

setEGLConfigChooser(8, 8, 8, 8, 16, 8);

Note that this needs to be after setEGLContextClientVersion(), but before setRenderer(). The last argument is the requested size of the stencil buffer. Some devices will always give you a stencil buffer when you request a depth buffer, others will not unless you explicitly request stencil as shown above.

To reliably get the desired configuration across devices, you'll often end up implementing your own EGLConfigChooser. The default behavior might not be consistent across devices, and some of it doesn't make a whole lot of sense even if it's implemented according to EGL specs.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133