openGL

GLSL语言的三种变量类型attribute uniform varying

  1. attribute 只能在vertex sharder中使用,通过glVertexAttribPointer()赋值
  2. uniform 相当于常量,通过glUniform**赋值
  3. varying 是vertex与fragment之间传递数据用的,一般vertex shader修改varying的值,然后fragment sharder 自动更新该值。

OpenGL Es 2.0过程及理解

读取顶点数据——执行顶点着色器——组装图元——光栅化图元——执行片元着色器——写入帧缓冲区——显示到屏幕上。

  • 内存拷贝。OpenGL作为本地库直接运行在硬件上,没有虚拟机,也没有垃圾回收或者内存压缩。在Java层定义图像的数据需要能被OpenGL存取,因此,需要把内存从Java堆复制到本地堆。

    1
    2
    3
    4
    5
    6
    private FloatBuffer floatBuffer;
    float[] vertexData = new float[16];
    floatBuffer = ByteBuffer.allocateDirect(vertexData.length * Constant.BYTES_PRE_FLOAT)
    .order(ByteOrder.nativeOrder())
    .asFloatBuffer()
    .put(floatBuffer);
  • 光栅化技术。手机屏幕都是由一个个像素点构成的,光栅化过程就是把每个点、直线和三角形分解成大量的小片元,每个片元都包含单一的纯色。

  • 顶点着色器是针对每个顶点都会执行的程序,是确定每个顶点的位置。同理,片元着色器是针对每个片元都会执行的程序,片元着色器确定每个片元的颜色。
  • 着色器需要进行编译,然后链接到OpenGL程序中。一个OpenGL的程序就是把一个顶点着色器和一个片段着色器链接在一起变成单个对象。

OpenGL 开发软件编写顺序

  1. java 代码创建顶点的数据
  2. 用ByteBuffer顶点数据从java内存复制到本地内存
  3. 创建顶点着色器代码和片元着色器代码并编译
  4. 顶点着色器和片元着色器总是一起工作的,需要链接顶点着色器和片元着色器,生成一个program
  5. 获取glsl程序里定义参数的location
  6. 利用location将第2步的数据与第4步的program关联起来,告诉program从哪里读取顶点数据
  7. 在onDrawFrame()方法里填充片元着色器数据

透视投影

  • 透视投影的原理是:利用矩阵将坐标的z分量反映到w分量,从而实现“远近效果”
  • 焦距-焦点到视椎体近端平面的距离称为焦距,焦距大小影响小端与大端的比例,以及对应的视野
  • 调用Matrix.perspectiveM()设置投影矩阵

FBO

OpenGL渲染管线的最后一个阶段,就是帧缓冲区(FrameBuffer)。对于帧缓冲区,Android系统中默认有一个缓冲区,英文名称window-system-provided framebuffer,用于屏幕显示。 当GPU往显示缓冲区写入数据后,屏幕会显示这个缓冲区的内容。这是一个生产者消费者模型,大多数情况下能满足我们的需求。
而对于Android某些特殊需求来说,比如给视频加水印后渲染保存,比如Camera实时滤镜。 这些都需要把视频的原始data经过一定的处理后保存、或者再进行显示。

对于一般的Camera来说,我们用于预览/录制的Surface都是由Android系统提供给OpenGL渲染的帧缓冲区,OpenGL的所有渲染结果都是直接到达到帧缓冲区,这是on-screen的渲染方式;
而对于滤镜相机、贴纸相机来说,使用帧缓冲区对象,OpenGL可以将原先绘制到窗口提供的帧缓冲区重定向到FBO之中。

FBO是一个挂接器,类似画家画画用的托架;其中FBO只能挂接两种对象,纹理图像 和 渲染图像,这个理解就是画家准备创作作品前,在托架上放的是油画纸还是水墨纸(纹理),或者根本不是放画纸,放的是木板雕刻(渲染模板)。最后我们等画家创作出他的艺术品后,直接搬到到展示区,呈现給大家