Android initialise openGL2.0 context with EGL

后端 未结 1 1668
滥情空心
滥情空心 2021-02-08 04:25

I want to do off-screen image processing on Android in native code, so I need create the openGL context in native code by EGL.

By EGL, we can create EGLSurface, I can se

相关标签:
1条回答
  • 2021-02-08 05:23

    You are trying to use EGL options that just don't work on Android and pbuffers only work on some GPUs - not Nvidia Tegra. pi32ConfigAttribs[] should look like this regardless of whether it will be on-screen or off-screen:

    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 is very inflexible in how they support off-screen EGLSurfaces. They defined their own pixmap type named EGL_NATIVE_BUFFER_ANDROID.

    To create an EGL surface that is off-screen on Android, construct a SurfaceTexture and pass that to eglCreateWindowSurface(). You should also look at using the EGL Image Extension and EGL_NATIVE_BUFFER_ANDROID, as discussed here:

    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: Here is some sample code that creates an off-screen surface:

    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);
    }
    
    0 讨论(0)
提交回复
热议问题