美文网首页
OpenGL ES - GLSL 语言简介 加实战

OpenGL ES - GLSL 语言简介 加实战

作者: Th丶小伟 | 来源:发表于2020-05-07 15:19 被阅读0次

基础语法

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。

  1. 类似于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

  1. in 修饰输入变量
  2. out 修饰输出变量
  3. 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 : 指向查询结果整数存储位置的指针


源码下载

相关文章

网友评论

      本文标题:OpenGL ES - GLSL 语言简介 加实战

      本文链接:https://www.haomeiwen.com/subject/zadaghtx.html