基础语法
int i = 300;
float f = 2.0f;//floact类型必须要有f
bool b = true;
聚合数据类型 - 向量
2D向量 3D向量 4D向量
float vec2 vec3 vec3
int ivec2 ivec3 ivec4
bool bvec2 bvec3 bvec4
//定义:
vec3 position = vec3(0.0f, 0.3f, 0.5f);
聚合数据类型 - 矩阵
float mat2(2*2矩阵) mat3(3*3矩阵) mat4x3 (4*3矩阵)
注意:举证相乘 需要看是否能链接
比如 mat4x3 与 mat3x2 得到一个4x2矩阵 换位置相乘无意义
还可以用结构体
注意 : GLSL文件里面不要加注释 有时候会编译不过
修饰符
uniform
外部(客户端)传递给vertext和fragment。
- 类似于const ,被uniform修饰的变量在顶点、片元着色器就只能用不能修改
uniform mate4 viewP;//mate4 为4x4矩阵
attribute
只能在顶点着色器使用 。用来表示顶点数据 (vertex shader)
attribute vec4 position;
varying
顶点着色器(vertex shader)传递数据到片元着色器中(fragment shader)
//顶点着色器 和 片元着色器 都声明这个
varying lowp vec2 varyTextCoord;
in out inout
- in 修饰输入变量
- out 修饰输出变量
- inout 修饰输入输出变量
精度设置
高精度
attribute highp vec4 position;
floating Point Range 范围在(-262,262)
Integer Range 范围在(-216,216)
中精度
attribute mediump vec2 textCoordinate;
floating Point Range 范围在 (-214,214);
Integer Range 范围在(-210,210)
低精度
varying lowp vec2 varyTextCoord;
floating Point Range 范围在 (-2,2);
Integer Range 范围在(-28,28)
低精度可以往高进度 转换:所以 int 的高&中精度可以转 float的高&中精度 。int 低进度不能转 float的低精度
注意:在顶点着色器里面已经默认了高精度。片元着色器没有默认,所以片元着色器需要自己写精度。
内键变量已经有默认精度
OpenGL ES 使用GLSL绘制图片
流程
- 需要创建2个基本对象才能用着色器进行渲染:着色器对象和程序对象(GLuint myPrograme)
- 获取连接后着色器对象 的 一般过程包括6个步骤
- 创建一个顶点着色器对象和一个片元着色器对象
- 将源代码连接到每个着色器对象
- 编译着色器
- 创建一个程序对象
- 将编译后的着色器对象连接到程序对象
- 连接程序对象
创建着色器文件(顶点着色器&片元着色器)
文件名 shaderv.vsh (顶点着色器)
attribute vec4 position;
attribute vec2 textCoordinate;
varying lowp vec2 varyTextCoord;
void main(){
varyTextCoord = textCoordinate;
gl_Position = position;
}
文件名 shaderf.fsh (片元着色器)
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main(){
gl_FragColor = texture2D(colorMap,varyTextCoord);
}
IOS端伪代码
开始绘制
-(void)randerLayer{
//设置清屏颜色
glClearColor(0.3f, 0.45f, 0.5f, 1.0f);
//清除屏幕
glClear(GL_COLOR_BUFFER_BIT);
//1.设置视口大小
CGFloat scale = [[UIScreen mainScreen]scale];
glViewport(self.frame.origin.x * scale, self.frame.origin.y * scale, self.frame.size.width * scale, self.frame.size.height * scale);
//2.读取顶点着色程序、片元着色程序
NSString *vertFile = [[NSBundle mainBundle]pathForResource:@"shaderv" ofType:@"vsh"];
NSString *fragFile = [[NSBundle mainBundle]pathForResource:@"shaderf" ofType:@"fsh"];
//3.加载shader
self.myPrograme = [self loadShaders:vertFile Withfrag:fragFile];
//4.链接
glLinkProgram(self.myPrograme);
GLint linkStatus;
//获取链接状态
glGetProgramiv(self.myPrograme, GL_LINK_STATUS, &linkStatus);
if (linkStatus == GL_FALSE) {
GLchar message[512];
glGetProgramInfoLog(self.myPrograme, sizeof(message), 0, &message[0]);
NSString *messageString = [NSString stringWithUTF8String:message];
NSLog(@"Program Link Error:%@",messageString);
return;
}
NSLog(@"Program Link Success!");
//5.使用program
glUseProgram(self.myPrograme);
...(顶点设置 纹理设置)
// 传入着色器 属性
//(1)注意:第二参数字符串必须和shaderv.vsh中的输入变量:position保持一致
GLuint position = glGetAttribLocation(self.myPrograme, "position");
//(2).设置合适的格式从buffer里面读取数据
glEnableVertexAttribArray(position);
//(3).设置读取方式
//参数1:index,顶点数据的索引
//参数2:size,每个顶点属性的组件数量,1,2,3,或者4.默认初始值是4.
//参数3:type,数据中的每个组件的类型,常用的有GL_FLOAT,GL_BYTE,GL_SHORT。默认初始值为GL_FLOAT
//参数4:normalized,固定点数据值是否应该归一化,或者直接转换为固定值。(GL_FALSE)
//参数5:stride,连续顶点属性之间的偏移量,默认为0;
//参数6:指定一个指针,指向数组中的第一个顶点属性的第一个组件。默认为0
glVertexAttribPointer(position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, NULL);
//9.----处理纹理数据-------
//(1).glGetAttribLocation,用来获取vertex attribute的入口的.
//注意:第二参数字符串必须和shaderv.vsh中的输入变量:textCoordinate保持一致
GLuint textCoor = glGetAttribLocation(self.myPrograme, "textCoordinate");
//(2).设置合适的格式从buffer里面读取数据
glEnableVertexAttribArray(textCoor);
//(3).设置读取方式
//参数1:index,顶点数据的索引
//参数2:size,每个顶点属性的组件数量,1,2,3,或者4.默认初始值是4.
//参数3:type,数据中的每个组件的类型,常用的有GL_FLOAT,GL_BYTE,GL_SHORT。默认初始值为GL_FLOAT
//参数4:normalized,固定点数据值是否应该归一化,或者直接转换为固定值。(GL_FALSE)
//参数5:stride,连续顶点属性之间的偏移量,默认为0;
//参数6:指定一个指针,指向数组中的第一个顶点属性的第一个组件。默认为0
glVertexAttribPointer(textCoor, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (float *)NULL + 3);
...(加载纹理)
//11. 设置纹理采样器 sampler2D
glUniform1i(glGetUniformLocation(self.myPrograme, "colorMap"), 0);
...(绘图)
}
#pragma mark - shader 链接
-(GLuint)loadShaders:(NSString*)vert Withfrag:(NSString*)frag{
GLuint verShader,fragShader;
GLuint program = glCreateProgram();
//编译
[self compileShader:&verShader type:GL_VERTEX_SHADER file:vert];
[self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:frag];
//着色器连接到program
glAttachShader(program, verShader);
glAttachShader(program, fragShader);
//连接之后需要删除
glDeleteShader(verShader);
glDeleteShader(fragShader);
return program;
}
#pragma mark - shader 编译
-(void)compileShader:(GLuint*)shader type:(GLenum)type file:(NSString*)file{
//1。读取文件路径 字符串
NSString *content = [NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil];
const GLchar *source = (GLchar*)[content UTF8String];
//2、创建着色器 - 需要指定是顶点着色器还是片元着色器
*shader = glCreateShader(type);
/*
3、着色器 代码 -> 附着到 着色器上面
参数1:shader 要编译的着色器对象 *shader
参数2:numberOfString 传递的源码字符串数量 1个
参数3:strings,着色器程序的源码(真正的着色器程序源码)
参数4:lenOfStrings,长度,具有每个字符串长度的数组,或NULL,这意味着字符串是NULL终止的
*/
glShaderSource(*shader, 1, &source, NULL);//1 传的是1个source
//4.着色器源码编译成目标代码
glCompileShader(*shader);
}
函数汇总
glDeleteShader(GLuint shader)
shader - 要上去的着色器对象句柄
glShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
shader - 指向着色器对象句柄
count - 着色器源字符串的数量,着色器可以由多个源字符串组成,但每个着色器只有一个main函数
string - 指向保存数量的count着色器源字符串的数组指针
length - 指向保存每个着色器字符串大小且元素数量为count的整数数组指针
glCompileShader(GLuint shader)
shader - 需要编译的着色器对象句柄
glGetShaderiv(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 — 需要获取信息⽇日志的着⾊色器器对象句句柄
maxLength — 保存信息⽇日志的缓存区⼤大⼩小
length — 写⼊入的信息⽇日志的⻓长度(减去null 终⽌止符); 如果不不需要知道⻓长度. 这个参数可以为Null infoLog — 指向保存信息⽇日志的字符缓存区的指针.
从程序信息⽇日志中获取信息
void glGetPorgramInfoLog( GLuint program ,GLSizei maxLength, GLSizei *length , GLChar *infoLog )
program : 指向需要获取信息的程序对象句句柄
maxLength : 存储信息⽇日志的缓存区⼤大⼩小
length : 写⼊入的信息⽇日志⻓长度(减去null 终⽌止符),如果不不需要知道⻓长度,这个参数可以为Null. infoLog : 指向存储信息⽇日志的字符缓存区的指针
void glUseProgram(GLuint program) program: 设置为活动程序的程序对象句句柄
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 - 指向程序对象句柄
链接程序之后, 需要检查链接是否成功. 你可以使⽤用glGetProgramiv 检查链接状态:
void glGetProgramiv (GLuint program,GLenum pname, GLint *params);
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
课程研发:CC⽼老老师 课程授课:CC⽼老老师
params : 指向查询结果整数存储位置的指针
网友评论