首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当glBindVertexArray未更新VAO时

当glBindVertexArray未更新VAO时
EN

Stack Overflow用户
提问于 2016-10-09 17:22:20
回答 1查看 207关注 0票数 0

我目前正在学习openGL,并试图理解VBO和VAO之间的关系。

据我所知,VBO是数据的缓冲区,仅此而已。为了将该数据传递到OpenGL管道中,我需要将该VBO数据绑定到VAO。

这可以通过大量的glVertexAttrib*函数来实现。或者,您可以将VAO设置为通过一组glVertexArray*函数自动从VBO上传数据,最后调用glEnableVertexArrayAttrib。现在,每当我在某些VBO中更改数据时,我所要做的就是调用VAO上的glBindVertexArray将数据从VBO上传到VAO。

对吗?

至少,这就是我理解发生的事情的方式。但是,当我试图在代码中实现它时,我看不到预期的结果(一个三角形在屏幕上变形)。

下面是我创建VAO和VBO的代码:

代码语言:javascript
复制
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()函数代码:

代码语言:javascript
复制
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);
}

我希望看到的是一个三角形在屏幕周围变形并改变颜色,但我所看到的只是一个静态的三角形在改变颜色。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39946386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档