i want to update VBO storage with other data, so i want previous storage not to leak. I can't use glMapBuffer as my size of data would be changing. So if I call again glBufferData with new size and data, does it allocate new storage ? what happens with previous memory?
From the OpenGL specification:
BufferData [...] delete[s] any existing data store ...
Related
I am currently working with OpenGL - version 4.4 and I had a question about the glMapBuffer function. In some other API's I have used (E.G. DX12 and VK) you can keep the pointer that the map function returns alive and flush the memory with a separate call instead of deallocating that pointer.
Is there a way to keep this pointer for a longer duration of time and updating the GPU memory without deallocating this pointer calling glUnmapBuffer?
A buffer object which has immutable storage (using gl(Named)BufferStorage from GL 4.4 or ARB_buffer_storage) can be so allocated with the GL_MAP_PERSISTENT_BIT flag. This allows glMap(Named)BufferRange to be given the same flag and thereby persistently map that range of the buffer's storage.
A buffer whose storage is persistently mapped can be used for many buffer operations without being unmapped first. However, the onus of all synchronization for data access is now on the user. So get comfortable with using fences and double-buffering to access/manipulate the data.
let's say that I have the vbo id stored in an int, and I want to resize that buffer; what would I do?
1st choice: use glbufferdata function after binding the buffer.
2nd choice:.use gldeletebuffers then regenerate the buffer and use glbufferdata function after binding the buffer.
So my question is does glbufferdata deallocate the buffer by it self or it didn't?
Just call glBufferData. The glDeleteBuffers / glGenBuffers calls are unnecessary.
Think about it this way: glBufferData creates a new buffer. The glGenBuffers function creates a new name (integer) for a bufffer.
You don't need to deallocate the buffer yourself… not that OpenGL gives you a way to do that. Your OpenGL implementation will do that for you after it is done using the data in the buffer, as long as you don't hold a reference to it.
Is it legal OpenGL to re-allocate the storage of a buffer object with a different size? Yes. Is it a good idea? Well, consider this.
OpenGL has a new(ish) way to allocate storage for a buffer: glBufferStorage. It allocates "immutable" storage. So called because, once allocated, you cannot re-allocate it.
The people behind OpenGL would not have added this immutable buffer allocation method if they thought that reallocating the storage of a buffer object was a good idea.
Let's say I allocate memory for a uniform buffer, like so:
GLuint length(0x1000);
GLuint myBuffer;
glGenBuffers(1, &myBuffer);
glBindBuffer(GL_UNIFORM_BUFFER, myBuffer);
glBufferData(GL_UNIFORM_BUFFER, length, NULL, GL_STATIC_DRAW);
When I am done using the buffer, I would like to make sure that the memory is available again for other buffers. Is it sufficient to call glDeleteBuffers(1,&myBuffer) to achieve that? Because my gut feeling tells me there should be a call symmetrical to glBufferData for that
(like glInvalidateBufferData​ in OpenGL 4), but nothing of the kind is mentioned in the documentation for glBufferData at all (http://www.opengl.org/sdk/docs/man/xhtml/glBufferData.xml)
Not to be a buzz kill, but container objects such as Vertex Array Objects significantly complicate this discussion.
Normally, when you delete a buffer object two key things happen that allow the memory to be reclaimed:
Its name (GLuint ID) is freed up for reuse immediately
The object is unbound from the currently active context
There is a hidden caveat that needs to be observed:
The data store is not actually freed until there are no remaining references to the object in any context.
When you delete a Vertex Buffer Object that is bound to a Vertex Array Object and that Vertex Array Object is not currently bound, the behavior discussed in bullet point 2 does not occur. What happens is the name is freed up, but the VAO continues to reference both the name (which is now invalid) and the data store (which continues to exist). The memory for the buffer object will not be reclaimed until this Vertex Array Object is deleted, or the binding is changed so that it no longer references the original buffer object.
For a more authoritative explanation of the above, I suggest you read Section 5.1.2 and Section 5.1.3 of the OpenGL 4.4 core spec. I will list the most relevant parts of both below.
5.1.2 Automatic Unbinding of Deleted Objects
When a buffer, texture, or renderbuffer object is deleted, it is unbound from any bind points it is bound to in the current context, and detached from any attachments of container objects that are bound to the current context, as described for DeleteBuffers, DeleteTextures, and DeleteRenderbuffers. If the object binding was established with other related state (such as a buffer range in BindBufferRange or selected level and layer information in FramebufferTexture or BindImageTexture), that state is not affected by the automatic unbind. Bind points in other contexts are not affected. Attachments to unbound container objects, such as deletion of a buffer attached to a vertex array object which is not bound to the context, are not affected and continue to act as references on the deleted object, as described in the following section.
5.1.3 Deleted Object and Object Name Lifetimes
[...]
The underlying storage backing a deleted object will not be reclaimed by the GL until all references to the object from container object attachment points, context binding points, or views are removed.
NOTE: This behavior applies to all container objects in OpenGL, memory is not reclaimed until all references to a resource are eliminated. Familiarizing yourself with the necessary conditions (see: 5.1.2) for references to be removed will serve you well in the long-run.
glDeleteBuffers marks the selected buffers for deletion and deallocation, which gets done as soon as no part of OpenGL any longer needs the buffer's data internally. For all practical means glDeleteBuffers frees the buffers.
glTexImage2D function takes a pointer to the Image data.
Now after I have called
glGenTextures,
glBindTexture, and then
glTexImage2D
to use texture in OpenGl.
Can I free the memory allocated to the Image data ptr?
or does opengl Copies the data from the pointer keeps it inside GPU after call
to glTexImage2D or it uses my Image data for texture?
Yes, you're safe to delete your information pointer once you provide it to glTexImage2D, it will just copy it to somewhere closer to the card (such as graphics card memory) and use it from there.
int *p = getImagePixels();
glTexImage2D(GL_TEXTURE..., p);
delete [] p;
Check out this similar question for a discussion on freeing glTexImage2D. It would seem that you can, though.
I have run into an issue I am unsure of how to properly handle. I recently began creating a particle system for my game, and have been using a structure called 'Particle' for my particle data. 'Particle' contains the vertex information for rendering.
The reason I am having issues is that I am pooling my particle structures in heap memory in order to save on large amounts of allocations, however I am unsure of how to use an array of pointers in glBufferData, I am under the impression that glBufferData requires the actual structure instance rather then a pointer to the structure instance.
I know I can rebuild an array of floats each render just to draw my particles, but is there an OpenGL call like glBufferData which I am missing somewhere that is able to de-reference my pointers as it is going through the data I supply? I would ideally like to prevent having to iterate over the array just to copy the data.
I am under the impression that glBufferData requires the actual structure instance rather then a pointer to the structure instance.
Correct. Effectively glBufferData creates a flat copy of the data preseted to it at the address pointed it via the data parameter.
which I am missing somewhere that is able to de-reference my pointers as it is going through the data I supply?
You're thinking of client side vertex arrays, and those are among the oldest features of OpenGL. They're around since OpenGL-1.1, released 19 years ago.
You just don't use a buffer object, i.e. don't call glGenBuffers, glBindBuffer, glBufferData and pass your client side data address directly to glVertexPointer or glVertexAttribPointer.
However I strongly advise to actually use buffer objects. The data must be copied to the GPU anyway, so that it can be rendered. And doing it through a buffer object enables the OpenGL driver to work more efficiently. Also since OpenGL-4 the use of buffer objects is no longer optional.