我正在研究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;
你能告诉我这样做的后果吗?
答案 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或类似),您将获得一个新指针,允许您直接使用数据',您必须小心那些映射缓冲器。