注:本文旨在记录笔者的学习过程,仅代表笔者个人的理解,如果有表述不准确的地方,欢迎各位指正!因为涉及到的概念来源自网络,所以如有侵权,也望告知!
前言
本文我们的目标是来了解一下OpenGL渲染架构的模型以及数据传递的3种⽅式。
正文
架构图
通过这个流程图,我们不难发现OpenGL把渲染分为两大部分,Client(客户端)和Server(服务端),这里的Client和Server跟我们日常开发中接触到的概念不同。OpenGL渲染过程中,Client是指在CPU中执行的代码块,比如C/C++的编码、OpenGL封装的API;Server则代表在GPU内做的渲染过程,包括顶点着色器操作、光栅化操作、片元着色器操作等等。
数据传递
从我们的架构图上也可以看到,OpenGL仅提供了3种数据传递的方式,来供我们向服务端(Server)中的顶点着色器(Vertex Shader)和片元着色器(Fragment Shader)传递参数和渲染信息,这三个通道分别是Attribute(属性变量),Uniform(统一变量),Texture Data(纹理变量)。这里要注意的是Uniform和Texture Data是可以同时直接传递数据给顶点着色器与片元着色器的,而Attribute则只能直接传递数据给顶点着色器,片元着色器是通过顶点着色器作为中介间接传递的。
那么这3种数据传递的方式,到底可以传递哪些类型的数据呢?
Texture Data变量
Texture Data纹理变量是专门用来传递纹理数据的通道。
Uniform变量
uniform变量是外部application程序传递给(vertex和fragment)shader的变量。因此它是application通过函数glUniform**()函数赋值的。在(vertex和fragment)shader程序内部,uniform变量就像是C语言里面的常量(const),它不能被shader程序修改。也就是说shader只能用不能改uniform变量。
如果uniform变量在vertex和fragment两者之间声明方式完全一样,则它可以在vertex和fragment共享使用。(相当于一个被vertex和fragment shader共享的全局变量)
uniform变量一般用来表示:变换矩阵,材质,光照参数和颜色等信息。
Attribute变量
attribute变量是只能在vertex shader中使用的变量。(attribute变量不能在fragment shader中声明,也不能被fragment shader中使用)
一般用attribute变量来表示一些顶点的数据,如:顶点坐标,法线,纹理坐标,顶点颜色等。
在application中,一般用函数glBindAttribLocation()来绑定每个attribute变量的位置,然后用函数glVertexAttribPointer()为每个attribute变量赋值。
varying变量是vertex和fragment shader之间做数据传递用的,并且OpenGL ES会对其进行线性插值。一般vertex shader修改varying变量的值,然后fragment shader使用该varying变量的值。因此varying变量在vertex和fragment shader二者之间的声明必须是一致的。application不能使用此变量。