GLSL

作者: tp夕阳武士 | 来源:发表于2020-04-13 00:33 被阅读0次
    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语法中使用分支语法

    相关文章

      网友评论

          本文标题:GLSL

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