1.着色器与与程序
- 需要创建两个基本对象才能使用着色器进行渲染:着色器对象(shader objcet)和程序对象(program object).
- 获取连接后,着色器对象的过程一般包括6个步骤:
stp1:参加一个顶点着色器对象和一个片元着色器对象
stp2:将源代码连接到每个着色器对象
stp3:编译着色器对象
stp4:参加一个程序对象
stp5:将编译后的着色器对象连接到程序对象
stp6:连接程序对象.
2.创建于编译一个着色器
GLuint glCreatshader(GLenume type);
//type : 创建的着色器类型:GL_VERTEX_SHADER 或 GL_FRAGMENT_SHADER
//返回值: GLuint类型 指向一个着色器对象的句柄,可以用glDeletshader方法删除
void glDeletShader(GLuint shader);
//shader : 需要被删除的着色器句柄
void glShaderSource(GLuint shader ,GLSizei count, const GLChar *string, const GLint *length );
//shader : 着色器句柄
//count : 着色器源字符串数量,着色器可以由多个源字符串组成,但是每个着色器只有一个main函数
//sting : 指向保存数量的count 的着色器源字符串的数组指针;
//length: 指向保存每个着色器字符串大小且元素数量为count的整数数组指针
void glComplieShader(GLuint shader);
//需要被编译的shader
// shader : 着色器句柄
void glGetShaderv(GLuint shader , GLenum pname , GLint *params);
//shader : 需要编译的着色器句柄
//pname : 需要获取的信息 :
GL_COMPILE_STATUS/
GL_DELETE_STATUS/
GL_INFO_LOG_LENGTH/
GL_SHADER_SOURCE_LENGTH/
GL_SHADER_TYPE/
//params: 查询结果
void glGetShaderInfoLog(GLuint shader , GLSizei maxlength , GLSizei *length , GLChar *infoLog);
//shader : 需要获取日志的shader
//maxlength : 保存信息日志的缓存区大小
//length: 写入的信息日志的长度,如果不需要知道长度,这个值可以穿NULL
//infoLog: 指向保存信息日志的字符串缓区的指针
GLUint glCreateProgram( )
//创建一个程序对象
//返回值: 返回一个执行新程序对象的句柄
void glDeleteProgram( GLuint program )
// program : 指向需要删除的程序对象句柄
//着⾊器与程序连接/附着
void glAttachShader( GLuint program , GLuint shader );
//program : 指向程序对象的句柄
//shader : 指向程序连接的着⾊器对象的句柄
//断开连接
void glDetachShader(GLuint program);
//program : 指向程序对象的句柄
//shader : 指向程序断开连接的着色器对象句柄
glLinkProgram(GLuint program);
//program : 指向程序对象句柄,也就是指向自己编写的两个glsl的两个文件
//连接以后需要检查是否连接成功,检查方法:
void glGetprogramiv(GLuint program, GLenum pname , GLint *params);
//program : 需要查询连接状态的program
//pname : 需要查询的是哪方面的信息,可选值有:
//GL_ACTIVE_ATTRIBUTES
//GL_ACTIVE_ATTRIBUTES_MAX_LENGTH
//GL_ACTIVE_UNIFORM_BLOCK
//GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH
//GL_ACTIVE_UNIFROMS
//GL_ACTIVE_UNIFORM_MAX_LENGTH
//GL_ATTACHED_SHADERS
//GL_DELETE_STATUS
//GL_INFO_LOG_LENGTH
//GL_LINK_STATUS
//GL_PROGRAM_BINARY_RETRIEVABLE_HINT
//GL_TRANSFORM_FEEDBACK_BUFFER_MODE
//GL_TRANSFORM_FEEDBACK_VARYINGS
//GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH
//GL_VALIDATE_STATUS
//params : 指向查询结果的指针;
// 从程序信息日志中获取信息
void glGetProgramInfoLog(GLuint program , GLSizei maxlength , GLSizei *length , GLChar *infoLog);
//program : 程序句柄
// maxlength : 存储信息日志的缓存区⼤小
//length : 写入的信息日志的长度;
//infoLog : 指向存储信息日志的字符缓存区的指针
void glUseProgram(GLuint program);
//program : 设置为活动程序对象句柄; 使用某个程序;
3.数据类型
向量类型 |
解释 |
vec2,vec3,vec4 |
2分量、3分量、4分量浮点向量 |
ivec2,ivec3,ivec4 |
2分量、3分量、4分量整型向量 |
uvec2,uvec3,uvec4 |
2分量、3分量、4分量无符号整型向量 |
bvec2,bvec3,bvec4 |
2分量、3分量、4分量bool型向量 |
矩阵类型 |
解释 |
mat2,mat2x2 |
两行两列 |
mat3,mat3x3 |
三行三列 |
mat4,mat4x4 |
四行四列 |
mat2x3 |
三行两列 |
mat2x4 |
四行两列 |
mat3x2 |
两行三列 |
mat3x4 |
四行三列 |
mat4x2 |
两行四列 |
mat4x3 |
三行四列 |
变量存储限定符 |
解释 |
<none> |
普通的本地变量外部不见,外部不可访问 |
const |
常量 |
in/varying |
从前阶段传过来的变量 |
in/varying centroid |
从前阶段传过来的变量,使用质心插值 |
out/attribute |
传递到下一个处理阶段或者在⼀个函数中指定⼀个返回值 |
out/attribute centroid |
传递到下⼀个处理理阶段,质⼼插值 |
uniform |
⼀个从客户端代码传递过来的变量,在顶点之间不不做改变 |
4.向量的声明与构造与基础运算;
与举出类型一样,向量也需要声明与初始化(构造),但是向量的构造需要使用构造函数,向量的构造函数是一个内建函数;
// 声明一个2分量浮点型向量
vec2 V1 ;
// 声明一个3分量整型向量
ivec2 V2;
// 声明一个无符号整型向量(3分量)
uvec3 V3;
// 声明并初始化 一个 4分量浮点型向量
vec4 V4 = vec4(x,y,z,w); //注意,这里使用了内建函数vec4();
// 向量的运算
vec4 v;
vec4 vOldPos = vec4(1,2,3,4);
vec4 vOffset = vec4(1,2,3,4);
v = vOldPos + vOffset;
v = vNewPos;
v += vec4(10,10,10,10);
v = vOldPos * vOffset;
v *= 5;
//向量可以单个或多个元素赋值 / 获取元素值也是同样的原理
v1.x = 3.0f;
v1.xy = vec2(3.0f,4.0f);
v1.xyz = vec3(3,0f,4,0f,5.0f);
//使用这个原理可以简单修改rgba
Vcolor.r = 3.0f;
Vcolor.rgba = vec4(1.0,1.0,1.0,1.0);
//修改纹理坐标
Vtexture.st = vec2(1.0,0);
//注意注意注意!!!!!!!!
//赋值混合是错误语法;
v1.st = v2.xt; // 不可以
v1.st = v2.xy; // 可以 但是没有任何意义
//向量支持调换操作,2个或者两个以上的元素进行交换
v1.rgba = v2.bgra;
// 向量支持一次性对所有分量操作
v1.x = v2.x +5.0f;
v1.y = v2.y +4.0f;
v1.z = v2.z +3.0f;
v1.xyz = v2.xyz + vec3(5.0f,4.0f,3.0f);
5.矩阵
矩阵类型 |
解释 |
mat2,mat2x2 |
两行两列 |
mat3,mat3x3 |
三行三列 |
mat4,mat4x4 |
四行四列 |
mat2x3 |
三行两列 |
mat2x4 |
四行两列 |
mat3x2 |
两行三列 |
mat3x4 |
四行三列 |
mat4x2 |
两行四列 |
mat4x3 |
三行四列 |
注意: 矩阵只有浮点类型,没有整型
//向量其实也可以看做一个矩阵,只不过它在行或者列上固定只有一行或者一列
vec4 mv = vec4(0,0,0,1);
vec4 mv2 = mv[3];
//1.声明矩阵
mat4 m1,m2,m3;
//2声明并构造一个矩阵
mat4 m4 = mat4(1.0f,0.0f,0.0f,0.0f,
0.0f,1.0f,0.0f,0.0f,
0.0f,0.0f,1.0f,0.0f,
0.0f,0.0f,0.0f,1.0f,
); //这是一个单元矩阵,
//如果是构造一个单元矩阵,还有简单的写法
mat4 m5 = mat4(1.0);
6.变量存储限定符
变量存储限定符 |
解释 |
<none> |
普通的本地变量外部不见,外部不可访问 |
const |
常量 |
in/varying |
从前阶段传过来的变量 |
in/varying centroid |
从前阶段传过来的变量,使用质心插值 |
out/attribute |
传递到下一个处理阶段或者在⼀个函数中指定⼀个返回值 |
out/attribute centroid |
传递到下⼀个处理理阶段,质⼼插值 |
uniform |
⼀个从客户端代码传递过来的变量,在顶点之间不不做改变 |
//常用的
const float zero = 0;
attribute vec4 position;
varying lowp vec2 varyTextCoord;
uniform mat4 rotateMatrix;
//可以关联glsl渲染图片项目中的着色器文件代码复习;
7. 结构体
struct forStruct{
vec4 color;
float start;
float end;
}fogVar; //定义一个结构体,结构体内部的元素可以使用glsl的数据,如向量,矩阵
fogVar = fogStruct(vec4(1.0,0.0,0.0,1.0),0.5,2.0); //初始化一个矩阵;
vec4 color = fogVar.color;
float start = fogVar.start;
8.数组
float floatArray[4];
vec4 vecArray[2];
float a[4] = float[](1.0,2.0,3.0,4.0);
vec2 c[2] = vec2[2](vec2(1.0,2.0),vec2(3.0,4.0));
9.函数
//glsl 定义了三个函数修饰符
in : (如果没有指定的时候,默认是这个修饰符),in修饰符的作用是,参数只能传入,不能修改;
inout : 传入相应数值,并且在函数中可以修改;
out : 函数返回时使用;
//接下来看看函数是怎么构造的
vec4 myFunc(inout float myFloat, out vec4 m1, mat4 m2){
};
vec4 diffuse(vec3 normal ,vec3 light, vec4 baseColor) {
return baseColor * dot(normal,light);
};
//注意,在glsl中,函数是没有递归的,因为所有函数都要先声明再使用,所以在前面的函数是无法调用后面声明的函数的;
10. 分支语句
在GLSL中同样存在分支语句:
if esle / do...while... / for 循环
但是尽量不要在glsl语法中使用分支语法
网友评论