Android OpenGL ES 学习 - 基础环境

配图摄于槟城,日出


建立 OpenGL ES 环境

概念 - 摘抄于《维基百科》

OpenGL(英语:Open Graphics Library,译名:开放图形库或者“开放式图形库”)是用于渲染 2D、3D 矢量图形的跨语言、跨平台的应用程序编程接口(API)

OpenGL ES(OpenGL for Embedded Systems)是 OpenGL 三维图形 API 的子集,针对手机、PDA 和游戏主机等嵌入式设备而设计。

要在应用里使用 OpenGL ES 画图,必须有一个容器(一个 View)去做这个事情。最直接的方法就是使用 GLSurfaceView 和 GLSurfaceView.Renderer,GLSurfaceView 是 OpenGL ES 画图的容器,而 GLSurfaceView.Renderer 则是控制画一些什么。

使用 GLSurfaceView 是实现 OpenGL ES 绘图的其中一个途径,可以全屏或者任意自定义大小。如果只是需要在一个 layout 里面放一个小小的 OpenGL ES 绘图容器,则可以了解一下 TextureView。当然,使用 OpenGL ES 在 SurfaceView 上绘制也是可以的,只是需要更多的一些操作,而实际上 GLSurfaceView 也是继承 SurfaceView。

在 Manifest 里声明 OpenGL ES

为了能在应用里使用 OpenGL ES 2.0 API,我们需要声明:

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

其中 0x00020000 是版本 2.0,使用 3.0 的则是:

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

在 Acticity 里使用 OpenGL ES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MainActivity extends AppCompatActivity {

    private GLSurfaceView mGLSurfaceView;

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

        mGLSurfaceView = (GLSurfaceView) findViewById(R.id.my_GLSurfaceView);
        // 设置 OpenGL ES 2.0 
        mGLSurfaceView.setEGLContextClientVersion(2);
        // 若没有 setRenderer,会造成程序奔溃
        mGLSurfaceView.setRenderer(new MyRenderer());
    }
}

创建我们的 Renderer 类

GLSurfaceView.Renderer,这个类用来控制在 GLSurfaceView 上面画些什么东西,里面有三个方法会被 Android 系统调用从而可以计算控制画些什么以及怎么画。

  • onSurfaceCreated() 在创建 OpenGL ES 环境的时候被调用
  • onDrawFrame() 每一次的绘制都会调用
  • onSurfaceChanged() 当 view 的大小改变的时候调用,例如机器的横竖屏切换

以下是一个对 OpenGL ES renderer 的简单实现,绘制一个红色背景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    private static class MyRenderer implements GLSurfaceView.Renderer {

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            gl.glClearColor(1f, 0f, 0f, 0f);
        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        }
    }

效果: