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

2024-01-04

我想在Android上用本机代码进行离屏图像处理,所以我需要通过EGL在本机代码中创建openGL上下文。

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

第一个用于屏幕上处理,第二个用于屏幕外处理,所以我像这样使用 EGL_PIXMAP_BIT :

// 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);

代码在第5步失败,Android好像不支持离屏处理?不支持 EGL_PIXMAP_BIT 类型。!


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

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 在如何支持离屏 EGLSurface 方面非常不灵活。他们定义了自己的像素图类型,名为EGL_NATIVE_BUFFER_ANDROID.

要在 Android 上创建离屏的 EGL 表面,请构造一个SurfaceTexture并将其传递给eglCreateWindowSurface()。您还应该考虑使用 EGL 图像扩展和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/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 http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1

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

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);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android使用EGL初始化openGL2.0上下文 的相关文章

随机推荐

  • RXJS 等待数组中的所有可观察值完成(或错误)

    我正在将可观察量推入这样的数组中 var tasks tasks push Observable timer 1000 tasks push Observable timer 3000 tasks push Observable timer
  • 为什么 Main 方法是私有的?

    新的控制台项目模板创建一个如下所示的 Main 方法 class Program static void Main string args 为什么两者都不是Main方法也不Program类需要公开吗 程序的入口点标记为 entrypoint
  • 如何在 R-Markdown 中的 R Chunk 中使用 LaTeX 代码?

    我目前正在使用 rmarkdown 编写报告 因此我想在 r 代码块内创建部分 我发现在 cat 和 results asis 的帮助下这是可能的 我对这个解决方案的问题是 我的 R 代码结果和代码没有像往常一样正确显示 例如 title
  • 如何使用 htmlagilitypack 抓取 xml 文件

    我需要从中抓取 xml 文件http feeds feedburner com Torrentfreak http feeds feedburner com Torrentfreak其链接和描述 我使用了这段代码 var webGet ne
  • Ubuntu上使用curlftpfs的权限

    I use sudo curlftpfs o allow other alpha 1234 192 168 1 100 home alpha share 在 Ubuntu 12 04 中将 ftp 文件夹挂载为本地文件夹 然后我可以读取和编
  • 从列表中删除 NULL 元素[重复]

    这个问题在这里已经有答案了 mylist lt list NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 123 NULL 456 gt mylist 1 NULL 2 NULL 3 NU
  • Rails 3 控制器中需要 gem 失败并出现“持续缺失”

    我在其他线程中多次看到这个问题 但似乎没有一个答案适用 环境 轨道3 来自 jugend 的亚马逊 ecs gem 唯一的文件在这里 http github com jugend amazon ecs blob master lib ama
  • 如何测试浏览器是否支持

    如何测试当前浏览器是否支持手机浏览器使用设备摄像头拍照的功能 https addpipe com html media capture demo https addpipe com html media capture demo 在所有桌面
  • OSTYPE 在 shell 脚本中不可用

    目前我正在使用新的 Xubuntu trusty tahr 设置一个新系统 我对 shell 脚本不太熟悉 但我有一个需要 OSTYPE 环境变量来确定要做什么的脚本 如果我打电话echo OSTYPE在 xfce terminal 中我成
  • 读取 HTTP 请求标头,并修改 Apps 脚本 Web 应用程序的响应标头

    我可以修改 HTTP 响应标头以添加 cookie 和额外信息吗 另外 我在读取请求标头时遇到问题 您无法在部署为 Web 应用程序的 Apps 脚本应用程序中读取或设置 HTTP 标头 您只能分别读取查询字符串或 GET POST 的发布
  • 批处理文件 - 如何使用 for 循环批量更改所有特定变量

    以下代码接受批处理文件的所有命令行参数 就我而言 我有大约 30 个命令行参数 它们都是 1 2 或 3 的数字 我接受它们然后想将它们重新分配给其他字符 我想要每个var 如果是1 就改成 如果是2 就改成 如果是3 就改成 第一部分效果
  • PHP get_browser:如何识别 ie7 和 ie6?

    有没有办法使用 PHP 的 get browser 函数来区分 IE7 和 IE6 您可以这样做 browser get browser if browser gt browser IE browser gt majorver 6 echo
  • Android Studio 将目录标记为测试源根

    我在 build gradle 中做了一些操作来删除 androidTest java 包的绿色突出显示 我不知道如何把它找回来 IntelliJ 在上下文菜单中有一个 将目录标记为测试源根目录 选项 但我在 Android Studio
  • 使用 Python 3 将 Pig Latin 翻译成英语

    正如您将在下面的代码中看到的 我已经制作了一个将英语翻译成 Pig Latin 的程序 它遵循两个规则 如果单词以元音开头 则应附加 way 例如 apple 变为 appleway 如果单词以辅音序列开头 则该序列应移至末尾 以 a 为前
  • 重复上下动画 div

    我想要一个使用 jquery 重复上下移动的 div 换句话说 div 从某个位置的顶部开始 向下移动 然后向上移动并重复此过程 从上到下大约有 1 秒的时间间隔 再回到顶部大约有 1 秒的时间间隔 有slideUp和slideDown以及
  • 发送以 HTML 文件作为正文的电子邮件 (C#)

    如何使用 HTML 文件设置 MailMessage 的正文 只需设置邮件消息正文格式 http msdn microsoft com en us library system web mail mailmessage bodyformat
  • Scala 的“With”语句等效吗?

    也许是 Scala 学习者的闲思 但是 在我的修改中 我写了以下内容 n child size gt 0 n child filter isInstanceOf Text size 0 n 是 scala xml Node 但这并不重要 特
  • 对二维点数组进行排序以找出四个角

    您好 我有任何大小的二维点的集合 通过查找原点之间距离的最小值和最大值 我能够找出左上角和右下角点 但我无法找出顶部 右点和左下点 也许你可以使用cv approxPoly 找到二维点集的角点 然后您可以通过以下方式按您想要的任何顺序对点进
  • hibernate用于动态表创建

    我是一个 HIBERNATE 初学者 因为我需要创建其中包含动态字段的动态表 所以我选择使用 hibernate 据我了解 创建表需要一个类 其中包含类中定义的字段 如何根据具有所需字段的表动态生成类 我不确定我是否理解这个问题 标题是关于
  • Android使用EGL初始化openGL2.0上下文

    我想在Android上用本机代码进行离屏图像处理 所以我需要通过EGL在本机代码中创建openGL上下文 通过EGL 我们可以创建EGLSurface 我可以看到那里有三个选择 EGL WINDOW BIT EGL PIXMAP BIT E