学习OpenGL(二)GLSL

2.3 OpenGL着色器语言描述

2.3.1 使用GLSL构建着色器

变量的声明

GLSL是一种强类型的语言,所有变量都必须事先声明,并且要给出变量的类型。
GLSL中的基本数据类型:

类型描述
floatIEEE 32 位浮点数
doubleIEEE 64 位浮点数
int有符号二进制补码的 32 位整数
uint无符号的 32 位整数
bool布尔值
变量的作用域

在任何函数定义之外声明的变量拥有全局作用域,因此对着色器程序中的所有函数都是可见的。
在一组大括号之内声明的变量,只能在大括号的范围内存在。
循环的迭代自变量,只能在循环体内起作用。

构造函数

向量的构造函数还可以用来截短或者加长一个向量。如果将一个较长的向量传递给一个较短向量的构造函数,那么向量将别自动取短到对应的长度。
vec4 color;
vec3 RGB = vec3 (color);

类似的,也可以使用同样的方式来加长一个向量。这也是唯一的一类构造函数,它的输入参数比变量的事迹分量数较少。
vec3 white = vec3(1.0); // white = (1.0, 1.0, 1.0);
vec4 translucent = vec4 (white, 0.5);

矩阵的构建方式于此相同,并且可以将它初始化为一个对角矩阵或者完全填充的矩阵。对于对角矩阵,只需要向构造函数传递一个值,矩阵的对角线元素就设置为这个值,其他元素全部设置为0,例如:

				 (4.0 0.0 0.0)
m = mat3(4.0) =  (0.0 4.0 0.0)
				 (0.0 0.0 4.0)

矩阵的指定需要遵循列主序的原则,传入的数据将首先填充列,然后填充行。

mat3 M = mat3  (1.0, 2.0, 3.0,
				4.0, 5.0, 6.0,
				7.0, 8.0, 9.0);

得到的结果 (1.0 4.0 7.0)
----------------(2.0 5.0 8.0)
----------------(3.0 6.0 9.0)

向量分量的访问符
分量访问符符号描述
x, y, z, w与位置相关的分量
r, g, b, a与颜色相关的分量
s, t, p, q与纹理坐标相关的分量

2.3.2 存储限制符

类型修饰符描述
const将一个变量定义为只读形式,如果它初始化时用的是一个编译时常量,那么它本身也会成 为编译时常量
In设置这个变量为着色器阶段的输入变量
out设置这个变量为着色器阶段的输出变量
uniform设置这个变量为用户应用程序传递给着色器的数据,它对于给定的图元而言是一个常量
buffer设置应用程序共享的一块可读写的内存,这块内存与作为着色器中的存储缓存使用
shared设置变量是本地工作组中共享的。它只能用于计算着色器中

GLint glGenUniformLocation (GLuint program, const char* name);
返回着色器程序中uniform变量name对应的索引值。

当得到uniform变量的对应索引值之后,我们就可以通过glUniform*() 或者 glUniformMatrix*()系列函数来设置uniform变量的值了。

  • void glUniform {1234} {fdi ui} (GLint location, TYPE value);

  • void glUniform {1234} {fdi ui}v (GLint location, GLsizei count, const TYPE* values);

  • void glUniformMatrix {234} {fd} v (GLint location, GLsizei count, GLboolean transpose, const GLfloat* values);

  • void glUniformMatrix {2x3,2x4,3x2,3x4,4x2,4x3}{fd}v(GLint location, GLsizei count, GLboolean transpose, const GLfloat* values);

设置与location索引位置对应的uinform变量的值。

对于 glUniformMatrix {2x3,2x4,3x2,3x4,4x2,4x3} *()系列函数来说,可以从values中读入对应矩阵维度的数值构成矩阵。如果transpose设置为GL_TRUE,那么values中的数据是以行主序的顺序读入的,如果是GL_FALSE,那么values中的数据是以列主序的顺序读入的。

2.5 着色器编译

对于每个着色器对象:

1.创建一个着色器对象。
2.将着色器源代码编译为对象。
3.验证着色器的编译是否成功。
然后将多个着色器对象链接为一个着色器程序:
1.创建一个着色器程序。
2.将着色器对象关联到着色器程序。
3.链接着色器程序。
4.判断着色器的链接过程是否成功完成。
5.使用着色器来处理顶点和片元。

调用glCreateShader(GLenum type);
分配一个着色器对象,type必须是GL_VERTEX_SHADER、GL_FRAGMENT_SHADER、GL_TESS_CONTROL_SHADER、GL_TESS_EVALUATION_SHADER、GL_GEOMETRY_SHADER、或GL_COMPUTE_SHADER中的一个。返回指可能是一个非零的整数值,如果返回0说明发生了错误。

void glShaderSource (GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
将着色器源代码关联到一个着色器对象shader上。

void glCompileShader (GLuint shader);
编译着色器的源代码。结果查询可以调用glGetShaderiv(),并且参数为GL_COMPILE_STATUS.返回的是编译过程的状态。如果返回为GL_TRUE,那么编译成功,下一步可以将对象链接到一个着色器程序中。如果返回失败,那么可以通过调取编译日志来判断错误的原因。glGetShaderInfoLog()函数会返回一个与具体实现相关的信息,用于描述编译时的错误。这个错误日志的大小可以通过调用glGetShaderiv()(带参数 GL_INFO_LENTH)来查询。

void glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei* length, char* infoLog);
返回shader的最后编译效果。返回的日志信息是一个以NULL结尾的字符串,它保存在infoLog缓存中,长度为length个子浮窗。日志可以返回的最大值是通过bufSize来定义的。如果length设置为NULL,那么将不会返回infoLog的大小。

当创建并编译了所有必要的着色器对象之后,下一步就是链接它们以创建一个可执行的着色器程序。

GLuint glCreateProgram(void);
创建一个空的着色器程序。返回指是一个非零的整数,如果为0则说明发生了错误。

void glAttachShader(GLuint program, GLuint shader);
将着色器对象shader关联到着色器程序program上。

void glDetachShader(GLuint program, GLuint shader);
移除着色器对象shader与着色器程序program的关联。

void glLinkProgram (GLuint program);
处理所有与program关联的着色器对象来生成一个完整的着色器程序。

void glGetProgramInfoLog(GLuint program,GLsizei bufSize, GLsizei* length,char* infoLog);
返回最后一次program链接的日志信息。

void glUseProgram(GLuint program)
使用链接过的着色器程序program。如果program为零,那么所有当前使用的着色器都会被清除。

void glDeleteShader(GLuint shader);
删除着色器对象shader。如果shader当前已经链接到一个或者多个激活的着色器程序上,那么它将被标识为“可删除”,当对应的着色器程序不再使用的时候,就会自动删除这个对象。

void glDeleteProgram (GLuint program)
立即删除一个当前没有在任何环境下使用的着色器程序program.如果程序正在被某个环境使用,那么等他空闲时在删除。

最后,为了确保接口的完整性,还可以调用glIsShader()来判断某个着色器对象是否存在,或者通过glIsProgram()判断着色器程序是否存在。

GLboolean glIsShader(GLuint shader);
如果shader是一个通过glCreateShader()生成的着色器对象的名称,并且没有被删除,那么返回GL_TRUE,如果shader是零或者不是着色器对象名称的非零值,则返回GL_FALSE。

GLboolean glIsProgram(GLuint program);
如果program是一个通过glCreateProgram()生成的程序对象的名称,并且没有被删除,那么返回GL_TRUE,如果program是0或者不是着色器程序名称的非零值,则返回GL_FALSE。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值