Results 1 to 9 of 9

Thread: Updating a VBO

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2011
    Location
    California, U.S.
    Posts
    19

    Updating a VBO

    I have a large vertex buffer object and I only want to update a small portion of it. Google tells me that this is a job for the glBufferSubData function but I'm not sure how to use it. I've been able to replace data in a array of vertices, but I'd rather leave them alone and work with the indices instead. However, trying to use glBufferSubData on my index VBO causes the entire array to go blank (my object disappears, anyway) and so I've just been recreating the entire array for each update (very slow). Here's my code for updating (written in Java with the lwjgl lib):

    Code :
    public int updateChunk(int indexVboId, int totalVerts) {
     
    	// Bind and buffer VBO
    	ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, indexVboId);
    	ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB,
    		intSize*totalVerts, ARBVertexBufferObject.GL_STREAM_DRAW_ARB);
     
    	// Map VBO
    	ByteBuffer indexBuffer = ARBVertexBufferObject.glMapBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, 
    		ARBVertexBufferObject.GL_WRITE_ONLY_ARB, intSize*totalVerts, null);
     
    	// start replacing data at the beginning of the array (0)
    	GL15.glBufferSubData(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, 0, indexBuffer);
     
    	// replace first 4 indices with these
    	indexBuffer.putInt(0).putInt(1).putInt(2).putInt(3).putInt(4);
     
    	indexBuffer.flip();
     
    	//unmap and unbind
    	ARBVertexBufferObject.glUnmapBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB);
    	ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
     
    	return 1;
     
    }

    Does anything look wrong here? Why would this code work for an array of vertices but not indices?

    Also, how would I remove indices from the VBO?

  2. #2
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,672

    Re: Updating a VBO

    Let me make sure I understand what you're doing here.

    You have a buffer object. Then you map it with glMapBuffer. Then you take the pointer you mapped, the one that you told OpenGL would be only used for writing (GL_WRITE_ONLY_ARB), and use it as the input to glBufferSubData.

    If you ask for a write-only pointer from glMapBuffer, you must actually treat it like a write-only pointer. By not reading from it.

    Furthermore, I don't see why you're calling glBufferSubData at all (which I'm fairly sure is illegal for mapped buffers). The point of mapping a write-only pointer to the buffer is, presumably, to change the contents of the buffer. Thus, even if the glBufferSubData call actually worked (and it doesn't, since even if you could glBufferSubData to mapped buffers, you're still reading from a write-only pointer), it would do nothing. It would just be copying the data from the mapped pointer to itself.

  3. #3
    Junior Member Newbie
    Join Date
    Apr 2011
    Location
    California, U.S.
    Posts
    19

    Re: Updating a VBO

    I pretty much guessed on how to use glBufferSubData here, since I can't find any tutorials on using it or any sample code for updating a VBO. I figured that the last argument in glBufferSubData indicated which buffer to replace data in (instead of the actual data), but I guess binding the buffer does this?

    My goal is to replace, add, and subtract indices from the buffer. What would be the simplest and most efficient way to do this?


    Edit: I think I might have figured it out. Should I create a new temporary buffer, map data to it (allow it to be read and written to) and then sub that temporary buffer into my main buffer?

  4. #4
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,672

    Re: Updating a VBO

    since I can't find any tutorials on using it or any sample code for updating a VBO.
    *cough*

    My goal is to replace, add, and subtract indices from the buffer. What would be the simplest and most efficient way to do this?
    If you intend to "add" indices, then you first need to figure out what the maximum number of indices will be and allocate a buffer that big. Buffer objects are like arrays in C/C++; it's not getting any bigger than what you asked for.

    There is no "simplest and most efficient" way. There is a simple way to do it, and there may be a "most efficient" way which is both potentially hardware-dependent and almost certainly is not the simple way.

    The simple way is just to change the data however you see fit. You can use glMapBuffer to map the data and change the values in the pointer you get. Or you can use glBufferSubData (aka: memcpy) to write to the buffer.

  5. #5
    Junior Member Newbie
    Join Date
    Apr 2011
    Location
    California, U.S.
    Posts
    19

    Re: Updating a VBO

    Ok, thank you for that link (and replies). I understand how adding data would work and I have allocated enough memory. However, subtracting data seems like it would be more difficult. My first idea would be to use glBufferSubData to replace a portion of the big buffer with an empty buffer, but then the big buffer would have a dataless hole in it (and I assume cause a crash or something). Do I need to redefine the entire buffer just to get rid of that gap (defeating the purpose of using glBufferSubData)?

  6. #6
    Junior Member Newbie
    Join Date
    Apr 2011
    Location
    California, U.S.
    Posts
    19

    Re: Updating a VBO

    I'm still having trouble getting glBufferSubData to work. I've made my method for updating very simple now but it crashes the program (EXCEPTION_ACCESS_VIOLATION) as soon as it's called:

    Code :
    	public int updateChunk(int bigBuffer, int smallBuffer) {
     
    		// get pointer to small buffer
    		ByteBuffer data = ARBVertexBufferObject.glGetBufferPointerARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, smallBuffer);
     
    		// bind big buffer, sub data into it, then unbind
    		ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, bigBuffer);
    		GL15.glBufferSubData(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, 0, data);
    		ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
     
    		return 1;
     
    	}

    Is there anything wrong with this code? I know that the small buffer is indeed smaller than the big buffer, and that they are both element_arrays that hold Int values.

  7. #7
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,161

    Re: Updating a VBO

    I don't know if this has anything to do with it but you have a mixture of ARB function calls and core GL function calls. Are both of these initialised?
    Why not use the core functions always and be consistent?

  8. #8
    V-man
    Guest

    Re: Updating a VBO

    ARBVertexBufferObject.glGetBufferPointerARB(ARBVer texBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, smallBuffer);

    should be

    ARBVertexBufferObject.glGetBufferPointerARB(ARBVer texBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, ARBVertexBufferObject.GL_BUFFER_MAP_POINTER);


    PS: you can only call that on a VBO that you have glMapBuffer. But them glMapBuffer gives you the pointer so you don't really need glGetBufferPointerARB

    I'm assuming you are using LWJGL

  9. #9
    Junior Member Newbie
    Join Date
    Apr 2011
    Location
    California, U.S.
    Posts
    19

    Re: Updating a VBO

    Alright, I've replaced the glGetBufferPointer call with glMapBuffer and glBufferSubData is now working correctly!

    The problem now is that I don't know how to subtract data from the big buffer. Adding data was easy because all I had to do was set the offset in glBufferSubData to the last vertex in the big buffer, but you can't subtract data from the big buffer simply by replacing part of the big buffer with an empty buffer. Is there a way to remove vertices without remapping the entire buffer?

    @BionicBytes: I thought using ARB calls was the only way to work with VBOs (learned pretty much everything I know from one example file), but I just looked at the OpenGL function lists and saw that they're available in the core as well. Thanks for pointing that out.

Similar Threads

  1. Updating shader from 120 to 330
    By abdd0e77 in forum OpenGL: Basic Coding
    Replies: 3
    Last Post: 03-17-2013, 09:01 PM
  2. My First Code - Not Updating
    By beakie in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 08-26-2012, 07:37 AM
  3. Updating Ortho vs Updating Vertices
    By Beiufin in forum OpenGL: Basic Coding
    Replies: 4
    Last Post: 06-26-2012, 07:44 AM
  4. Updating Normals.
    By glAntony in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 11-02-2004, 04:18 PM
  5. frame updating
    By JazzD in forum OpenGL ES
    Replies: 4
    Last Post: 10-20-2004, 09:50 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean