【问题标题】:Creating OpenGL shaders in NativeActivity在 NativeActivity 中创建 OpenGL 着色器
【发布时间】:2012-01-14 06:19:17
【问题描述】:

我已经调整了本机活动 NDK 示例,以合并来自 hello-gl2 示例的 OpenGL 代码。我处理APP_CMD_INIT_WINDOW 消息,然后尝试创建着色器。着色器创建失败,我尝试通过 getShaderInfoiv 获取信息,但同样失败。

所以我的问题是 - 如何在纯原生 Android 应用程序中创建 OpenGL ES 2.0 着色器?

附:我知道如果您使用 Java GLSurfaceView 并且没有在正确的线程中创建它们,着色器创建可能会失败,但是查看本机活动示例,它似乎只有一个线程!

【问题讨论】:

  • 很抱歉这个可能没用的问题,但是您是否以某种方式启动了 EGL?我认为 OpenGL 引擎根本没有准备好接收您的请求(这可以解释 getShaderInfoiv 调用的静默失败)。万一,是否加载了 OGL 2.0 库?
  • 在没有原生 OpenGL 开发经验的情况下,我猜测以下原生活动示例会为您提供 OpenGL ES 1.0 上下文。在 hello-gl2 示例中,OpenGL ES 2.0 配置选择是在 Java 代码中完成的。
  • 是的,这也是我关心的问题。我可能会尝试将代码从 Java 移植到 C++。

标签: android native opengl-es-2.0 shader


【解决方案1】:

当然可以在原生 Android 应用程序中创建 OpenGL ES 2.0 着色器。关键是使用正确的 OpenGL ES 2.0 上下文。我在我的应用程序中做了类似的事情,即在本机部分初始化 EGL 上下文,然后仅在本机代码中创建(和使用)着色器。根据我设法做到的,我认为你想做的也是完全可能的。

由于我在 Java 代码中有一个入口点(没有使用 NativeAcvity 机制),我还必须将本机窗口句柄 (EGLNativeWindowType) 从 java 传递到 C++,以便在本机代码中创建 EGL 表面。但是,由于您只想修改 NativeActivity 示例,因此您可以使用 engine->app->window 在 NativeActivity main.c 示例中创建 EGL 表面。

好的,如何在本机代码中创建正确的 OpenGL ES 2.0 上下文?我刚刚对 NativeActivity 示例中的 main.c 文件进行了两次更改并检查了它是否有效。

首先,使用了以下 EGL 属性

const EGLint attribs[] = {
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //important 
EGL_BLUE_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_RED_SIZE, 8,
EGL_NONE
};

eglChooseConfig(display, attribs, &config, 1, &numConfigs);.

其次,稍后在创建上下文时使用

const EGLint attrib_list [] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};

context = eglCreateContext(display, config, NULL, attrib_list);

我保持其余代码不变。我打印了一些信息以确保正在使用 OpenGL ES 2.0:

I/native-activity(  955): Details: [Version: OpenGL ES 2.0 1403843], [Vendor: Qualcomm], [Renderer: Adreno 205], [Extensions: GL_AMD_compressed_3DC_texture GL_AMD_compressed_ATC_texture ... ]

希望对你有帮助!

【讨论】:

  • 谢谢 - 这听起来正是我正在寻找的。我回家后会检查的。
  • 这 2 项更改成功了。谢谢!
  • 很高兴能帮上忙!我只后悔我写答案太晚了,没有得到赏金;)
【解决方案2】:

我想知道你为什么决定使用完整的 Native 解决方案,通常你所做的只是保持“原生”只有你的“重组件”,例如渲染引擎、AI 引擎、物理引擎,然后你保留“设备层”直到 Java 部分。

这样,最大的优势就是便携。如果您在 NDK 中构建所有内容,那么如果您想将游戏/程序移至 Iphone,则必须重新发明轮子,而如果您将“核心”保留在 C 中,而将附加层保留在 Java 中,则只需重写问题的简单部分。

在这种解决方案中,我拥有丰富的经验,因为我的 3D 引擎 (PATRIA 3D) 是基于本机代码构建的,能够从 Android NDK 交叉移植到 Iphone Objective C(加上 Windows/Linux/Mac OSx)。归根结底,我的代码是完全兼容的 C89 + OpenGL2.0,能够在 Android(使用 android ndk-build)和 Iphone (XCODE) 上直接编译(稍作改动)。

按照这种方式,引擎和执行实际绘图的线程在同一个线程上,让我称之为主线程。

如果您的应用程序中需要多线程:

A - 将绘图保持在主要的(主要)上 B - 在 Java 中创建新线程,不要在 C 中这样做(当您移植到其他平台时,您会在新层上构建多线程)

关于着色器,这种方式的解决方案非常简单,因为 OpenGL 的表面和初始化是由 Java 使用标准 EGL 库执行的。

相信我,如果您可以编写一次并在 Android 和 Iphone 这两个平台上使用,那么您的“客户”数量就会翻倍,这是您不能忽视的事情,它可能会使您的收入翻倍。

我希望这在某种程度上有所帮助。

【讨论】:

  • 这似乎是一个非常好的帖子,但我没有得到线程部分如果我使用可以使用多线程的 c++11,可以使用完整的原生解决方案?因为我用的是带有java接口的c++个人引擎(我把所有的纹理都放在了Java中),不整洁。
猜你喜欢
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 2018-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多