Android inicializa el contexto openGL2.0 con EGL
Quiero hacer el procesamiento de imágenes fuera de pantalla en Android en código nativo, por lo que necesito crear el contexto openGL en código nativo de EGL.
Por EGL, podemos crear EGLSurface, puedo ver que hay tres opciones allí: * EGL_WINDOW_BIT * EGL_PIXMAP_BIT * EGL_BUFFER_BIT
- NVidia PerfHUD ES Tegra en Google Nexus 7
- Android SIGSEGV al dibujar ruta mediante aceleración de hardware
- Opengl fondo transparente y Vista previa de cámara no les gusta texturing
- Escribir una aplicación Java portátil utilizando JOGL y Android OpenGL
- DrawerLayout ListView no dibujado con GLSurfaceVer como contenido
El primero es para el procesamiento en pantalla, el segundo es para fuera de pantalla, así que utilizo EGL_PIXMAP_BIT como este:
// Step 1 - Get the default display. EGLDisplay eglDisplay = eglGetDisplay((EGLNativeDisplayType) 0); if ((eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY)) == EGL_NO_DISPLAY) { LOGH("eglGetDisplay() returned error %d", eglGetError()); exit(-1); } // Step 2 - Initialize EGL. if (!eglInitialize(eglDisplay, 0, 0)) { LOGH("eglInitialize() returned error %d", eglGetError()); exit(-1); } // Step 3 - Make OpenGL ES the current API. eglBindAPI(EGL_OPENGL_ES_API); // Step 4 - Specify the required configuration attributes. EGLint pi32ConfigAttribs[] = { EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE }; // Step 5 - Find a config that matches all requirements. int iConfigs; EGLConfig eglConfig; eglChooseConfig(eglDisplay, pi32ConfigAttribs, &eglConfig, 1, &iConfigs); if (iConfigs != 1) { LOGH( "Error: eglChooseConfig(): config not found %d - %d.\n", eglGetError(), iConfigs); exit(-1); } // Step 6 - Create a surface to draw to. EGLSurface eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, NULL); // Step 7 - Create a context. EGLContext eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, ai32ContextAttribs); // Step 8 - Bind the context to the current thread eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
El código falló en el paso 5, parece Android no es compatible con el procesamiento fuera de pantalla? No se admite el tipo EGL_PIXMAP_BIT.
- OpenGL ES 3.0. Textura de punto flotante
- Grabación de vídeo en pantalla de Android
- Decodificación y reproducción de vídeo en Android
- No se puede encontrar el ejemplo adecuado para la clase de sprite de OpenGL 2d que no usa GL11Ext para dibujar
- EglCreateWindowSurface falla con java.lang.IllegalArgumentException
- Matriz int a la textura opengl en android
- Cómo crear una textura OpenGL de matriz de bytes en Android
- EGLImages con renderbuffer como hermano de origen y textura como hermano objetivo
Estás intentando usar opciones de EGL que simplemente no funcionan en Android y los pbuffers sólo funcionan en algunas GPUs – no en Nvidia Tegra. pi32ConfigAttribs[]
debería verse así independientemente de si estará en la pantalla o fuera de la pantalla:
EGLint pi32ConfigAttribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_NONE };
Android es muy inflexible en cómo soportan EGLSurfaces fuera de pantalla. Ellos definieron su propio tipo de EGL_NATIVE_BUFFER_ANDROID
llamado EGL_NATIVE_BUFFER_ANDROID
.
Para crear una superficie EGL que esté fuera de pantalla en Android, construya una SurfaceTexture
y pase a eglCreateWindowSurface()
. También debe ver el uso de EGL Extensión de imagen y EGL_NATIVE_BUFFER_ANDROID
, como se explica aquí:
http://software.intel.com/en-us/articles/using-opengl-es-to-accelerate-apps-with-legacy-2d-guis
UPDATE: He aquí un ejemplo de código que crea una superficie fuera de la pantalla:
private EGL10 mEgl; private EGLConfig[] maEGLconfigs; private EGLDisplay mEglDisplay = null; private EGLContext mEglContext = null; private EGLSurface mEglSurface = null; private EGLSurface[] maEglSurfaces = new EGLSurface[MAX_SURFACES]; @Override public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) { InitializeEGL(); CreateSurfaceEGL(surfaceTexture, width, height); } private void InitializeEGL() { mEgl = (EGL10)EGLContext.getEGL(); mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); if (mEglDisplay == EGL10.EGL_NO_DISPLAY) throw new RuntimeException("Error: eglGetDisplay() Failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); int[] version = new int[2]; if (!mEgl.eglInitialize(mEglDisplay, version)) throw new RuntimeException("Error: eglInitialize() Failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); maEGLconfigs = new EGLConfig[1]; int[] configsCount = new int[1]; int[] configSpec = new int[] { EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, EGL10.EGL_BLUE_SIZE, 8, EGL10.EGL_ALPHA_SIZE, 8, EGL10.EGL_DEPTH_SIZE, 0, EGL10.EGL_STENCIL_SIZE, 0, EGL10.EGL_NONE }; if ((!mEgl.eglChooseConfig(mEglDisplay, configSpec, maEGLconfigs, 1, configsCount)) || (configsCount[0] == 0)) throw new IllegalArgumentException("Error: eglChooseConfig() Failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); if (maEGLconfigs[0] == null) throw new RuntimeException("Error: eglConfig() not Initialized"); int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; mEglContext = mEgl.eglCreateContext(mEglDisplay, maEGLconfigs[0], EGL10.EGL_NO_CONTEXT, attrib_list); } private void CreateSurfaceEGL(SurfaceTexture surfaceTexture, int width, int height) { surfaceTexture.setDefaultBufferSize(width, height); mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, maEGLconfigs[0], surfaceTexture, null); if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) { int error = mEgl.eglGetError(); if (error == EGL10.EGL_BAD_NATIVE_WINDOW) { Log.e(LOG_TAG, "Error: createWindowSurface() Returned EGL_BAD_NATIVE_WINDOW."); return; } throw new RuntimeException("Error: createWindowSurface() Failed " + GLUtils.getEGLErrorString(error)); } if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) throw new RuntimeException("Error: eglMakeCurrent() Failed " + GLUtils.getEGLErrorString(mEgl.eglGetError())); int[] widthResult = new int[1]; int[] heightResult = new int[1]; mEgl.eglQuerySurface(mEglDisplay, mEglSurface, EGL10.EGL_WIDTH, widthResult); mEgl.eglQuerySurface(mEglDisplay, mEglSurface, EGL10.EGL_HEIGHT, heightResult); Log.i(LOG_TAG, "EGL Surface Dimensions:" + widthResult[0] + " " + heightResult[0]); } private void DeleteSurfaceEGL(EGLSurface eglSurface) { if (eglSurface != EGL10.EGL_NO_SURFACE) mEgl.eglDestroySurface(mEglDisplay, eglSurface); }
- ¿Cómo evitar el parpadeo mientras se actualiza gridview?
- ¿Cómo enviar medios desde el servidor a la aplicación Android?