纹理加载后是全白的_OpenGL ES学习(二)-使用顶点着色器和片元着色器(GLSL)加载图片...

05a56a38112281c8c9bf297adf22307f.png

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
ac8758056201cf1c63cef68b2ed5b7e3.png

其主要功能如下:

  1. 和本地窗⼝系统(native windowing system)通讯;
  2. 查询可⽤的配置;
  3. 创建OpenGL ES可⽤的“绘图表⾯”(drawing surface);
  4. 同步不同类别的API之间的渲染,⽐如在OpenGL ES和OpenVG之间同步,或者在OpenGL和本地窗⼝的绘图命令之间;
  5. 管理“渲染资源”,⽐如纹理映射(rendering map)。

1.认识GLSL

GLSL也就是OpenGL Shading Language,也称作 GLslang,是一个以C语言为基础的高阶著色语言。它是由 OpenGL ARB 所建立,提供开发者对绘图管线更多的直接控制,而无需使用汇编语言或硬体规格语言。

https://www.wikiwand.com/zh-hans/GLSL​www.wikiwand.com

1.1.GLSL中的向量数据类型

b76cc2647e3121f73a31bf5439db4a18.png
向量数据类型

默认位float类型,即vec2,vec3,vec4默认位float类型。

1.2.GLSL中的矩阵数据类型

b4a07aee0a5fc252206b9ad4df2044d3.png
矩阵数据类型

当需要创建的列和行相等时,例如mat2x2、mat3x3,mat4x4这样的矩阵叫方阵,可以简写成mat2、mat3、mat4。

1.3.在Xcode中创建顶点着色器文件、片元着色器文件

在Xcode中,是不支持编写色器文件、片元着色器文件的,也没有相应的后缀,所以需要自己创建一个文件把文件后缀改为.vsh(顶点着色器文件),.fsh(片元着色器文件)。(其实改为什么文件后缀都可以,但是一般为了直观展示,使用.vsh和.fsh,也有以.glsl文件后缀,其实说白了GLSL语言就是一段字符串)。

  1. 一般不建议直接使用string类型,因为看起来非常的不清晰;
  2. 不建议写中文注释,因为可能会出先意想不到的bug;
  3. 一般不在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个步骤:

  1. 创建⼀个顶点着⾊器对象和⼀个⽚段着⾊器对象
  2. 将源代码链接到每个着⾊器对象
  3. 编译着⾊器对象
  4. 创建⼀个程序对象
  5. 将编译后的着⾊器对象连接到程序对象
  6. 链接程序对象

2.1.创建与编译⼀个着⾊器

GLuint 

3.创建与链接程序

GLUint 

4.将客户端代码传递到顶点着色器、片元着色器-案例(加载图片)

4.1.编写着色器代码

shaderv.vsh

attribute 

shaderf.fsh

shaderf

4.2.加载shader

//加载shader

4.3.编译着色器

// 编译着色器

在不使用采样GLKBaseEffect时,使用编译链接自定义的着色器(shader)。用简单的glsl语言来实现顶点、片元着色器,并图形进行简单的变换。思路:

  1. 创建图层
  2. 创建上下文
  3. 清空缓存区
  4. 设置RenderBuffer
  5. 设置FrameBuffer
  6. 开始绘制

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对象存储模板值。

7122a6fe39f7c1c5c257b21a8147faa6.png
FrameBuffer Objects,RenderBuffer Objects and Textures

4.3.4.设置RenderBuffer

-

4.3.5.设置FrameBuffer

-

4.3.6.开始绘制

-

图片解压缩

// 从图片中加载纹理:图片解压缩

最终得到的效果

85345efaa4a1b840d50bb54bf176f48a.png
最终得到的效果

案例源码:

使用顶点着色器和片元着色器(GLSL)加载图片

5.解决图片翻转问题

5.1.旋转矩阵翻转图形,不翻转纹理

增加翻转方法

-

然后修改顶点着色器

attribute 

然后在绘图时调用

...

这种方案不可取,因为改动的地方比较多。

案例代码:

使用顶点着色器和片元着色器(GLSL)加载图片-图片翻转1

5.2.解压图片时,将图片源文件翻转

比较多见的解决方法

...

63db712507a390cbe1fd9ee6abc0f365.png
执行原理

OpenGL_ES_004-使用顶点着色器和片元着色器(GLSL)加载图片--图片翻转2

5.3.修改片元着色器,纹理坐标

修改纹理坐标

precision 

5.4.修改顶点着色器,纹理坐标

attribute 

5.5.直接从源纹理坐标数据修改

GLfloat 

最终的执行结果:

e9ae238dfd07fbae71f851e69c8617a1.png
最终的执行结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值