1

1、背景

本文我们基于最基础,最简单的OpenGL API,最终实现三角形的绘制(基于OpenGL 1.0 Java接口)。本文只对OpenGL相关接口使用进行介绍,深入原理后续逐步剖析。

2、Android OpenGL环境搭建

Android为我们提供了SurfaceView,可以在一个新启的单独线程中可以重新绘制画面,GLSurfaceView在SurfaceView的基础上绑定了OpenGL相关环境。工作中我们用到这两个控件主要是播放视频,预览摄像头画面,今天我们使用GLSurfaceView调用OpenGL相关接口进行绘制。

首先,GLSurfaceView的创建和普通View没区别:GLSurfaceView view = new GlSurfaceView(context);

接着,我们需要为GLSurfaceView设置渲染器GLSurfaceView.Rendererview.setRenderer(renderer)

GLSurfaceView.Renderer是一个接口,要实现这个接口需要实现三个方法:

public class MyRenderer 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) {
  }

这三个方法的调用时机:

  1. onSurfaceCreated是GLSurfaceView被创建时,调用线程是GL线程;
  2. onSurfaceChanged是GLSurfaceVIew大小发生改变时,比如收到虚拟按键隐藏显示等影响导致大小发生改变;
  3. onDrawFrame是真正的执行,GLSurfaceView可以通过setRenderMode设置渲染模式,有两种渲染模式:

    1. RENDERMODE_WHEN_DIRTY:脏渲染,命令渲染,只有surface被创建时或者我们主动调用requestRender时才会触发onDrawFrame方法回调;
    2. RENDERMODE_CONTINUOUSLY:持续渲染,GL线程会持续的调用onDrawFrame进行绘制。

接下来我们实现这三个接口就可以进行具体绘制了。

3、绘制步骤

3.1 onSurfaceCreated

onSurfaceCreate中做一些一次性操作:

  1. 设置清屏色:gl.glClearColor(0f, 0f, 0f, 1f);,代表整个背景的颜色,最小0,最大1,四个参数分别代表R、G、B、A分量;
  2. 启用顶点缓存:gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);,glEnableClientState 和 glDisableClientState 启用或禁用单个客户端功能。默认情况下,禁用所有客户端功能,我们这里会用到顶点缓存,所以需要手动开启。

3.2 onSurfaceChanged

onSurfaceChange回调时拿到了实际渲染窗口大小,可以:

  1. 设置视口大小:gl.glViewport(0, 0, width, height);
  2. 设置投影矩阵:

    1. 设置投影矩阵:gl.glMatrixMode(GL10.GL_PROJECTION);
    2. 加载单位矩阵,重置投影矩阵:gl.glLoadIdentity();
    3. 设置平截头体:gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7);,前四个参数代表近平面(左右下上),后面两个参数分别代表近平面Z坐标值。

3.3 onDrawFrame

每次绘制时我们要做一些事情:

  1. 清除颜色缓冲区和深度缓冲区:gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
  2. 加载模型视图矩阵:gl.glMatrixMode(GL10.GL_MODELVIEW);
  3. 加载单位矩阵,重置模型视图矩阵:gl.glLoadIdentity();
  4. 设置摄像机/眼睛坐标:GLU.gluLookAt(gl, 0f, 0f, 5f, 0f, 0f, 0f, 0f, 1f, 0f);分别代表摄像机XYZ坐标、朝向XYZ坐标、朝上XYZ坐标
  5. 设置绘制颜色:gl.glColor4f(1f, 0f, 0f, 1f);,这里我们设置为红色
  6. 设置三角形顶点集合:gl.glVertexPointer(3, GL10.GL_FLOAT, 0,buffer);,第一个参数代表每个点多少个type,第二个参数代表每个点表达数据类型,第三个参数步幅,这里是0,buffer是java.nio.Buffer,存放顶点坐标数据
  7. 绘制三角形:gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

3.4 效果展示

用到的顶点坐标:

float[] vertexCoords = {
        0.2f,0f,0f,
        0.6f,0f,0f,
        0.4f,0.5f,0f
}

Screenshot_20230428_170104.jpg

4、总结

本文介绍了Android系统提供的GLSurfaceView的用法及绘制一个最基本的图像:三角形用到的API:设置清屏色、启用顶点缓存、设置视口、设置投影矩阵等。


轻口味
16.8k 声望3.7k 粉丝

移动端十年老人,主要做IM、音视频、AI方向,目前在做鸿蒙化适配,欢迎这些方向的同学交流:wodekouwei


引用和评论

0 条评论