问题
I'm studying OpenGL API and I would like to ask you if I can delete a float array of vertices after passing it to OpenGL.
Example code:
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;
Could you tell me consequences about doing it?
回答1:
Yes, absolutely. After the glBufferData()
call returns, you can do anything you want with the data. Overwrite it, delete it, etc.
The consequence is that the OpenGL implementation either has to update the buffer immediately during the call (which is somewhat against the asynchronous way that OpenGL likes to operate in), or create a temporary copy of the data (which is undesirable for performance reasons).
This is a main reason why calls like glMapBufferRange()
were introduced. They avoid the extra data copy that often happens under the hood when glBufferData()
and glBufferSubData()
are used. They have their own synchronization caveats if not used carefully.
There is a very similar case for texture data, where calls like glTexImage2D()
often cause an extra copy of the data in the OpenGL implementation. The performance implications can be worse in that case because texture data is typically much bigger. Apple has an extension for this purpose (APPLE_client_storage), where you can avoid the extra copy by promising to keep the data untouched until it has been consumed by OpenGL.
Almost all OpenGL calls with data pointers as arguments consume the data as part of the call. The only notable exception I can think of is glVertexAttribPointer()
when used without VBOs. This usage is often called "client side vertex arrays", and the data is consumed during the draw call, which can be long after the glVertexAttribPointer()
call. This usage is deprecated, and not available in the OpenGL Core Profile.
回答2:
According to https://www.opengl.org/sdk/docs/man/html/glBufferData.xhtml this function creates "a new data store" and "the data store is initialized with data from this pointer".
This means that the data is copied to a new location and it is safe to delete this original data (nothing you do to the original data after calling glBufferData will affect this gl buffer).
You may note that it also states that "the new data store is not mapped", this means you do not yet have 'direct' access to the new buffer. If you later choose to map the buffer (e.g. with glMapBuffer, glMapBufferRange or similar) you will be given a new pointer that allows you to work with the data 'directly', you must be careful with those mapped buffers.
来源:https://stackoverflow.com/questions/30416086/can-i-delete-a-float-array-when-i-have-used-glbufferdata