我使用glBufferData时可以删除浮点数组吗?

时间:2015-05-23 18:16:20

标签: object opengl buffer vertices

我正在研究OpenGL API,我想问你是否可以在将其传递给OpenGL后删除浮点数组顶点。

示例代码:

GLuint VBO;
float *vertices = new float[2];
vertices[0] = 0.0f;
vertices[1] = 1.0f;

glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

delete[] vertices;

你能告诉我这样做的后果吗?

2 个答案:

答案 0 :(得分:2)

是的,绝对的。 glBufferData()调用返回后,您可以使用数据执行任何操作。覆盖它,删除它等等。

结果是OpenGL实现要么在调用期间立即更新缓冲区(这有点违背OpenGL喜欢操作的异步方式),要么创建数据的临时副本(这对性能不利)原因)。

这是引入glMapBufferRange()等调用的主要原因。它们避免了在使用glBufferData()glBufferSubData()时经常发生的额外数据副本。如果不仔细使用,他们有自己的同步警告。

纹理数据的情况非常相似,其中像glTexImage2D()这样的调用经常会在OpenGL实现中产生额外的数据副本。在这种情况下,性能影响会更糟,因为纹理数据通常要大得多。 Apple有一个扩展用于此目的(APPLE_client_storage),您可以通过承诺在OpenGL使用数据之前保持数据不变来避免额外的副本。

几乎所有使用数据指针作为参数的OpenGL调用都会将数据作为调用的一部分。在没有VBO的情况下使用时,我能想到的唯一值得注意的例外是glVertexAttribPointer()。这种用法通常被称为"客户端侧顶点数组",并且在绘制调用期间消耗数据,这可能在glVertexAttribPointer()调用之后很长时间。此用法已弃用,在OpenGL核心配置文件中不可用。

答案 1 :(得分:1)

根据https://www.opengl.org/sdk/docs/man/html/glBufferData.xhtml,此功能创建了一个新的数据存储"和"数据存储使用来自此指针的数据初始化"。这意味着数据被复制到新位置并且可以安全地删除此原始数据(您对原始数据没有任何操作)调用glBufferData后的数据会影响这个gl缓冲区。)

您可能会注意到它还指出"新数据存储未映射",这意味着您还没有'直接'访问新缓冲区。如果您以后选择映射缓冲区(例如使用glMapBuffer,glMapBufferRange或类似),您将获得一个新指针,允许您直接使用数据',您必须小心那些映射缓冲器。