先放一个图形渲染管线的每个阶段的抽象展示。要注意蓝色部分代表的是我们可以注入自定义的着色器的部分:
顶点缓冲对象(VBO)
所有的顶点数据(位置、纹理、法线等)都需要存储在GPU上,OpenGL通过顶点缓冲对象管理这个内存。其声明和绑定的代码函数如下:
unsigned int vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
设置顶点属性
在绑定VBO时,我们只是指定了一堆数据,但是对于其内存布局(layout)完全未知,为了让机器知道顶点属性,我们还需如下代码(这两行代码的顺序无所谓):
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
每个索引都可以绑定一种属性,比如上面的例子就是将每2个连续的float
作为一组属性绑定在索引0上,这里的索引0在后面的顶点着色器中也会使用到。
代码中并没有指明这个属性具体是什么属性,比如位置还是法线等,它只是一组属性并且被绑定在了索引上。
你可能会觉得很奇怪,没有指明哪个内存空间就直接设置属性。这也是OpenGL状态机的体现,只要在GL_ARRAY_BUFFER
上绑定的VBO,那么这个属性就对应的是这个VBO。
着色器(shader)
着色器简单来说就是运行在显卡上的一段小程序,我们可以通过编程控制器输入输出进而控制图像的显示。OpenGL着色器是用OpenGL着色器语言(OpenGL Shading Language, GLSL)写成的,它是一种类C语言。
就目前而言,我们最需要了解的着色器就两个:顶点着色器和片段着色器。简单来说,我们首先在CPU上定义了顶点数据,之后将其转移到显存上(通过VBO),之后需要通过顶点着色器(一段小程序,对每个顶点都运行一次)处理顶点数据,并将必要的数据输出,再之后就是片段着色器(计算颜色等,对每个光栅块处理一次)进行处理,最后通过混合显示图像。
着色器间不能相互通信,它们之间唯一的沟通只有通过输入和输出。GLSL定义了in和out关键字专门来实现这个目的。每个着色器使用这两个关键字设定输入和输出,只要一个输出变量与下一个着色器阶段的输入匹配,
标签:绑定,诞生,OpenGL,顶点,三角形,GL,着色器,属性 From: https://www.cnblogs.com/warren-j1an/p/18225096