Learn OpenGL(三)——顶点着色器(Vertext Shader)

        顶点着色器是几个着色器中的一个, 它是可编程的。 现代OpenGL需要我们至少设置一个顶点着色器和一个片段着色器, 如果我们打算做渲染的话。 我们会简要介绍一下着色器以及配置两个非常简单的着色器来绘制我们第一个三角形。 
        我们需要做的第一件事是用着色器语言GLSL写顶点着色器, 然后编译这个着色器, 这样我们就可以在应用中使用它了。 下面你会看到一个非常基础的顶点着色器的源代码, 它就是使用GLSL写的:
 

#version 330 core
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position.x, position.y, position.z, 1.0);
}


就像你所看到的那样, GLSL看起来很像C语言。 每个着色器都起始于一个版本声明。 这是因为OpenGL 3.3和更高的GLSL版本号要去匹配OpenGL的版本(GLSL420版本对应于OpenGL4.2)。 我们同样显式地表示我们会用核心模式(Core-profile)。

下一步, 我们在顶点着色器中声明所有的输入顶点属性, 使用in关键字。 现在我们只关心位置(Position)数据, 所以我们只需要一个顶点属性(Attribute)。 GLSL有一个向量数据类型, 它包含1到4个 float 元素, 包含的数量可以从它的后缀看出来。 由于每个顶点都有一个3D坐标,我们就创建一个 vec3 输入变量来表示位置(Position)。 我们同样也指定输入变量的位置值(Location), 这是用 layout (location = 0) 来完成的, 你后面会看到为什么我们会需要这个位置值。



向量(Vector)
在图形编程中我们经常会使用向量这个数学概念, 因为它简明地表达了任意空间中位置和方向, 二者是有用的数学属性。 


为了设置顶点着色器的输出, 我们必须把位置数据赋值给预定义的 gl_Position 变量, 这个位置数据是一个 vec4 类型的。 在main函数的最后, 无论我们给 gl_Position 设置成什么, 它都会成为着色器的输出。 由于我们的输入是一个3元素的向量, 我们必须把它转换为4元素。 我们可以通过把 vec3 数据作为 vec4 初始化构造器的参数, 同时把 w 元素设置为 1.0f (我们会
在后面解释为什么)。这个顶点着色器可能是能想到的最简单的了, 因为我们什么都没有处理就把输入数据输出了。 在真实的应用里输入数据通常都没有在标准化设备坐标中, 所以我们首先就必须把它们放进OpenGL的可视区域内。
编译一个着色器
我们已经写了一个顶点着色器源码, 但是为了OpenGL能够使用它, 我们必须在运行时动态编译它的源码。
我们要做的第一件事是创建一个着色器对象, 再次引用它的ID。 所以我们储存这个顶点着色器为 GLuint , 然后用 glCreateShader 创建着色器:

GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);


我们把着色器的类型提供 glCreateShader 作为它的参数。 这里我们传递的参数是 GL_VERTEX_SHADER 这样就创建了一个顶点着色器。
下一步我们把这个着色器源码附加到着色器对象, 然后编译它:

glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);


glShaderSource 函数把着色器对象作为第一个参数来编译它。 第二参数指定了源码中有多少个字符串, 这里只有一个。 第三个参数是顶点着色器真正的源码, 我们可以把第四个参数先设置为 NULL 。

注:
可能会希望检测调用glCompileShader后是否编译成功了, 是否要去修正错误。 检测编译时错误的方法是:

GLint success;
GLchar infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);


首先我们定义一个整型来表示是否成功编译, 还需要一个储存错误消息的容器(如果有的话)。 然后我们用`glGetShaderiv`检查是否编译
 

if(!success)
{
   glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
   std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}

 


如果编译的时候没有任何错误, 顶点着色器就被编译成功了
 

你可能感兴趣的:(Opengl)