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

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.

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

http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1

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); } 
  • Plataforma C ligera y ligera (OpenGL)
  • Android: cómo averiguar la relación de aspecto exacta de píxeles de los dispositivos mediante programación?
  • Mezcla dos texturas con diferentes coordenadas y tamaños en el mismo sombreado
  • Cómo configurar / calcular texturebuffer en glTexCoordPointer al importar desde archivo OBJ
  • ¿Se admiten objetos Array Vertex de ES OpenGL en cualquier emulador de Android?
  • Memoria insuficiente al asignar memoria nativa
  • ¿Puedo hacer una aplicación C ++ bastante nativa con Android?
  • ¿Es posible realizar llamadas de OpenGL ES desde su código C ++ y Java?
  • Hoja de ruta para el desarrollo de Android
  • ¿Por qué no hay un método onSurfaceDestroyed en GLSurfaceView.Renderer?
  • Errores extraños al animar (Adreno, GL)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.