OpenGL系列(四)Shader

发布于:2024-06-04 ⋅ 阅读:(189) ⋅ 点赞:(0)

    通过VBO和VAO准备好数据后,接下来要指示GPU如何通过这些数据绘制图形。类似CPU可以通过执行程序来完成特定的任务,GPU也可以执行特定的程序来完成绘制任务,GPU执行的程序称为Shader,也叫着色器。

    GPU绘制图形分为不同的处理阶段,在顶点处理和片元

OpenGL的着色器使用GLSL语言编写

着色器程序示例

     三角形示例icon-default.png?t=N7T8https://blog.csdn.net/leesino/article/details/139093716 使用到了顶点着色器(Vertex Shader)和片元着色器(Fragment Shader),下面分别对两者进行介绍。

    首先介绍的是顶点着色器,示例中的三角形的Vertex Shader的源码如下所示:

#version 300 es
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 outColor;
void main()
{
    gl_Position = vec4(aPos, 1.0);
    outColor = aColor;
}

    Vertex Shader的源码解析:

  1. #version 300 es 指定使用 OpenGL ES 3.0版本。
  2. aPos 声明接收顶点数据的变量,其中layout (location = 0)表示数据从0号属性取出,in表示这是一个输入变量。vec3表示这是一个3个浮点数的向量。
  3. aColor用于接收颜色数据,内容从1号顶点属性获得。
  4. 在main方法中,把aPos转成4维向量后传给gl_Position,这是个内置变量,一般用于传递顶点数据,是一个4维的浮点数向量,因此这里要把顶点从3维向量转为4维向量。
  5. outColor用于将颜色属性传递到下一个阶段,out表示输出变量。

    顶点着色器程序的执行次数与顶点数量有关,因此绘制一个三角形要执行3次顶点着色器程序。

    接下来介绍片元着色器程序,片元着色器程序用于确定每个片元的最终颜色,三角形示例的代码如下。

#version 300 es
precision mediump float;
out vec4 FragColor;
 in vec3 outColor;
void main()
{
   FragColor = vec4(outColor, 1.0);
}
  1.  precision mediump float 设置浮点数精度为中精度。
  2. FragColor,该变量声明为out,用于输出片元的最终颜色。
  3. outColor,接收顶点着色器传递过来的颜色,名称必须与顶点着色器声明的一样。

    在光栅化阶段会计算得到一个三角形的片元数量,每个片元执行一次片元着色器程序才能得到它的颜色。

使用方法

    着色器程序准备好了以后,接下来是如何使用着色器绘制图形,大体上分为以下3步:

    1、编译,使用着色器程序绘制图形,首先要对着色器进行编译,编译步骤如下。

    GLuint shader = glCreateShader(shader_type);

    //attach source to shader object
    glShaderSource(shader, 1, &source, NULL);
    glCompileShader(shader);

    // Check for compilation errors
    GLint compiled = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);

    着色器编译流程解析如下:

  1. glCreateShader,创建着色器对象,创建成功后得到着色器的句柄。参数用于指明着色器的类型,GL_VERTEX_SHADER表示创建的是顶点着色器对象,GL_FRAGMENT_SHADER表示创建的是片元着色器对象。
  2. glShaderSource,将着色器程序加载到着色器对象中
  3. glCompileShader,对着色器进行编译
  4. glGetShaderiv,第二个参数传GL_COMPILE_STATUS表示要获取编译结果。

    如果顶点着色器和片元着色器编译都没有问题,下一步可以对它们进行链接。

2、链接

    链接过程主要把不同阶段的着色器变成一个程序,主要步骤如下

GLuint program = glCreateProgram();
glAttachShader(program, shaders[i]);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &linked);

链接步骤解析如下。

  1. glCreateProgram,创建着色器程序对象,成功后返回程序对象的句柄。
  2. glAttachShader,将着色器添加到程序对象
  3. glLinkProgram,链接程序
  4. glGetProgramiv,通过该方法可以获取链接结果。

链接没有问题,最后可以使用着色器程序绘制图形。

3、使用

   使用着色器绘制图形比较简单,以下是使用着色器程序绘制图形的过程。

void onDraw(){
   glUseProgram(mProgram);
   glBindVertexArray(VAO);
   glDrawArrays(GL_TRIANGLES, 0, 3);
   glUseProgram(0);
}

    绘制流程解析如下:

  1. glUseProgram指定要使用的着色器程序
  2. glBindVertextArray指定VAO,相当于明确了顶点数据
  3. glDrawArrays开始绘制
  4. 最后glUseProgram传入0表示未指定任何着色器程序。

到此为止,三角形示例的主要代码流程基本介绍完成,通过OpenGL系列(二)EGLOpenGL系列(三)VBO、VAO和本文的学习,基本上能理解三角形的绘制流程。


网站公告

今日签到

点亮在社区的每一天
去签到