OpenGL二维图像绘制流程说明

Vertex Shader

  • Shader Program必须包含Vertex ShaderFragment Shader, 其中Vertex Shader负责告诉GPU图像顶点的位置, Fragment Shader负责告诉GPU某个位置的颜色值
  • Vertex Shader
  // attribute 仅能在Vertex Shader中使用变量, 在Shader Program运行期间不断变化, 一般用于定点坐标、纹理坐标、顶点颜色
  attribute vec4 position;
  attribute vec4 inputTextureCoordinate;
  // uniform声明Vertex Shader和Fragment Shader中使用的常量, 在Shader 中不能修改, 但外部可通过`glUniformXX`函数给`uniform`的常量赋值.
  uniform mat4 mvpMatrix;
  // varying 用于修饰Vertex Shader传递数据到Fragment Shader的变量的关键字, 一旦有(Vertex/Fragment)Shader使用了varying变量, 另一方(Vertex/Fragment)Shader也必须声明同样类型和命名的变量。在Shader外不能直接修改varying变量
  varying vec2 textureCoordinate;

  void main() {
    // `gl_Position`是Vertex Shader的内置输出变量, 表示当前Vertex Shader处理的顶点坐标最终映射的位置, 并赋给`gl_Position`
    gl_Position = mvpMatrix * position;
    // 将外部输入的纹理坐标`inputTextureCoordinate.xy`赋值给`textureCoordinate`, 即传递给Fragment Shader
    textureCoordinate = inputTextureCoordinate.xy;
  }

  // 变量类型
  `vecN`表示N(2<=N<=4)个浮点数类型分量的向量(vector), `vecN`的读取和构造方式灵活, 可按需通过`x`, `y`, `x`, `w`; `r`、`g`、`b`、`a`或者`s`、`t`、`p`、`q`来读取
  vec3 v3 = vec3(1.0, 2.0, 3.0);
  // 读取第二分量值
  float y = v3.y; // 2.0
  float g = v3.g; // 2.0
  // 将xyz值赋给vec3变量
  vec4 v4 = vec4(v3.xyz, 4.0);
  float q = v4.q;// 4.0

Fragment Shader

  // 定义Fragment Shader使用的浮点数的精度为中等精度, 可以使用低精度`lowp`和高精度`highp`。高精度不是所有设备支持。Fragment Shader必须声明浮点数精度, 否则在mali GPU上运行失败(如美图手机)
  precision mediump float;
  varying highp vec2 textureCoordinate;
  // `sample2D`表示2D的texture类型
  uniform sample2D inputTextureCoordinate;

  void main() {
    // 表示从纹理`inputTextureCoordinate`中获取坐标为`textureCoordinate`的像素值
    vec4 color = texture2D(inputTextureCoordinate, textureCoordinate);
    // `gl_FragColor`是Fragment Shader的内置输出变量, 表示Vertex Shader处理的顶点坐标的位置对应的色值
    // 注意这里丢失了`inputImageTexture`的alpha通道, 原因是如果纹理的RGB和alpha混合后, 离屏渲染再混合可能出现泛白问题
    gl_FragColor = vec4(color.rgb, 1.0);
  }

Shader Program

  // 1. 定义句柄
  // Shader Program句柄
  private int mProgramHandle;
  // 水印纹理ID
  private int mTextureId;
  // 顶点坐标数组
  private FloatBuffer mVertexBuffer;
  ...

  // 2. 定义好句柄, 给句柄赋值
  public GLProgram(String vertexShader, String fragmentShader) {
    mProgramHandle = OpenGLUtils.loadProgram(vertexShader, fragmentShader);
    ...
  }

  // 3. bitmap转纹理
  public void loadTexture(Bitmap bitmap) {
    mTextureId = OpenGLUtils.loadTexture(bitmap, mTextureId, true);
  }

  // 4. 定点坐标

  // 5. gl准备工作

  // 6. 绘制

参考