基本数据类型
GLSL是一种强类型语言,所有的变量必须事先声明,并给出变量的类型,语法与C语言相似。下表为GLSL的基本数据类型。
以上的基本数据类型是都是”透明”的,他们的内部形式都是暴露出来的,与之对于的是”不透明”类型,他们的内部形式没有暴露出来,例如采样器(sampler),图像(image),以及原子计数器(atomic)。他们声明的变量相当于一个不透明的句柄。
变量的作用域
在任何函数定义之外声明的变量都拥有全局作用域,对着色器中所有函数都是可见的。
在一组大括号之内声明的变量只能在大括号范围内使用
循环的迭代自变量只能在循环内起最作用。
变量的初始化
所有的变量必须在声明的同时进行初始化,例如
int i = 100‘
foat f = 2.0;
bool b = true;
聚合类型
1.矩阵类型需要给出两个纬度的信息,例如mat4*3,其中一个值表示列数,一个值表示行数。
2.向量的初始化与标量类似
Vec3 v = vec3(0.0, 4.0, 1.0);
类型间可以互相转化
ivec3 steps = ivec3(v);
3.矩阵的构建方式与此相同,例如
通过指定每一个元素来初始化
mat3 M = mat3(1, 2, 3,
4, 5, 6,
7, 8, 9)
通过向量来初始化
vec3 v1 = vec3(1,2,3);
vec3 v2 = vec3(4,5,6);
vec3 v3 = vec3(7,8,9);
mat3 M = mat3(v1,v2,v3);
还可以
vec2 v1 = vec2 (1,2);
vec2 v2 = vec2 (4,5);
vec2 v3 = vec2 (7,8);
mat3 M = mat3(v1, 3, v2, 6, v3, 9);
4,访问向量和矩阵中的元素
向量可以使用分量的名称和下表来访问元素
vec3 color = vec3(1,2,3);
float rad = color.r;或 float rad = color[0];
矩阵元素的访问可以使用数组标记访问
mat4 m = mat4(2.0);
vec4 zVec = m[2];
float yScale = m[1][1];
结构体
struct particle{
float lifetime;
vec3 position;
vec3 velocity;
};
数组
GLSL还支持任意类型的数组,包括结构体数组
GLSL4.2和更早的版本不允许创建数组类型的数组。
float coeff[3];//有3个float元素的数组
float[3] coeff;//有3个float元素的数组
int indices[];//为定义数组,可以从新声明它的纬数
float coeff[3] = float[3]2.38, 3.14, 42.0();//用构造函数构造数组
coeff.lenhth();//返回元素的个数
存储限制符
in存储限制符
用于修饰用于定义着色器的输入变量,这类输入可以是顶点属性,也可以是前一个着色器的输出变量
out存储限制符
用于修饰用于定义着色器的输出变量,例如顶点着色器输出坐标,或者片段着色器输出最终的片段颜色
uniform存储限制符
uniform修饰符可以设置一个全局变量,该变量数据是单向传递的,用户应用程序可以修改该变量,着色器只能读取该变量,无法写入到该变量,也无法改变它的值。
在用户程序中想要写入数据到uniform变量,通常需要两个函数
GLint glGetUniformLocation(GLuint program, const char* name);
返回值:返回着色器程序中uniform变量对应的索引值。
参 数:program着色器程序Id
name uniform变量名
void glUniform1f (GLint location, GLfloat value );
返回值:空。
参 数:location色器程序中uniform变量对应的索引值
value写入的值
使用方法通常是这样的
1.在着色器程序中定义一个uniform变量
uniform float temp;
2.在用户程序中修改f的值,首先获取该uniform变量在着色器中对应的索引值,
GLint id = glGetUniformLocation(1, "temp");
3.接着修改它的值
glUniform1f(id, 4);
buffer存储限制符
如果需要在应用程序中共享一大块缓冲给着色器,那么buffer变量是一个好的选择,这块缓冲对于着色器来说是可读可写的。
shared存储限制符只能用于计算着色器中,它可以建立本地工作组内共享的内存。
参数限制符
在GLSL中函数可以在运行后返回和修改数据,但它与"C" 不同,并没有指针或引用的概念,不过函数的参数可以指定一个参数限制符,来表明如何处理数据。
数据块接口
uniform块
着色器与应用程序之间或者着色器个阶段之间共享的变量可以组织为变量块的形式,uniform可以使用uniform块,in, out, buffer可以使用各自对应的块。例如
uniform b{//限定符可以用in, out, buffer
vec3 v;//变量列表
bool b;
}
注:uniform块中只能包含透明类型的变量,而且uniform块必须在全局作用域内声明。
uniform块的布局控制
在uniform块中可以使用不同的限制符来设置变量的布局方式。限制符如下表
如果需要共享一个uniform块,并且使用行主序的方式来存储数据,如下所示:
layout (shared, row_major) uniform{ };
如果需要对所有的uniform块布局,可以使用下面的语句
layout (shared, row_major) uniform;