一、简介
GLSurfaceView继承SurfaceView,并实现了SurfaceHolder.Callback2接口。既然继承于SurfaceView,就拥有SurfaceView的特性。如能在View的基础上创建独立的Surface,拥有SurfaceHolder来管理Surface,并且可以在子线程中进行View的渲染操作。通过SurfaceHolder得到Canvas,然后在单独的线程中利用Canvas绘制内容,然后更新到Surface。
GLSurfaceView在SurfaceView的基础上实现GLThread(EGLContext创建GL环境所在线程),可通过OpenGL进行绘制,可在SurfaceView所提供的Surface进行绘制。
二、引入
GLSurfaceView在Android工程中可以通过xml的形式引入,也可以直接在java代码中使用。
1.xml中引入示例:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.opengl.GLSurfaceView
android:id="@+id/mGLSurfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
2.java代码引入示例:
mGLSurfaceView = new GLSurfaceView(this);
//设置使用OpenGL2.0版本
mGLSurfaceView.setEGLContextClientVersion(2);
mGLSurfaceView.setRenderer(new LineRenderer(this));
//设置渲染模式:requestRender方法触发会渲染
mGLSurfaceView.setRenderMode(DGLSurfaceView.RENDERMODE_WHEN_DIRTY);
setContentView(mGLSurfaceView);
三、GLSurfaceView常用方法介绍
方法 | 介绍 |
---|---|
setEGLContextClientVersion | 设置opengl es的版本号,目前支持1、2、3,分别对应OpenGL ES1.0、OpenGL ES2.0、OpenGL ES3.0 |
setRenderer | 设置与此视图关联的渲染器 |
setRenderMode | RENDERMODE_WHEN_DIRTY:手动触发;RENDERMODE_CONTINUOUSLY:自动触发 |
四、Renderer的相关介绍
在实现Renderer的时候必须继承GLSurfaceView.Renderer接口,并且实现onSurfaceCreated、onSurfaceChanged和onDrawFrame接口。示例如下:
public class EmptyRenderer implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
@Override
public void onDrawFrame(GL10 gl) {
}
}
onSurfaceCreated:
onSurfaceCreated是在Surface创建的时候被调用的。可以在这个函数的实现中做一些初始化的工作。它的函数原型如下:public abstract void onSurfaceCreated (GL10 gl, EGLConfig config)。第二个参数在文档中没有关于它的任何public方法和域。因此我们可以不用管它。第一个参数非常重要。如果说Renderer是画笔的话,那么这个gl参数,就可以说是我们的手了。如何操作这支画笔,都是它说了算!所以我们绝大部分时候都是通过这个叫做gl的手来指挥Renderer画图的。
onSurfaceChanged:
onSurfaceChanged是当GLSurfaceView大小改变时,对应的Surface大小也会改变。值得注意的是,在Surface刚创建的时候,它的size其实是0,也就是说在画第一次图之前它也会被调用一次的。(而且对于很多时候,Surface的大小是不会改变的,那么此函数就只在创建之初被调用一次而已),当然也有变化时候,例如横竖屏切换等。
原型如下:public abstract void onSurfaceChanged (GL10 gl, int width, int height) , 该方法返回了控件的宽高,这点很重要。因为在onSurfaceCreated的时候我们是不知道纸的宽高的,所以有一些和长宽相关的初始化工作还得在此函数中来做。
onDrawFrame:
onDrawFrame就是真正实现绘制,每调用一次就会重新绘制一次。
五、概念
纹理:
可以被采样的复杂的数据集合,但这里我们先把纹理简单理解成一块连续的内存,本节就且把它看成一副图像。
在Opengl ES中我们使用最多的有两种类型的纹理:TEXTURE_2D和TEXTURE_EXTERNAL_OES,后面一种纹理主要用于摄像头数据采集,通过SurfaceTexture来转换得到,而摄像头采集获得的数据一般是YUV格式的,事实上,通过查看Opengl的源码我们知道,Android底层对TEXTURE_EXTERNAL_OES这种类型的纹理是经过特殊转换的,前一种纹理就是标准的RGB格式图像数据,这一节我们主要用到的是TEXTURE_2D的纹理,后一种在讲摄像头预览的时候会详细说明。
网友评论