OpenGL 4.4 和 Android

移动开发 Android
手机硬件的更新是如此迅速以至于我们开始进入一个手机与高端PC功能无异的时代。它们的区别将只是芯片的功耗不同而已。

手机硬件的更新是如此迅速以至于我们开始进入一个手机与高端PC功能无异的时代。它们的区别将只是芯片的功耗不同而已。

我不想让自己听起来像是在推广我们自己的芯片,但我相信Tegra K1是未来即将发生的事物的前瞻。不仅仅发生在我们身上,我希望其他行业也能加入进来,从而使开发者可以为从PC到手机安全地假设一个相对统一的功能集。K1只是***示例,因为它的GPU核心是Kepler 。而且它不是什么营销手段,它实际上是与运转像GTX780这种神奇事物相同的微架构。几年的血汗与泪水使其成为了可能。并且限于尺寸,功率和热限制,它 只有192个核心(而不是2304个),但它仍具有较强的性能竞争力。更重要的是在功能上它处于一个完全不同的阵营中,因为它支持完整的桌面级 OpenGL4.4,包括几何着色器,镶嵌,计算等,还有像bindless这样的支持其他事物的扩展。

但是Android只支持OpenGL ES,对吗?实际上不是这样的。虽然现在在Android平台上,***的官方支持的图形API是OpenGL ES,你仍然可以使用EGL在平台上创建一个"大"OpenGL 上下文,前提是你的设备支持它。这使得在不同的操作系统上传输数据很实用,Windows/Linux/Mac/streamOS 都有OpenGL的后台程序,可以快速启动并模拟裁剪平面(clip planes),alpha测试,或者spec中的少数差异。它同样可以作为一个不错的引用渲染后端程序,在ES渲染路径启动和运行之前验证你的端口。

不要担心,你可以在你的app中同时使用GLES和BigGL。实际上,这很简单。最重要的事情在EGL中,它是Android为创建OpenGL上下文而公开的API。Java或C/C++同样可以这样做,但是要注意需要EGL_SPEC.1.4以上版本。

首先,在创建上下文(或者调用任何一个EGL函数)之前,要知道哪个版本的GL最支持当前设备。可以通过简单地调用eglBindAPI(EGL_OPENGL_API)来完成。该API会将EGL切换到桌面OpenGL模式,如果当前设备不支持,则返回EGL_TRUE或者留下未改变的状态并返回EGL_FALSE。鉴于该函数可以切换全局状态,所以最安全的做法是让EGL首先调用它,之后不再调用。

创建完上下文之后,如果eglBindAPI()函数没有切换BigGL模式,你就要和你之前那样创建你的ES上下文。如果切换成功,你可选择性地 创建BigGL上下文。幸运的是,EGL让它简单化。因为我们已经调用了eglBindAPI(EGL_OPENGL_API),EGL已经设置为 BigGL模式,所以我们只需要在配置文件和上下文中调整一些属性即可。

首先,在传递给eglChooseConfig()的配置属性中,我们需要确保 EGL_RENDERABLE_TYPE 设置为 EGL_OPENGL_BIT ,而不是EGL_OPENGL_ES2_BIT.

其次, 传递给函数  eglCreateContext() 的属性也需要稍微调整。对于 ES上下文,通常把 EGL_CONTEXT_CLIENT_VERSION 设为 1, 2 或3, 这取决于你想搭建哪个版本的OpenGL ES.对于BigGL上下文,我们不使用这个属性,所以不要设置。事实上,你可以直接把BigGL的属性列表置空。

粗略地讲,这比较像下面的样本 (为简洁起见,忽视错误检查):

 

  1. if(eglBindAPI(EGL_OPENGL_API)) 
  2.   // Create a BigGL context... 
  3.   EGLDisplay display = eglGetDisplay(...); 
  4.   eglInitialize(display, ...); 
  5.   const EGLint configAttrs[] = 
  6.   { 
  7.     EGL_SURFACE_TYPE,    EGL_WINDOW_BIT, 
  8.     EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, 
  9.     // backbuffer attributes here... 
  10.     EGL_NONE 
  11.   }; 
  12.   EGLConfig config; 
  13.   EGLint    numConfigs = 0
  14.   eglChooseConfig(display, configAttrs, &config, 1, &numConfigs); 
  15.   EGLint ctxAttrs[] = 
  16.   { 
  17.     EGL_NONE 
  18.   }; 
  19.   eglCreateContext(display, config, EGL_NO_CONTEXT, ctxAttrs); 
  20. else 
  21.   // TODO: Fallback to old ES context creation... 

***一点问题,也是我对于使用OpenGL或者OpenGL ES的开发人员的一些建议,不论他们基于怎样的平台进行开发。尤其重要的一点是像上面提到的那样在API之间进行切换。并且,不要隐式地链接到GL符号!就算是再多的功能,你都应当使用eglGetProcAddress(), 并且当心不要在上下文中共享函数指针。如果你做了一下比较疯狂的事情,比如在同一个应用中创建了一个BigGL上下文和一个ES上下文,或者创建了像 glDrawElement()这样的函数,在两者的API中都存在,但是可能指向了完全不同的实现方法。这就意味着你应当仅链接到libEGL,所以需 要通过qglGetProcAddress()函数查询所有的符号。

编辑:应当指出的是,从技术的角度讲,通过eglGetProcAddress()可获得的“EGL_KHR_get_all_proc_addresses”应当是目前的核心功能,但是我坚信,既然目前它在Android通用EGL接口上进行了实现,也就意味着它可以单独驱动,这可能在旧版本的Android上无法正常工作。但是如果你正在考虑支持BigGL,你可能不希望旧设备成为你道路上的绊脚石。

特别强调:我强烈建议如果可能的话,任何正在开发的应用程序应该也有GLES渲染路径。BigGL对于开发是实用的,对于一些边缘特性,甚至会更实用,但是有GLES后端同样会帮助Android避免分段存储,并且帮助你的应用更多的曝光在尽可能多的用户面前。

英文原文:OpenGL 4.4 and beyond on Android

 译文链接:http://www.oschina.net/translate/opengl-44-and-beyond-on-android

责任编辑:chenqingxiang 来源: oschina
相关推荐

2013-10-29 16:50:50

Android 4.4特性

2013-09-04 10:15:22

Android开发

2013-11-28 15:03:56

Android4.4ART模式省电原理

2013-11-04 17:28:44

Android

2014-04-29 14:16:54

2013-09-22 15:51:32

Android 4.4

2013-12-02 10:33:36

Android 4.4Nexus One

2013-10-16 09:58:52

Nexus 5Android4.4

2014-04-29 14:49:37

OpenGL ES 2Android应用投影

2013-09-25 10:52:27

Android 4.4扁平化

2013-10-29 16:36:22

Android 4.4功能

2013-11-26 13:47:31

GoogleAndroid 4.4

2013-09-05 10:42:46

诺基亚三星Android 4.4

2013-11-22 14:10:46

2013-11-28 13:53:08

Android4.4ART运行模式

2013-10-10 09:23:15

Android 4.4Kitkat

2013-11-04 09:25:08

Android 4.4设备

2013-11-28 13:47:37

Android4.4ART模式

2014-04-29 14:08:40

OpenGL ESAndroid应用投影

2013-11-14 10:34:57

Android 4.4特性
点赞
收藏

51CTO技术栈公众号