音视频篇 - GLSurfaceView 初探

这篇文章开始正式进入 OpenGL ES 的世界,来学习使用 GLSurfaceView。

 

1. GLSurfaceView 介绍

GLSurfaceView 从 Android 1.5 (API level 3) 开始加入,继承自 SurfaceView,实现了 SurfaceHolder.Callback2 接口,拥有SurfaceView 的全部特性,也有 view 所有的功能和属性,特别是处理事件的能力,它主要是在 SurfaceView 的基础上它加入了 EGL 的管理,并自带了一个 GLThread 绘制线程(EGLContext 创建 GL 环境所在线程即为 GL 线程),绘制的工作直接通过 OpenGL 在绘制线程进行,不会阻塞主线程,绘制的结果输出到 SurfaceView 所提供的 Surface 上,这使得GLSurfaceView 也拥有了 OpenGL ES 所提供的图形处理能力,通过它定义的 Render 接口,使更改具体的 Render 的行为非常灵活性,只需要将实现了渲染函数的 Renderer 的实现类设置给 GLSurfaceView 即可。

GLSurfaceView 提供了下列特性:

  • 1. 提供并且管理一个独立的 Surface。
  • 2. 提供并且管理一个 EGL display,它能让 OpenGL 把内容渲染到上述的 Surface 上。
  • 3. 支持用户自定义渲染器 (Render),通过 setRenderer 设置一个自定义的 Renderer。
  • 4. 让渲染器在独立的 GLThread 线程里运作,和 UI 线程分离。
  • 5. 支持按需渲染 (on-demand) 和连续渲染 (continuous) 两种模式。
  • 6. GPU 加速:GLSurfaceView 的效率是 SurfaceView 的 30 倍以上,SurfaceView 使用画布进行绘制,GLSurfaceView 利用GPU 加速提高了绘制效率。
  • 7. View 的绘制 onDraw(Canvas canvas) 使用 Skia 渲染引擎渲染,而 GLSurfaceView 的渲染器 Renderer 的onDrawFrame(GL10 gl) 使用 OpenGL 绘制引擎进行渲染。

 

 

2. GLSurfaceView 使用步骤

(1) 在使用 OpenGL ES 前,需要在 AndroidManifest.xml 中设置 OpenGL ES 的版本

这里我使用的是 OpenGL ES 2.0,因此可进行如下声明:

  <uses-feature android:glEsVersion="0x00020000" android:required="true" />

(2) GLSurfaceView 布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_height="match_parent"
  android:layout_width="match_parent">

  <android.opengl.GLSurfaceView
    android:id="@+id/glsurfaceview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>

(3) 初始化 GLSurfaceView

GLSurfaceView 默认情况下已经初始化好了 OpenGL ES 的运行环境,不需要做额外的工作就可以使用(当然你也可以设置一些参数) 

public final class GLSurfaceViewActivity extends AppCompatActivity {

    private GLSurfaceView glSurfaceView;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_glsurfaceview);

        glSurfaceView = findViewById(R.id.glsurfaceview);
        // GLContext 设置 OpenGLES2.0
        glSurfaceView.setEGLContextClientVersion(2);
    }

    @Override
    protected void onResume() {
        super.onResume();
        glSurfaceView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        glSurfaceView.onPause();
    }
}

(4) 设置 Renderer

渲染是 OpenGL ES 的核心工作,setRenderer 可以将用户自定义的一个 Renderer 加入实际的渲染流程中。

        // 设置 renderer
        glSurfaceView.setRenderer(new GLRenderer());
        // 渲染方式,RENDERMODE_WHEN_DIRTY 表示被动渲染,只有在调用 requestRender 或者 onResume 等方法时才会进行渲染。
        // RENDERMODE_CONTINUOUSLY 表示持续渲染
        glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
final class GLRenderer implements Renderer {

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 关闭抗抖动
        gl.glDisable(GL10.GL_DITHER);
        // 设置系统对透视进行修正
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glClearColor(0, 0, 0, 0);
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 渲染窗口大小发生改变或者屏幕方法发生变化时候回调
        GLES20.glViewport(0, 0, width, height);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        // 执行渲染工作
        GLES20.glClearColor(GLES20.GL_COLOR_BUFFER_BIT, 0f, 0f, 0f);
    }
}

这就给 GLSurfaceView 渲染一层黑色背景:


 

下一篇文章将来学习 GLSurfaceView 中 3D 绘图的基本概念与实践。

  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值