Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Automatic buffer clear while using OpenGL on Android

I'm writing a certain OpenGL application where I'd specifically like to draw frames incrementally. For this, I'd like to disable automatic clearing of buffer which I understand, is default behavior of GLSurfaceView.Renderer#onDrawFrame(). Can someone please help me on how to do this? I need to write the application in Java, not using native SDK.

I understand that I could possibly do this by :-

  1. setting EGL_SWAP_BEHAVIOR_PRESERVED_BIT bit for EGL_SURFACE_TYPE attribute while doing eglChooseConfig, and
  2. setting EGL_SWAP_BEHAVIOR attribute to EGL_BUFFER_PRESERVED by calling eglSurfaceAttrib on the EGLSurface object

However, I gather from the Khronos doc that:-

  • EGL_SWAP_BEHAVIOR_PRESERVED_BIT are supported only if the EGL version is 1.4 or greater.
  • EGL_SWAP_BEHAVIOR is supported only if the EGL version is 1.2 or greater.

Now, I understand that I could access EGL in two ways in my Android application:-

  1. use the Khronos API class EGL10 in javax.microedition.khronos.egl package (EGL11 doesn't seem to be implemented yet)
  2. use the Android API class EGL14 in android.opengl package (similar to using class android.opengl.GLES20)

The problem with (1) is that the version is < 1.4 so it doesn't support the functionality I need. The problem with (2) is that my application simply crashes the moment I call any method in EGL14, and I'm not sure how I'm supposed to use it (I could not find a single example program / tutorial on how EGL14 is supposed to be used in an app). In particular, I'd like to learn how to get a valid GL context from EGL14: in the case of EGL10, I could do that by calling javax.microedition.khronos.egl.EGLContext.getGL(). However, I see no equivalent method in class android.opengl.EGLContext. In fact, all EGL-related classes in android.opengl except EGL14 seem to be mostly empty.

My best bet was to follow the same line of reasoning as in case of GLES20: to call the methods only inside the GLSurfaceView.Renderer methods: onDrawFrame(), onSurfaceCreated(), onSurfaceChanged(), because these supply valid GL (GL10) and EGL (EGLConfig) contexts as arguments. So I put following code inside onDrawFrame():-

public void onDrawFrame(GL10 gl) {
    ...
    android.opengl.EGLDisplay d = null;
    if ( (d = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)) == EGL14.EGL_NO_DISPLAY) {
        Log.i("Triangle", "EGL14.eglGetDisplay() failed!");
    } else {
        Log.i("Triangle", "EGL14.eglGetDisplay() succeeded!");
    }
    ...
}

I believe I won't have to instantiate EGL14 before calling the above since all methods are static. However, the call to EGL14.eglGetDisplay() crashes the app.

Any help would be much appreciated, thanks:)

like image 659
Ankur Sakhuja Avatar asked Nov 12 '22 06:11

Ankur Sakhuja


1 Answers

Instead of using EGL directly, you could extend GLSurfaceView and call setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); on init.

This setting prevents the GLSurfaceView frame from being redrawn until you call requestRender(), which is more efficient for this sample app.

See the android docs 1 on how to setup GLES with Java.

Building an OpenGL ES Environment

like image 125
torbjoernwh Avatar answered Nov 14 '22 21:11

torbjoernwh