首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android使用EGL初始化openGL2.0上下文

Android使用EGL初始化openGL2.0上下文
EN

Stack Overflow用户
提问于 2013-08-30 17:05:37
回答 1查看 11.5K关注 0票数 11

我想在Android上使用原生代码进行屏幕外的图像处理,所以我需要使用EGL在原生代码中创建openGL上下文。

通过EGL,我们可以创建EGLSurface,我可以看到有三个选择:* EGL_WINDOW_BIT * EGL_PIXMAP_BIT * EGL_BUFFER_BIT

第一个用于屏幕上的处理,第二个用于屏幕外的处理,所以我使用EGL_PIXMAP_BIT如下:

代码语言:javascript
复制
// 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);

代码在第五步失败了,看起来Android不支持屏下处理?不支持EGL_PIXMAP_BIT类型。!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-31 00:16:12

您正在尝试使用EGL选项,这些选项在Android上不起作用,而pbuffer只在某些GPU上起作用-而不是Nvidia Tegra。无论是在屏幕上还是在屏幕外,pi32ConfigAttribs[]都应该是这样的:

代码语言:javascript
复制
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在支持屏幕外EGLSurfaces的方式上非常不灵活。他们定义了自己的名为EGL_NATIVE_BUFFER_ANDROID的像素映射类型。

要在Android上创建一个屏幕外的EGL图面,需要构造一个SurfaceTexture并将其传递给eglCreateWindowSurface()。您还应该考虑使用EGL Image扩展和EGL_NATIVE_BUFFER_ANDROID,如下所述:

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

更新:下面是一些创建离屏界面的示例代码:

代码语言:javascript
复制
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);
}
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18529021

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档