任何一种OpenGL程序本质可以分为两个部分:CPU运行的部分 (采用C++之类的语言编写)和 GPU运行的部分(采用GLSL语言编写)
OpenGL的可编程管线:
- 顶点着色阶段(vertex shading stage) 必选
- 细分着色阶段(tessellation shading stage) 可选
- 细分控制着色器 (tessellation control shader)
- 细分赋值着色器(tessellation evaluation shader)
- 几何着色阶段(geometry shading stage) 可选
- 片元着色阶段(fragment shading stage) 必选
- 计算着色阶段 (conpute shading stage) 可选
GLSL创建着色器
1. 注释,同C语言规范一致
// 单行注释
/* */ 多行注释
2. main函数 ,不需要同C语言一样返回一个int而是返回一个void
void main(){
}
3. 每一行必须需要一个分号
4.变量的声明,命名规范同C语言一致
5. 基本数据类型
透明:内部形式都是暴露出来的
不透明类型:内部形式没有暴露出来
包括:采样器(sampler) 图像(image) 原子计数器(atomic counter)
6. 变量的作用域(同C++一致)
7.构造函数
类型转换:检验严格 如: int a = false;将编译错误
能够进行隐士转换的类型有:
8. 聚合类型
GLSL的基本类型可以合并,从而与核心OpenGL的数据类型一致,从而简化数据计算过程操作
类型赋值:vec3 velocity = vec3(1.0, 1.0, 1.0);
类型间等价转换:ivec3 steps = ivec3(velocity);
截短: vec4 color;
vec3 RGB= vec3(color);//现在只有前3个分量了
加长: vec3 white = vec3(1.0);
vec4 translucent = vec4(white, 0.5);
矩阵的构建方式:
m = mat3(4.0) = 一个值时指设置对角线的值,其余部分值均设置为0
通过以下几种形式来初始化一个3*3 的矩阵
或者
访问向量矩阵中的元素,各分量可直接根据名字进行访问,或者从0 开始
结构体与数组:同C语言语法一致。
9.存储限制符
uniform存储限制符:
可以声明一个uniform,将颜色的值传递到着色器当中
uniform vec4 Basecolor
在着色器当中,可以根据名字Basecolor来引用这个变量。
如果需要设置当中的值需要获得BaseColor 的索引,通过
GLint glGenUniform(GLuint program, const char * name);来获取
返回对应的索引值,那么为一个字符串
例子:
GLint timeLoc;
GLfloat timeValue;
timeLoc = glGetUniformLocation(program, "time");
glUniform1f(timeLoc, timevalue);
算术操作符重载 :大部分操作符都是经过重载的。没有的可以通过函数调用的方式实现
函数声明:
returntype fuctionname([accessModifier] type1 variable1, [accessModifier] type2 variable2 ...)
{
//函数体
return value;
}
计算的不变性 : precise invariance
10 数据块接口
uniform块
uniform{
mat4 ModelView;
mat4 Projection;
mat4 Color;
}
用应用程序中访问uniform块:
Gluint glGetUniformBlockIndex(GLuint program,const char * uniformBlockName);
返回uniform块的索引值
获取索引之后需要将一个缓存对象与整个块关联
void glBindBufferRange(GLenum target, GLuint index, GLuint buffer, Glintptr offset, GLsizeiptr size)
void glBindBufferBase(GLenum target, GLuint index, GLuint buffer)
着色器的编译:
对于每个着色器对象
1. 创建一个着色器对象
GLuint glCreateShader(GLenum type);
2. 将着色器源码编译为对象
void glShaderSource(GLuint shader, GLsizei count, const char** string, const GLint* length);
void glCompileShader(GLuint shader);
3.验证着色器编译是否成功
void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, char* infolog);
然后将多个着色器对象链接为一个着色器程序
创建一个着色器程序
GLuint glCreateProgram(void);
将着色器对象关联到着色器程序
void glAttatchShader(GLuint program, GLuint shader);
void glDetachShader(GLuint program, GLuint shader);
链接着色器程序
void glLinkProgram(GLuint program);
判断着色器的链接过程是否成功完成
void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
使用着色器来处理顶点或者片元
void glUseProgram(GLuint program);