我目前正在学习openGL,并试图理解VBO和VAO之间的关系。
据我所知,VBO是数据的缓冲区,仅此而已。为了将该数据传递到OpenGL管道中,我需要将该VBO数据绑定到VAO。
这可以通过大量的glVertexAttrib*函数来实现。或者,您可以将VAO设置为通过一组glVertexArray*函数自动从VBO上传数据,最后调用glEnableVertexArrayAttrib。现在,每当我在某些VBO中更改数据时,我所要做的就是调用VAO上的glBindVertexArray将数据从VBO上传到VAO。
对吗?
至少,这就是我理解发生的事情的方式。但是,当我试图在代码中实现它时,我看不到预期的结果(一个三角形在屏幕上变形)。
下面是我创建VAO和VBO的代码:
void startup()
{
static const GLfloat positions[] =
{
1.00f, -0.25f, 0.0f, 1.0f,
1.00f, -0.25f, 0.0f, 1.0f ,
1.00f, -0.25f, 0.0f, 1.0f
};
m_renderingProgram = compile_shaders();
//Create VAO and VBO
glCreateVertexArrays(1, &m_VAO);
glCreateBuffers(1, &m_VBO);
//Set the VAO to automatically update it's data with VBO when it is bound
glNamedBufferStorage(m_VBO, sizeof(positions), positions, 0);
glVertexArrayVertexBuffer(m_VAO, 0, m_VBO, 0, 4);
glVertexArrayAttribFormat(m_VAO, 0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexArrayAttribBinding(m_VAO, 0, 0);
glEnableVertexArrayAttrib(m_VAO, 0);
//Create a named buffer, so we can change the data within easily
glNamedBufferData(m_VBO, sizeof(positions), positions, GL_MAP_WRITE_BIT);
//Upload the data to the VAO
glBindVertexArray(m_VAO);
}这是我的Update()函数代码:
void render(double currentTime)
{
const GLfloat red[] = { (float)sin(currentTime) * 0.5f + 0.5f,
(float)cos(currentTime) * 0.5f + 0.5f,
(float)sin(currentTime) * 0.5f + 0.5f,
1.0f };
const GLfloat newPosition[] =
{
sin(currentTime) * 1.00, sin(currentTime) * -0.25, 0.0, 1.0,
tan(currentTime) * 1.00, tan(currentTime) * -0.25, 0.0, 1.0 ,
cos(currentTime) * 1.00, cos(currentTime) * -0.25, 0.0, 1.0
};
const GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glViewport(sin(currentTime) * 0.4f, cos(currentTime) * 0.5f, 800, 600);
glClearBufferfv(GL_COLOR, 0, black);
//Copy the new position to the buffer
glNamedBufferSubData(m_VBO, 0, sizeof(newPosition), newPosition);
//Use the shader program program
glUseProgram(m_renderingProgram);
glVertexAttrib4fv(1, red);
//Update the VAO with the updated VBO
glBindVertexArray(m_VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
}我希望看到的是一个三角形在屏幕周围变形并改变颜色,但我所看到的只是一个静态的三角形在改变颜色。
发布于 2016-10-09 18:01:48
据我所知,VBO是数据的缓冲区,仅此而已。
缓冲对象是数据的缓冲区。术语"VBO“指的是一个缓冲区对象,该对象(当前)被用作顶点属性的源。缓冲区对象可用于许多其他事情。,您可以以多种不同的方式使用相同的缓冲区。
为了将该数据传递到OpenGL管道中,我需要将该VBO数据绑定到VAO。
技术术语是将缓冲区对象“附加”到VAO。您将一个对象“附加”到另一个对象;将一个对象“绑定”到上下文中。
现在我们已经制定了我们的术语,让我们来谈谈您的代码哪里出错了。
//创建一个命名缓冲区,这样我们就可以轻松地在glNamedBufferData(m_VBO、sizeof(头寸)、positions、GL_MAP_WRITE_BIT)中更改数据;
你不能这么做。您已经用glNamedBufferStorage为该缓冲区对象创建了存储。更重要的是,您为它创建了不可变的存储。这意味着,一旦为缓冲区对象创建了不可变存储,就不能返回并创建新存储。
这很好;实际上,这行是完全多余的,因为您已经创建了存储并上传到它。只要移除这条多余的线路。
//将新位置复制到缓冲器glNamedBufferSubData(m_VBO,0,sizeof(newPosition),newPosition);
这就是我们开始陷入更严重问题的地方。
您看,您创建的缓冲区的存储如下:
glNamedBufferStorage(m_VBO,大量(职位),职位(0));
那个0是标志字段;它指定来自CPU的存储器的 (以及其他事情)。也就是说,不变的存储并不意味着你不能再把东西复制到里面。这就意味着你不能重新分配存储空间。
但你通过了0。这意味着您创建的缓冲区是完全静态的。您告诉OpenGL,您不希望通过CPU进程更改缓冲区的内容。这对于静态缓冲区来说很好,但这显然不是您想要的。
所以,您应该传递一个适当的标志,而不是0。允许glNamedBufferSubData工作的标志称为GL_DYNAMIC_STORAGE_BIT。
https://stackoverflow.com/questions/39946386
复制相似问题