分享

【新提醒】Android OpenGL ES 总结

 Sundy工作室 2013-11-26
 本帖最后由 delight 于 2012-5-18 17:58 编辑

OpenGL es(Embeded  Systems)  的官方组织是http://www./  ,该组织关注于手持和移动平台上的动态媒体编著、播放所需的API,并致力于为这些API建立无限权费用的开放标准。


OpenGL|ES 是根据手持及移动平台的特点,对 OpenGL 3D 图形 API 标准进行裁剪定制而形成的,因此大多数 OpenGL 方面的知识都是可以借鉴的,因此保持对 OpenGL 官方组织的关注是非常有益的,OpenGL ARB 网站在 http://www.


OpenGL ES 是一个平台中立的图形库,在它能够工作之前,需要与一个实际的窗 口系统关联起来,这与 OpenGL是一样的。但不一样的是,这部份工作有标准, 这个标准就是 EGL 。而 OpenGL 时代在不同平台上有不同的机制以关联窗口系 统,在 Windows 上是 wgl,在X-Window 上是 xgl,在 Apple OS 上是 agl 等。 EGL 的工作方式和部份术语都接近于 xgl。


OpenGL  ES简化了模型描述,取消了通过在 glBegin/glEnd 之间使用大量glVertex之类的调用来逐点描述模型,统一到使用VertexArray。



  • 初始化EGL

OpenGL ES的初始化过程如下图所示:


Display → Config → Surface
                        ↑
                      Context
                        ↑
Application → OpenGL Command

  • 获取display()
  • 初始化EGL
  • 选择Config .      所谓Config实际指的是 FrameBuffer的参数。
  • 构造Surface
  • 创建Context

在 OpenGL  的编程接口中,Context 就代表这个状态机,程序的主要工作就是向 Context 提供图元、设置状态,偶尔也从 Context 里获取一些信息。


2.初始化GLES
  • 调用 eglInitialize() 初始化 egl 库
  • 用 eglChooseConfig() 选择合适的 framebuffer
  • 调用 eglCreateWindowSurface 创建 EGLSurface
  • 用 eglCreateContext 创建 RenderContext(RC)。


Android 将 大部分OpenGL   ES的工作都已经完成,对它进行了封装,提供了SurfaceView  ,Renderer,

等类供我们调用,接下来就来看看这些类的使用。


GLSurfaceView是一个视图,继承至SurfaceView,它内嵌的surface专门负责OpenGL渲染。

        GLSurfaceView提供了下列特性:

                1>管理一个surface,这个surface就是一块特殊的内存,能直接排版到android的视图view上。

                2>管理一个EGL display,它能让opengl把内容渲染到上述的surface上。

                3>用户自定义渲染器(render)。

                4>让渲染器在独立的线程里运作,和UI线程分离。

                5>支持按需渲染(on-demand)和连续渲染(continuous)。

                6>一些可选工具,如调试。


   3.SurfaceView的使用
  • 使用GLSurfaceView

        通常会继承GLSurfaceView,并重载一些和用户输入事件有关的方法。如果你不需要重载事件方法,GLSurfaceView也可以直接使用, 你可以使用set方法来为该类提供自定义的行为。例如,GLSurfaceView的渲染被委托给渲染器在独立的渲染线程里进行,这一点和普通视图不一 样,setRenderer(Renderer)设置渲染器。


初始化GLSurfaceView

        初始化过程其实仅需要你使用setRenderer(Renderer)设置一个渲染器(render)。当然,你也可以修改GLSurfaceView一些默认配置。

            *setDebugFlags(int)

            *setEGLConfigChooser(boolean)

            *setEGLConfigChooser(EGLConfigChooser)

            *setEGLConfigChooser(int, int, int, int, int, int)

            *setGLWrapper(GLWrapper)

定制android.view.Surface

        GLSurfaceView默认会创建像素格式为PixelFormat.RGB_565的surface。如果需要透明效果,调用getHolder().setFormat(PixelFormat.TRANSLUCENT)。透明(TRANSLUCENT)的surface的像 素格式都是32位,每个色彩单元都是8位深度,像素格式是设备相关的,这意味着它可能是ARGB、RGBA或其它。


  • 选择EGL配置

        Android设备往往支持多种EGL配置,可以使用不同数目的通道(channel),也可以指定每个通道具有不同数目的位(bits)深度。因此, 在渲染器工作之前就应该指定EGL的配置。GLSurfaceView默认EGL配置的像素格式为RGB_656,16位的深度缓存(depth buffer),默认不开启遮罩缓存(stencil buffer)。

        如果你要选择不同的EGL配置,请使用setEGLConfigChooser方法中的一种。


调试行为

        你可以调用调试方法setDebugFlags(int)或setGLWrapper(GLSurfaceView.GLWrapper)来自定义GLSurfaceView一些行为。在setRenderer方法之前或之后都可以调用调试方法,不过最好是在之前调用,这样它们能立即生效。


  • 设置渲染器

        总之,你必须调用setRenderer(GLSurfaceView.Renderer)来注册一个GLSurfaceView.Renderer渲染器。渲染器负责真正的GL渲染工作。


渲染模式

        渲染器设定之后,你可以使用setRenderMode(int)指定渲染模式是按需(ondemand)还是连续(continuous)。默认是连续渲染。


  • Activity生命周期

        Activity窗口暂停(pause)或恢复(resume)时,GLSurfaceView都会收到通知,此时它的onPause方法和 onResume方法应该被调用。这样做是为了让GLSurfaceView暂停或恢复它的渲染线程,以便它及时释放或重建OpenGL的资源。


  • 事件处理

        为了处理事件,一般都是继承GLSurfaceView类并重载它的事件方法。但是由于GLSurfaceView是多线程操作,所以需要一些特殊的处 理。由于渲染器在独立的渲染线程里,你应该使用Java的跨线程机制跟渲染器通讯。queueEvent(Runnable)方法就是一种相对简单的操 作,例如下面的例子。

         class MyGLSurfaceView extendsGLSurfaceView {

             private MyRenderermMyRenderer;

             public voidstart() {

                mMyRenderer = ...;

                setRenderer(mMyRenderer);

             }

             public booleanonKeyDown(int keyCode, KeyEvent event) {

                 if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {

                    queueEvent(new Runnable() {

                        // 这个方法会在渲染线程里被调用

                        public void run() {

                            mMyRenderer.handleDpadCenter();

                        }});

                    return true;

                 }

                return super.onKeyDown(keyCode, event);

             }

         }


        (注:如果在UI线程里调用渲染器的方法,很容易收到“call to OpenGL ES API with no current context”的警告,典型的误区就是在键盘或鼠标事件方法里直接调用opengl es的API,因为UI事件和渲染绘制在不同的线程里。更甚者,这种情况下调用glDeleteBuffers这种释放资源的方法,可能引起程序的崩溃, 因为UI线程想释放它,渲染线程却要使用它。)


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多