OpenGL ES 的版本
目前OpenGL ES有如下三个版本:
OpenGL ES 1.X :针对固定功能流⽔管线硬件
OpenGL ES 2.X :针对可编程流⽔管线硬件
OpenGL ES 3.X :OpenGL ES 2.0的扩展
EGL
上一篇文章也介绍了EGL,
GhostClock:OpenGL ES学习(一)-OpenGL ES初探zhuanlan.zhihu.com其主要功能如下:
- 和本地窗⼝系统(native windowing system)通讯;
- 查询可⽤的配置;
- 创建OpenGL ES可⽤的“绘图表⾯”(drawing surface);
- 同步不同类别的API之间的渲染,⽐如在OpenGL ES和OpenVG之间同步,或者在OpenGL和本地窗⼝的绘图命令之间;
- 管理“渲染资源”,⽐如纹理映射(rendering map)。
1.认识GLSL
GLSL也就是OpenGL Shading Language,也称作 GLslang,是一个以C语言为基础的高阶著色语言。它是由 OpenGL ARB 所建立,提供开发者对绘图管线更多的直接控制,而无需使用汇编语言或硬体规格语言。
https://www.wikiwand.com/zh-hans/GLSLwww.wikiwand.com1.1.GLSL中的向量数据类型
默认位float类型,即vec2,vec3,vec4默认位float类型。
1.2.GLSL中的矩阵数据类型
当需要创建的列和行相等时,例如mat2x2、mat3x3,mat4x4这样的矩阵叫方阵,可以简写成mat2、mat3、mat4。
1.3.在Xcode中创建顶点着色器文件、片元着色器文件
在Xcode中,是不支持编写色器文件、片元着色器文件的,也没有相应的后缀,所以需要自己创建一个文件把文件后缀改为.vsh(顶点着色器文件),.fsh(片元着色器文件)。(其实改为什么文件后缀都可以,但是一般为了直观展示,使用.vsh和.fsh,也有以.glsl文件后缀,其实说白了GLSL语言就是一段字符串)。
- 一般不建议直接使用string类型,因为看起来非常的不清晰;
- 不建议写中文注释,因为可能会出先意想不到的bug;
- 一般不在GLSL文件里面写太多的注释。
1.4.GLSL中有三种修饰类型
uniform,attribute,varying。
uniform:把客户端代码(App端)传递到顶点着色器(vertex)和片元着色器(fragment)里面用到的变量。使用gluiform传递参数。我们一般把vertex和fragment看作常量(这里的常量是指,在着色器里面不变的数据)。使用uniform传递的数据一般有: 视图矩阵,投影矩阵,投影视图矩阵。
uniform
attribute:其最大的特点就是只能从客户端把数据传递到顶点着色器,也只能在顶点着色器里面使用。一般用来修饰顶点数据、纹理坐标、颜色、法线,即一切和坐标、和颜色有关的数据。
attribute
varying:当需要把纹理坐标传递到片元着色器里面来时,无法使用attribute来传递,需要使用varying来做以下桥接。
varying
2.顶点着色器和片元着色器
着⾊器与程序
需要创建2个基本对象才能⽤着⾊器进⾏渲染: 着⾊器对象和程序对象.
获取链接后着⾊器对象的⼀般过程包括6个步骤:
- 创建⼀个顶点着⾊器对象和⼀个⽚段着⾊器对象
- 将源代码链接到每个着⾊器对象
- 编译着⾊器对象
- 创建⼀个程序对象
- 将编译后的着⾊器对象连接到程序对象
- 链接程序对象
2.1.创建与编译⼀个着⾊器
GLuint
3.创建与链接程序
GLUint
4.将客户端代码传递到顶点着色器、片元着色器-案例(加载图片)
4.1.编写着色器代码
shaderv.vsh
attribute
shaderf.fsh
shaderf
4.2.加载shader
//加载shader
4.3.编译着色器
// 编译着色器
在不使用采样GLKBaseEffect时,使用编译链接自定义的着色器(shader)。用简单的glsl语言来实现顶点、片元着色器,并图形进行简单的变换。思路:
- 创建图层
- 创建上下文
- 清空缓存区
- 设置RenderBuffer
- 设置FrameBuffer
- 开始绘制
4.3.1.创建图层
-
4.3.2.创建上下文
-
4.3.3.清空缓存区
-
为什么要⽤FrameBuffer和 RenderBuffer? 它们是什么关系?
⼀个renderbuffer对象是通过应⽤分配的⼀个2D图像缓存区。renderbuffer能够被⽤来分配和存储颜⾊、深度或者模板值。也能够在⼀个framebuffer被⽤作颜⾊、深度、模板的附件。⼀个renderbuffer是⼀个类似于屏幕窗⼝系统提供可绘制的表⾯。⽐如pBuffer。⼀个renderbuffer,然后它并不能直接的使⽤像⼀个GL纹理。
⼀个frameBuffer对象(通常被称为⼀个FBO)。是⼀个收集颜⾊、深度和模板缓存区的附着点。描述属性的状态,例如颜⾊、深度和模板缓存区的⼤⼩和格式,都关联到FBO(Frame Buffer Object)。并且纹理的名字和renderBuffer 对象也都是关联于FBO。各种各样的2D图形能够被附着framebuffer对象的颜⾊附着点。它们包含了renderbuffer对象存储的颜⾊值、⼀个2D纹理或⽴⽅体贴图。或者⼀个mip-level的⼆维切⾯在3D纹理。同样,各种各样的2D图形包含了当时的深度值可以附加到⼀个FBO的深度附着点钟去。唯⼀的⼆维图像,能够附着在FBO的模板附着点,是一个renderbuffer对象存储模板值。
4.3.4.设置RenderBuffer
-
4.3.5.设置FrameBuffer
-
4.3.6.开始绘制
-
图片解压缩
// 从图片中加载纹理:图片解压缩
最终得到的效果
案例源码:
使用顶点着色器和片元着色器(GLSL)加载图片
5.解决图片翻转问题
5.1.旋转矩阵翻转图形,不翻转纹理
增加翻转方法
-
然后修改顶点着色器
attribute
然后在绘图时调用
...
这种方案不可取,因为改动的地方比较多。
案例代码:
使用顶点着色器和片元着色器(GLSL)加载图片-图片翻转1
5.2.解压图片时,将图片源文件翻转
比较多见的解决方法
...
OpenGL_ES_004-使用顶点着色器和片元着色器(GLSL)加载图片--图片翻转2
5.3.修改片元着色器,纹理坐标
修改纹理坐标
precision
5.4.修改顶点着色器,纹理坐标
attribute
5.5.直接从源纹理坐标数据修改
GLfloat
最终的执行结果: