opengl中VAO和VBO的关系

opengl中VAO和VBO的关系

什么是VBO

VBO(vertex buffer object)顶点缓冲对象,用来存储顶点信息,并把这些信息发送给顶点着色器。
VBO是CPU和GPU传递信息的桥梁我们把数据存入VBO是在CPU上操作,VBO会自动将数据送至GPU。送至GPU不需要任何人为操作。关于VBO另外补充解释:使用VBO管理内存(GPU上储存顶点数据),使用VBO好处就是将内存一次性发送大批数据到显卡,而不是每次发送一个顶点数据。从CPU把这些数据发送到显卡相对较慢,所以只要可能就尝试尽量一次性尽可能多的数据。发送到显卡的内存后,顶点着色器几乎能立即访问顶点,过程比较快。

什么是VAO

VBO将顶点数据传送至GPU只是一堆数字,要怎么向GPU解释它们呢,就需要VAO了。有的读者会奇怪,顶点数据无非是一个个三维坐标,三个为一组,传就传了,为什么还需要解释呢?那么我们来看下面这个VBO中的数据:

float vertices[] = {
    // 位置              // 颜色              //纹理坐标
     0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,   1.0f, 1.0f // 右下
    -0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,   1.0f, 0,0f // 左下
     0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f    0.0f, 0.0f // 顶部
};`

由以上数据可以看出顶点数据并不是三个为一组的三维坐标,也有两个数字一组的。

如果我们向VBO中传入了以上buffer,并且VBO把它们送入了GPU。

然而,顶点着色器不知道该如何解释这些数字,到底是把它们3个一组,还是先3个一组、后2个一组,或者是3个、2个、3个?

GPU并不知道。这就需要VAO来告诉GPU怎么解释这些缓存数据了,如下:

	//vertex coord 顶点坐标属性
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);
    // color attribute 颜色属性
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
    glEnableVertexAttribArray(1);
    // texture coord attribute 纹理坐标属性
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
    glEnableVertexAttribArray(2);

上面看似解释了顶点坐标属性、颜色属性、纹理坐标属性三段,其实它们同时绑定在一个VAO中。

总结

VBO是顶点缓冲对象,是CPU和GPU中间的桥梁,开发者只需要将数据存入VBO中,VBO自动将数据送入GPU中。而VBO传输的只是一堆数字,GPU怎么解释这些顶点数据,就需要VAO来解释。

补充

一个VAO可以解释多个VBO,这就涉及到OpenGL的上下文知识:一个完整的OpenGL程序相当于一个容器,我们在用到VAO、VBO时,需要先绑定(Bind操作)、再使用,没有经过绑定的VAO/VBO是不起作用的

绑定VAO,告诉OPenGL用这个VAO来解释这个VBO

绑定第一个VBO, 向VBO中写入数据,告知VAO该如何解释VBO
解绑第一个VBO

绑定第二个VBO, 向VBO中写入数据,告知VAO该如何解释VBO
解绑第二个VBO
//========================生成VBO,VAO==========================
	unsigned int VBO[2], VAO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(2, VBO);

//=========================绑定VAO===============================
	glBindVertexArray(VAO); 
//===============================================================

//=======================绑定第一个VBO============================
	glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
	glBufferData(GL_ARRAY_BUFFER, sphereVertices.size() * sizeof(float), &sphereVertices[0], GL_STATIC_DRAW); //向第一个VBO中写入数据
//===============================================================

//================告知VAO该如何解释第一个VBO的信息=================
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
//===============================================================

//=======================解绑第一个VBO===========================
	glBindBuffer(GL_ARRAY_BUFFER, 0);
//===============================================================

//=======================绑定第二个VBO============================
	glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
	glBufferData(GL_ARRAY_BUFFER, sizeof(texVertrices), texVertrices, GL_STATIC_DRAW);//向第二个VBO中写入数据
//===============================================================

//================告知VAO该如何解释第二个VBO的信息=================
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(1);
//=============================================================

好辣,今天就到这里了~

Qt OpenGL提供了一种实现高效渲染的机制,它使用了VAO(Vertex Array Object)和VBO(Vertex Buffer Object)技术。 VAO是一种对象,用于存储顶点数据、顶点属性以及它们之间的关联关系。它可以理解为一个顶点属性的容器。通过使用VAO,我们可以将顶点数据存储在显存,而不是每次渲染时都从CPU传输顶点数据到显存,从而提高渲染的效率。 VBO是一个存储顶点数据的缓冲区对象。通过将顶点数据存储在VBO,我们可以将数据一次性地传输到显存,并且可以高效地管理和使用这些数据。同时,VBO还可以提供顶点缓存和索引缓存功能,用于顶点的重用和图元的索引。 Qt OpenGL提供了许多方便的API来操作VAOVBO。我们可以使用QOpenGLVertexArrayObject类来创建和管理VAO,通过调用QOpenGLBuffer类的相关方法来创建和管理VBO。例如,我们可以使用QOpenGLVertexArrayObject::bind()和QOpenGLVertexArrayObject::release()方法来绑定和释放VAO,使用QOpenGLBuffer::bind()和QOpenGLBuffer::release()方法来绑定和释放VBO。 使用VAOVBO可以大大简化OpenGL代码的编写,并且能够有效提高渲染效率。我们可以将需要渲染的数据一次性地传输到显存,并且设置好相应的渲染状态,然后每次渲染时只需要绑定VAO进行渲染即可,不需要重复的数据传输和状态设置操作。 综上所述,Qt OpenGLVAOVBO技术可以帮助我们实现高效渲染,提高应用程序的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值