Qt OpenGL 参考文章及重要概念[转]
【learn opengl with Qt】
- https://blog.csdn.net/qq_40946921/category_9969351.html
- 《OpenGL ES2.0 的三种变量类型(uniform,attribute和varying)》
OpenGL 概念
- 《理解glVertexAttribPointer、glEnableVertexAttribArray、VAO、VBO的关系》
- 《【图像】【OpenGL】VAO和VBO的关系》
- 《》
- 《[OpenGL] VAO、VBO、EBO》
- 使用glGenBuffers函数和一个unsigned int变量生成一个VBO对象(顶点缓冲对象):
void glGenBuffers(GLsizei n,GLuint * buffers);
unsigned int VBO;
glGenBuffers(1, &VBO);
unsigned int VBO[3];
glGenBuffers(3,VBO);
- 使用glBindBuffer函数给这个生成的顶点缓冲对象绑定一个缓冲类型
void glBindBuffer(GLenum target,GLuint buffer);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
- target: 缓冲对象的类型,GL_ARRAY_BUFFER:数组缓冲区,存储颜色、位置、纹理坐标等顶点属性,或者其它自定义属性。
- buffer: 要绑定的缓冲对象的名称(ID), 即我们在glGenBuffers函数里生成的ID。
- glBindBuffer函数完成了三项工作:
- 1、如果是第一次绑定buffer,且buffer是一个非0的unsigned int。那么将创建一个与该名称相对应的新缓冲对象。
- 2、如果绑定到一个已经创建的缓冲对象,那么它将成为当前被激活的缓冲对象。
- 3、如果buffer为0,那么OpenGL将不再对当前的target应用任何缓冲对象。
- 在OpenGL红包书中给出了一个恰当的比喻:
- 绑定对象的过程就像设置铁路的道岔开关,每一个缓冲类型(比如GL_ARRAY_BUFFER)中的各个缓冲对象(比如生成了多个缓冲对象,ID为:123,322,111)就像不同的轨道一样,我们将开关设置为其中一个的状态(比如绑定123为GL_ARRAY_BUFFER),那么之后的列车(针对GL_ARRAY_BUFFER的改动)都会驶入这条轨道(123缓冲对象)。
- 使用glBufferData函数将数据储存进那片显存区域中(缓冲对象)
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
- glBufferData是一个专门用来把用户定义的数据复制到当前绑定缓冲的函数。
- 它的第一个参数是目标缓冲的类型:顶点缓冲对象当前绑定到GL_ARRAY_BUFFER目标上。
- 第二个参数指定传输数据的大小(以字节为单位);用一个简单的sizeof计算出就行。
- 第三个参数是我们希望发送的实际数据。
- 第四个参数指定了我们希望显卡如何管理给定的数据。它有三种形式:
- GL_STATIC_DRAW :数据不会或几乎不会改变。
- GL_DYNAMIC_DRAW:数据会被改变很多。
- GL_STREAM_DRAW :数据每次绘制时都会改变。
- 这个函数完成了两个任务:在显存中分配数据所需得储存空间,将数据从CPU内存中拷贝到GPU显存中。
- 使用glVertexAttribPointer函数可以告诉OpenGL该如何解析这些数据(应用到逐个顶点属性上)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
- 第一个参数指定我们要配置的顶点属性。即在顶点着色器中使用layout(location = 0)定义了position顶点属性的位置值(Location),把顶点属性的位置值设置为0,因为这里我们希望把数据传递到这一个顶点属性中,所以这里我们传入0。
- 第二个参数指定顶点属性的大小。在例子中,三维坐标是一个vec3,它由3个值组成,所以大小是3。
- 第三个参数指定数据的类型,这里是GL_FLOAT(GLSL中vec*都是由浮点数值组成的)。
- 第四个参数定义我们是否希望数据被标准化(Normalize)。如果我们设置为GL_TRUE,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。
- 第五个参数叫做步长(Stride),它告诉我们在连续的数据中,一个顶点的三维坐标到下一个顶点的三维坐标的间隔。由于下个顶点的三维坐标在3个float之后,我们把步长设置为3 * sizeof(float)。
- 最后一个参数的类型是void*,所以需要我们进行这个奇怪的强制类型转换。它表示位置数据在所开辟的那片显存空间中起始位置的偏移量(Offset)。由于顶点的三维数据就在数组的开头,也就是那片显存空间中的开头,所以这里是 (void*) 0。
- glEnableVertexAttribArray(0)启用了顶点着色器的(location = 0)的属性变量
- 默认情况下,出于性能考虑,所有顶点着色器的属性(Attribute)变量都是关闭的,意味着数据在着色器端是不可见的,哪怕数据已经上传到GPU。只有由glEnableVertexAttribArray启用指定属性,才可在顶点着色器中访问逐顶点的属性数据。数据在GPU端是否可见,即,着色器能否读取到数据,由是否启用了对应的属性决定,这就是glEnableVertexAttribArray的功能,允许顶点着色器读取GPU显存内的数据。
- 参考 《glEnableVertexAttribArray函数》
- 《glEnableVertexAttribArray》