您的位置:华清远见教育科技集团 >> Android资料 >> Android OpenGL ES渲染方式  
 
Android OpenGL ES渲染方式
分享到:

2007年3月,Khronos完成了OpenGL ES 2.0规范的制定,OpenGL ES 2.0显著增强了各种移动设备的功能、灵活性及视觉体验。OpenGL ES 2.0设备将会包含两款驱动,分别支持OpenGL ES 2.0及OpenGL ES 1.1。在Android中,目前软件渲染仅支持OpenGL ES 1.1。如果底层芯片支持硬件渲染,则可以利用OpenGL ES 2.0来进行硬件渲染。

2010年3月,Goolge推出的Android NDK r3提供了对于OpenGL ES 2.0直接调用的功能,这将更加有利于提高Android图像处理的能力。

新的NDK版本为Android NDK r5b。允许开发者直接接入事件、音频、图像、窗口管理、断言、存储等。通过NativeActivity还可以管理应用程序的生命周期,进一步增强了原生代码开发的能力。

在Android中,Open GL ES的实现被封装在android.opengl中,主要的接口包括GLSurfaceView.EGLConfigChooser、GLSurfaceView.EGLContextFactory、GLSurfaceView.EGL WindowSurfaceFactory、GLSurfaceView.GLWrapper、GLSurfaceView.Renderer等。

主要的类包括GLDebugHelper(调试OpenGL ES 应用的助手函数)、GLES10(OpenGL ES 1.0)、GLES10Ext(OpenGL ES 1.0扩展)、GLES11(OpenGL ES 1.0)、GLES11Ext(OpenGL ES 1.1扩展)、GLSurfaceView(专用于OpenGL ES渲染的视图)、GLU(OpenGL ES的工具包)、GLUtils(桥接OpenGL ES和Android API的工具类)、Matrix(矩阵)、Visibility(一个计算三角形网格能见度的工具集)等。

OpenGL ES的原生方法接口的定义主要位于frameworks\base\core\jni目录下,分布在android_opengl_GLES10.cpp、android_opengl_GLES10Ext.cpp、android_opengl_GLES11.cpp、android_opengl_GLES11Ext.cpp等。

由于3D和2D的渲染机制有所不同,所以Android通过对SurfaceView的继承,创立了专用于3D渲染的GLSurfaceView。GLSurfaceView调用自定义的渲染器可以在特定的Surface上进行OpenGL ES的渲染,同时GLSurfaceView还实现了SurfaceHolder.Callback接口,可以监听到Surface状态变化的消息。下图显示了GLSurfaceView的类图。


GLSurfaceView的类图

GLSurfaceView提供了如下的能力:

第一,GLSurfaceView管理着一个特定的Surface,可以将OpenGL ES整合进Android的视图系统。

第二,GLSurfaceView管理着一个EGL显示(EGL Display),这使得OpenGL可以被渲染到Surface中。

第三,GLSurfaceView可以利用用户定义的渲染器(Renderer)对象来执行渲染。

第四,在GLSurfaceView中,为了提供渲染的性能,渲染工作会放在专有的线程中进行,与UI线程是分离的。

第五,在GLSurfaceView中,渲染模式可以分为两种:持续渲染模式(Continuous Rendering Mode)和需求渲染模式(On-demand Rendering Mode)。

第六,在GLSurfaceView中,提供了包装、跟踪、检错机制,方便OpenGL调用调试。

需要注意的是,由于渲染需要依赖于用户提供的渲染器进行,在进行初始化一个GLSurfaceView对象时,必须调用GLSurfaceView::setRenderer()方法来设置所用的渲染器。在设置渲染器前,用户可以根据自己的需求设置调试标志位、配置信息、包装器等。

下面是调用GLSurfaceView的一个实现过程:

mGLView=new GLSurfaceView(this);
    mGLView.setEGLConfigChooser(false);
    mGLView.setRenderer(new StaticTriangleRenderer(this));
    setContentView(mGLView);

在目前的实现中,Android已经提供了TriangleRenderer(三角板)、CubeRenderer(一对滚动的立方)、StaticTriangleRenderer(静态三角)、SpriteTextRenderer(文字精灵)、KubeRenderer、ClearRenderer、DemoRenderer等自定义渲染器的实例。

这里需要说明的是,为了实现自定义的渲染器,必须实现GLSurfaceView.Renderer:: onSurfaceCreated()、GLSurfaceView.Renderer:: onSurfaceChanged()、GLSurfaceView.Renderer:: onDrawFrame()等3个方法。

下面以CubeRenderer为例来说明这一过程:

代码:自定义渲染器的一般过程

public class CubeRenderer implements GLSurfaceView.Renderer {
    public CubeRenderer(boolean useTranslucentBackground) {
      mTranslucentBackground=useTranslucentBackground;
      mCube=new Cube();    //构建立方体对象
        }
    public void onDrawFrame(GL10 gl) {
      gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);//清空屏幕
    //设置矩阵模式为视图矩阵,其他两种模式为投影矩阵、纹理矩阵,该方法需和gl.glLoadIdentity()配合使用。
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();    //重置当前指定的矩阵为单位矩阵
    gl.glTranslatef(0, 0, -3.0f);    //设置渲染的起始坐标
    gl.glRotatef(mAngle, 0, 1, 0);    //进行旋转
    gl.glRotatef(mAngle*0.25f, 1, 0, 0);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);    // 激活选择的数组
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
    mCube.draw(gl);    //执行渲染
    gl.glRotatef(mAngle*2.0f, 0, 1, 1);
    gl.glTranslatef(0.5f, 0.5f, 0.5f);
    mCube.draw(gl);
    mAngle +=1.2f;
    }
    public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
    float ratio=(float) width/height;
    gl.glMatrixMode(GL10.GL_PROJECTION);    //设置矩阵模式为投影矩阵
    gl.glLoadIdentity();
    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); //创建投影矩阵
    }
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    gl.glDisable(GL10.GL_DITHER);
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
    if (mTranslucentBackground) {
        gl.glClearColor(0,0,0,0);
    }else{
        gl.glClearColor(1,1,1,1);
    }
    gl.glEnable(GL10.GL_CULL_FACE) ;
    //设置着色模型为平滑着色,另一种模式为平面着色
    gl.glShadeModel(GL10.GL_SMOOTH);
    gl.glEnable(GL10.GL_DEPTH_TEST);
      }
    private boolean mTranslucentBackground;
    private Cube mCube;
    private float mAngle;
    }

在自定义渲染器时,需要注意gl.glMatrixMode()方法和gl.glLoadIdentity()方法必须配合使用,前者设置矩阵模式为视图矩阵、投影矩阵、纹理矩阵中的一种,后者重置当前指定的矩阵为单位矩阵。

另外在设置着色模型时,需根据自身的需求设置着色模型是平滑着色还是平面着色。

 更多相关文章

·Android Skia UI控件架构
·Android Skia图形渲染
·Android Skia 渲染概述
·Android Surface渲染管理
·Android LayerBuffer模式的layer渲染