【问题标题】:OpenGL VAO VBO resizeOpenGL VAO VBO 调整大小
【发布时间】:2018-11-05 22:00:15
【问题描述】:

我遇到了一个问题,将不同大小的新内容上传到缓冲区会导致 VAO 行为异常。导致我的对象看起来好像缓冲区大小设置不正确。

1) 我为一个对象生成 VAO 和 VBO

glGenVertexArrays(1, &_vao); // Generate 1 VAO
glGenBuffers(1, &_vbo); // Generate 1 VBO

2) 获取统一变量和属性的位置

3) 像这样设置绑定:

glBindBuffer(GL_ARRAY_BUFFER, _vbo); // Bind VBO first
glBindVertexArray(_vao); // Bind VAO properties to VBO
{
    GLsizei packSize = DIM * sizeof(GLfloat) * 2;

    glEnableVertexAttribArray(_position);
    glVertexAttribPointer(_position, DIM, GL_FLOAT, GL_FALSE, packSize, (GLvoid*)0);

    // And so on ...
}
glBindVertexArray(0); // Unbind VAO
glBindBuffer(GL_ARRAY_BUFFER, 0); // Unbind VBO

4) 然后我加载我的数据:

glBindBuffer(GL_ARRAY_BUFFER, _vbo);
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(float),
                              _vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

问题在我尝试加载不同大小的新数据时开始:

glBindBuffer(GL_ARRAY_BUFFER, _vbo);

glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(float),
                              _vertices.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

而且我的缓冲区大小似乎保持不变。

不过,如果我再次定义并将我的 vao 绑定到 vbo(如在 3-d 步骤中)

glDeleteBuffers(1, &_vbo); 
glGenBuffers(1, &_vbo);
// glBindBuffer... See step 3
// ...

有效。

是否可以避免重新创建新缓冲区? 调整大小的首选方式是什么?

Resize screenshot

为什么会这样?

我使用 OpenGL 版本 4.2.0 Build 10.18.10.3379

【问题讨论】:

  • 我需要上传更多顶点到缓冲区。如果我调用glBufferData,它只会绘制部分顶点,因为缓冲区大小保持不变
  • 我附上了截图。任何想法为什么它可能会出错?
  • 也许我需要以某种方式更新 VAO?

标签: c++ opengl vbo vao


【解决方案1】:

调整大小的首选方式是什么?

调整缓冲区对象大小的首选方法是不调整它们的大小。我是认真的。

OpenGL ARB 创建了一个entire alternate way of allocating storage for buffers唯一的目的是为了防止以后重新分配它们。好的,如果你想成为技术人员,不可变存储的目的是允许持久映射,这需要不可变性,但如果他们只是想要持久映射的缓冲区,他们可以将新 API 限制为仅这些。

确定数据的最大大小(或您想要支持的任何最大值),预先分配它,以及您想要的任何部分。


从技术上讲,您的代码应该可以工作。按照标准,如果你调整缓冲区对象的大小,引用它的东西应该能够看到调整大小的存储。但是由于实现不希望您调整它们的大小,因此高性能应用程序不会调整它们的大小。因此,该代码很少在实际应用程序中进行测试,并且错误可能会持续很长时间。

不要这样做。

【讨论】:

  • 我必须按设计调整缓冲区的大小。我不知道,为什么它会如此奇怪
  • @kupihleba:重新思考你的设计。如果新尺寸小于旧尺寸,则只需在glBufferSubDataglDraw*** 命令中使用更小的参数。如果它更大,我相信您可以将模型分割成多个缓冲区并使用多个 glDraw***calls。
猜你喜欢
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多