OpenGL 编程指南(第八版)学习笔记——2 着色器基础
GLSL在notepad与VS2015中扩展:
GLSL(GL Shading Language)
使用GLSL构建着色器
#version 330 core
void
main()
{
// 在这里编写代码
}
变量
-
所有变量声明的同时进行初始化
-
聚合类型:
基本类型 2D向量 3D向量 4D向量 矩阵类型 float vec2 vec3 vec4 mat2 mat3 mat4… double dvec2 dvec3 dvec4 dmat2x2 dmat2x3… int ivec2 ivec3 ivec4 uint uvec2 uvec3 uvec4 bool bvec2 bvec3 bvec4 -
访问向量和矩阵中的元素
向量和矩阵中的元素是可以单独访问和设置的.
可以通过各个分量访问,也可以通过索引坐标访问
分量访问符 符号描述 (x,y,z,w) 与位置相关的分量 (r,g,b,a) 与颜色相关的分量 (s,t,p,q) 与纹理坐标相关的分量 -
结构体
-
数组
隐式方法: .length() -> 返回数组长度
-
存储限制符
类型修饰符 描述 const 常量 in 输入 out 输出 uniform 设置这个变量为用户应用程序传递给着色器的数据.它对于图元而言是一个常量 buffer 设置应用程序共享的一块可读写的内存.这块内存也作为着色器的存储缓存 shared 设置变量是本地工作组(local work group)中共享的.它只能用计算着色器中
数据块接口
- uniform变量可以使用 uniform块.
- 输入与输出变量可以使用in和out块
- 着色器的存储缓存可以使用buffer块
uniform块
-
写法:
uniform b{ vec4 v1; bool v2; }; // 访问成员时使用v1,v2 /* 或着 */ uniform b{ vec4 v1; bool v2; }name; //访问成员时使用name.v1,name.v2;
-
uniform缓存对象就是一种优化uniform变量访问,以及在不同的着色器程序之间共享uniform数据的方法
-
从应用程序中访问uniform块
// 返回program中名为 uniformBlockName的uniform块的索引值 GLuint glGetUniformBlockIndex(GLuint program,const char* uniformBlockName);
buffer块
-
GLSL中的buffer块,对于应用程序而言,就是着色器中的
存储缓存对象
. -
着色器可以写入 buffer块. 修改其中的内存并呈现给其他着色器
-
可以在渲染之前再决定它的大小.而不是在编译和连接的时候.
例如:
buffer BufferObject{ // 创建一个可读写的buffer块 int mode; // vec4 points[]; // 未定义大小的数组 };
-
如不需要写入缓存中,直接使用uniform.
着色器的编译
- 对于每个着色器对象:
- 创建一个着色器对象
- 将着色器源代码编译为对象
- 验证着色器编译是否成功
- 需要将多个着色器对象链接为一个着色器程序:
- 创建一个着色器程序
- 将着色器对象关联到着色器程序
- 连接着色器程序
- 判断着色器的链接过程是否成功完成
- 使用着色器来处理顶点和片元
// 调用 glCreateShader() 来创建着色器对象 分配一个着色器对象,type必须为 GL_VERTEX_SHADER GL_FRAGMENT_SHADER GL_TESS_CONTROL_SHADER GL_TESS_EVALUATION_SHADER或着GL_GEOMETRY_SHADER
GLuint glCreateShader(GLenum type);
// glShaderSource 将着色器代码关联到着色器对象shader上.
// glCompileShader(GLuint shader); // 比着色器的源代码