Buffer automático al utilizar OpenGL en Android
Estoy escribiendo una aplicación de OpenGL donde me gustaría específicamente dibujar marcos de forma incremental. Para ello, me gustaría desactivar el borrado automático de búfer que entiendo, es el comportamiento predeterminado de GLSurfaceView.Renderer.onDrawFrame (). ¿Puede alguien ayudarme por favor en cómo hacer esto? Necesito escribir la aplicación en Java, no usando SDK nativo.
Entiendo que podría hacer esto por:
- Cómo cargar recursos o activos en GLWallpaper service
- ¿Por qué estoy recibiendo "llamada a OpenGL ES API sin contexto actual"?
- ¿Por qué no hay un método onSurfaceDestroyed en GLSurfaceView.Renderer?
- GlDepthMask (GL_FALSE) trashes el búfer de cuadros en algunas GPUs
- Visualización del flujo de la cámara en un GLSurfaceView a través de SurfaceTexture
(1) setting EGL_SWAP_BEHAVIOR_PRESERVED_BIT bit for EGL_SURFACE_TYPE attribute while doing [eglChooseConfig][1](), and (2) setting EGL_SWAP_BEHAVIOR attribute to EGL_BUFFER_PRESERVED by calling [eglSurfaceAttrib][2] on the EGLSurface object
Sin embargo, deduzco del documento Khronos que:
"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."
Ahora, entiendo que podría acceder a EGL de dos maneras en mi aplicación de Android:
(1) use the Khronos API class [EGL10][3] in javax.microedition.khronos.egl package (EGL11 doesn't seem to be implemented yet) (2) use the Android API class [EGL14][4] in android.opengl package (similar to using class android.opengl.GLES20)
El problema con (1) es que la versión es <1.4 por lo que no es compatible con la funcionalidad que necesito. El problema con (2) es que mi aplicación simplemente se bloquea el momento en que llamo a cualquier método en EGL14, y no estoy seguro de cómo se supone que debo usarlo (no pude encontrar un solo ejemplo de programa / tutorial sobre cómo EGL14 es Se supone que se utiliza en una aplicación) . En particular, me gustaría aprender a obtener un contexto GL válido de EGL14: en el caso de EGL10, podría hacerlo llamando a javax.microedition.khronos.egl.EGLContext.getGL (). Sin embargo, no veo ningún método equivalente en la clase android.opengl.EGLContext. De hecho, todas las clases relacionadas con EGL en android.opengl excepto EGL14 parecen estar casi vacías.
Mi mejor apuesta era seguir la misma línea de razonamiento que en el caso de GLES20: llamar a los métodos sólo dentro de los métodos GLSurfaceView.Renderer: onDrawFrame (), onSurfaceCreated (), onSurfaceChanged (), ya que estos suministran GL válido (GL10) y EGL (EGLConfig) contextos como argumentos. Así que puse el siguiente código dentro 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!"); } ... }
Creo que no tendré que instanciar EGL14 antes de llamar a lo anterior ya que todos los métodos son estáticos. Sin embargo, la llamada a EGL14.eglGetDisplay () bloquea la aplicación.
Cualquier ayuda sería muy apreciada, gracias:)
- LibGDX - Shader trabajando en el escritorio pero no en Android
- ¿Cómo crear un bucle de actualización / dibujo apropiadamente con opengl android?
- Aplicar transformaciones de matriz a BoundingBox
- ¿El emulador de Android admite OpenGL ES 3.0?
- Ayúdame a configurar OpenGL para 2D
- Renderizar la representación de script es mucho más lento que el renderizado de OpenGL en Android
- ¿Por qué mi programa de shader openGL para puntos tiene anillos de artefactos?
- Android, texto / fuente se procesa como cuadrados
La versión EGL implementada puede ser superior a la interfaz que está utilizando. La versión real es devuelta por EGL10.eglInitialize (). Si es [1,4] o superior, puede pasar [EGL10.EGL_SURFACE_TYPE, EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT] al llamar a EGL10.eglChooseConfig (). Está bien usar la definición EGL14 de EGL_SWAP_BEHAVIOR_PRESERVED_BIT aquí – es sólo un int definido por la especificación EGL.
¿Cómo EGL14.eglGetDisplay () bloquea la aplicación. ¿Es lanzar una excepción que no está siendo atrapada? Puede que valga la pena archivar un error (con tantos detalles sobre lo que está haciendo y en qué dispositivo) en https://code.google.com/p/android/issues/list .
En lugar de usar EGL directamente, puede extender GLSurfaceView y llamar a setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
En init.
Esta configuración impide que el marco GLSurfaceView se vuelva a dibujar hasta que llame a requestRender (), que es más eficiente para esta aplicación de ejemplo.
Vea los documentos de Android 1 sobre cómo configurar GLES con Java.
Creación de un entorno OpenGL ES
Simplemente puede procesar la textura y luego dibujar esa textura a la pantalla.
Para construir sobre la solución de Jesse Hall:
import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; import android.opengl.EGL14;
Puede tener una clase interna en su subclase GLSurfaceView
que implementa un EGLConfigChooser:
private static class MyEGLConfigChooser implements GLSurfaceView.EGLConfigChooser { public EGLConfig chooseConfig (EGL10 egl, EGLDisplay display) { EGLConfig [] configs = new EGLConfig[1]; int [] num_config = new int[1]; int [] attrib_list = new int[] { EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, // ... + anything else you want ... EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT | EGL14.EGL_SWAP_BEHAVIOR_PRESERVED_BIT, EGL10.EGL_NONE, }; if (egl.eglChooseConfig(display, attrib_list, configs, configs.length, num_config) && num_config[0] > 0) { // We just pick the first here, but you could interrogate all return configs[0]; } return null; } }
En su constructor de la subclase GLSurfaceView
, agregue:
setEGLConfigChooser(new MyEGLConfigChooser());
Luego, en la implementación de su GLSurfaceView.Renderer
, siempre que cambie la superficie, puede establecer los atributos en él:
public void onSurfaceChanged(GL10 gl, int width, int height) { EGL14.eglSurfaceAttrib(EGL14.eglGetCurrentDisplay(), EGL14.getCurrentSurface(EGL14.EGL_DRAW), EGL14.EGL_SWAP_BEHAVIOR, EGL14.EGL_BUFFER_PRESERVED); }
- ¿La aplicación no es compatible con el dispositivo que utilizo para desarrollarlo?
- ¿Cómo puede mi aplicación Android comunicarse con un daemon nativo?