OpenGL之顶点着色器、片段着色器

本片文章的最终成果是在屏幕上画出一个三角形。

涉及的知识主要有:顶点输入,顶点着色器,编译着色器,片段着色器,着色器程序,链接顶点属性,顶点数组对象,索引缓冲对象。

首先我们来简答介绍一下OpenGL的渲染管线:

1、渲染管线的第一部分是顶点着色器,顶点着色器允许我们设置一些简单的顶点属性,顶点着色器将一个顶点作为单独的输入,将顶点进行一些坐标系的变换(局部坐标系,世界坐标系,观察坐标系等)。

2、图元装配阶段:他的输入就是顶点着色器的输出,该阶段的作用就是将顶点装配成指定的图形形状,有点、直线,三角形等,有专门的gl指令。

3、几何着色器:该阶段的输入是图元装配阶段的输出,他将图元装配阶段生成的图像进行变换生成新的图像,比如一个三角形变成两个三角形,OpenGL中有默认的几何着色着色器。

4、光栅化:几何着色器的输出会被传入光栅化阶段,光栅化的阶段就是将这些图元映射成最终屏幕上的像素,然后将这些像素传递给片段着色器,在进入片段着色器之前还会进行裁剪,裁剪将极大的提高我们的运行效率。

5、片段着色器:片段着色器主要计算像素的最终颜色,最终片段着色器包含3D场景的许多数据:光照,阴影,光的颜色等,用来计算最终的呈现在屏幕上的像素的颜色。

在上面所有的过程都执行完成之后,就会执行最后的阶段:Alpha测试和混合(Blend),这个阶段会测试他的深度,当前的物体有咩有被挡住,如果挡住的话,我们就可以不用画他,Alpha测试是对像素进行透明度的判断,因为片段着色器计算出来的当前像素像素颜色可能不同于同时渲染几个好多物体的时候当前像素的颜色。

顶点输入

OpenGL中需要我们自己去设置所画图形的顶点,以此顶点来确定图像的位置,但是OpenGL只接受x,y,z坐标在-1到1之间范围的顶点,并把这个范围之间的顶点称之为的标准化顶点,没有在这个范围内的顶点就不会被画出来。

所以如果我们需要画出一个三角形的话,我们就要给出一个坐标在标准化范围之内的顶点:

float vertices[] = {
    -0.5f, -0.5f, 0.0f,
     0.5f, -0.5f, 0.0f,
     0.0f,  0.5f, 0.0f
};

注释:因为OpenGL是在3D中工作的,我们现在如果需要渲染一个2D的三角形,只需将z坐标设置为0,也就是他的深度设置为0,这个时候三角形就是一个2D的三角形。

Tip:标准化坐标系是设置的窗口的中心为坐标系原点,通过标准化坐标系变换到屏幕坐标的过程是根据自己设定的ViewPort的数据,来进行视口变换,最终变换成屏幕坐标。所得到的屏幕坐标又会变成片段进入到片段着色器。

定义好这样的顶点数据之后,我们就可以将起发送到顶点着色器中去,这是一个从CPU发送数据到GPU中,两者的通信比较耗时,所以我们要尽可能的一次发送多的数据到GPU,我们在GPU中使用一个叫做顶点缓冲对象的东西来管理这一段内存,而且我们还需要告诉OpenGL如何管理这一段内存。

顶点缓冲对象和其他的OpenGL对象一样,有一个独一无二的ID,我们创建好之后,还需要将这个顶点缓冲对象进行数据的填充,就使用我们刚才创建的那个数组。

// 我们创建一个ID:VBO
unsigned int VBO;
// 然后使用指令和刚才创建的缓冲来生成一个顶点缓冲对象
glGenBuffers(1, &VBO);

// 然后将我们生成的顶点缓冲对象绑定到对应的类型上
glBindBuffer(GL_ARRAY_BUFFER, VBO); 

// 填充顶点缓冲的数据
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
/*Tip:第一个参数是目标缓冲的类型:
第二个参数指定传输数据的大小(以字节为单位);
第三个参数是我们希望发送的实际数据。
第四个参数指定了我们希望显卡如何管理给定的数据。它有三种形式:
GL_STATIC_DRAW :数据不会或几乎不会改变的时候用这个
GL_DYNAMIC_DRAW:数据会被改变很多用这个
GL_STREAM_DRAW :数据每次绘制时都会改变用这个
*/

现在我们就已经将我们的顶点的数据交由一个顶点缓冲对象VBO来管理了。

你可能感兴趣的:(c++,游戏开发,OpenGL)