Unloading vertex buffers in OpenGL
I have an Android live wa开发者_如何学JAVAllpaper that I suspect is leaking memory, probably either textures or vertex arrays. I'm calling glDeleteTextures on my texture IDs, but don't see any sort of equivalent for my vertex buffers. I'd like to be able to be sure both my textures and buffers are getting unloaded by OpenGL, am i missing something?
The documents I've found seem to suggest OpenGL just works it out on its own, but that's not giving me a lot of comfort.
Vertex Arrays and Vertex Buffers are 2 different things, and it's unclear from your question if you indeed use the Vertex Buffer Object (VBO) mechanism to provide vertex data to GL, or if you use client-side arrays.
From GL point of view, a VBO is owned by GL, and requires allocation/deallocation explicitly. This is what a stray cat is talking about. You allocate memory of a VBO with glBufferData, and deallocate either with glBufferData or by deleting the VBO object itself.
Now, if you're not using VBO, then GL copies the data you're passing it on each draw, and does not consider the source memory as its own. In your case, this means a couple of things:
- the source data is up to the client to delete. Since you're using java, and java is a garbage collected language, chances are the only way to get rid of that memory is that java collects it
- the GL implementation often needs to keep a temporary copy of the data (because the GPU will not work on the draw immediately, in a lot of cases). This is totally up to the GL implementation to handle, and you likely have absolutely no control over this.
It's not simply glDeleteBuffers()
?
Point taken. Currently I'm using a native order direct bytebuffer for everything, which I thought got buffered into OpenGL upon use, but maybe I'm wrong. The setup code looks like this:
ByteBuffer bufTCDirect;
bufTCDirect = ByteBuffer.allocateDirect( aNumElements * 2 * ( Float.SIZE >> 3 ) );
bufTCDirect.order( ByteOrder.nativeOrder() );
FloatBuffer bufTC;
bufTC = bufTCDirect.asFloatBuffer();
bufTC.clear();
bufTC.put(tcArrayFromFile); // a float[] array loaded from the model file
bufTC.position(0);
Later on, all I'm doing when I'm told to unload is this:
this.bufTC = null;
this.bufTCDirect = null;
It sounds to me like this is correct, as if these are client side the garbage collector will take care of things from there?
With OpenGL ES2 or newer, keep the buffer location as a field in the class:
int buffers[] = new int[1];
Generate a buffer pointer on the GPU:
glGenBuffers(buffers.length, buffers, 0);
Create the vertex array and load into GPU memory:
FloatBuffer vertexArray = ByteBuffer
.allocateDirect ( 4 * vertexData.length ) // 4 bytes per float
.order ( ByteOrder.nativeOrder ( ) )
.asFloatBuffer ( )
.put ( vertexData );
glBufferData ( GL_ARRAY_BUFFER,
4 * vertexArray.capacity ( ), // bytes per float again
vertexArray,
GL_STATIC_DRAW );
When finished, delete the buffers:
glDeleteBuffers ( 1 , buffers , 0 );
精彩评论