OpenGL - How can I delete vertices from a Vertex Array Buffer? - opengl

My current implementation of removing vertices from the buffer is by copying the portions of the buffer before and after the section of vertices I want to remove, into a new buffer.
However this process becomes very slow when the buffer size increases.
So is there a way to just remove the vertices and have the vertices after them take their place in the buffer?

Related

Using Index buffers in DirectX 11; how does it know?

Let's say I create two vertex buffers, for two different meshes.
(I'm assuming creating separate buffers for separate meshes is how it's usually done)
Now, let's say I want to draw one of the meshes using an index buffer.
Looking at the book Practical Rendering and Computation with Direct3D 11 it doesnt seem like the creation of an index buffer in any way references a vertex buffer, so how does the index buffer know (during input assembly) what vertex buffer to act on?
I've done some googling without answers, which leads me to assume there's something obvious about it that I'm missing.
You are right, index buffers do not reference specific vertex buffers. During DrawIndexed active index buffer is used to supply indices into active vertex buffers (the ones you set using SetIndexBuffer/SetVertexBuffers).
Indeed, Index Buffers and Vertex Buffers are completely independent.
Index buffer will know about VertexBuffer at draw time (eg: when both as bound to the pipeline)
You can think of Index Buffer as a "Lookup Table", where you keep a list or elements indices to draw.
That also means you can attach two completely "logically unrelated" buffers to the pipeline and draw it, nothing will prevent you from doing that, but you will of course have some strange visual results.
Decoupling both has many advantages, here are a few examples:
You can reuse an index buffer (for example, two displaced grids with identical resolution can share the same index buffer). That can be a decent memory gain.
You can draw your Vertex buffer on it's own and do some processing per vertex (draw a point list for sprites for example, or apply skinning/displacement into a Stream Output buffer , then draw the resulting vertex buffer using DrawIndexed)
Both Vertex/Index buffers can also be bound as ByteAddressBuffer, so you can also process your geometry in Compute Shader, and build another optimized index buffer, with culled triangles for example, then process the Indexed Draw with the optimized buffer. Applying those culls in with indices instead of vertices is often faster than vertex, as you will move much less memory.
This is a niche case, but sometimes I have to draw a mesh as a set of triangles, but then draw as a set of lines (some form of wireframe). If as example, you take a single Box, you will not want to draw the diagonals as lines, so I have a shared Vertexbuffer with box vertices, then one IndexBuffer dedicated to draw triangle list, and another to draw line list. In case of large models, this can also be an effective memory gain.

efficient update of GL state given a change to the scene

Suppose we have a scene which consists of a list of n meshes in draw order. The triangle count of each mesh is bounded by a constant (though that constant may be large). Also suppose we have GL state such that all meshes can be rendered with a single draw call (glDrawArrays/Elements).
Given a change to the scene, which may consist of:
Inserting a mesh in the list
Removing a mesh from the list
Changing the geometry of the mesh (which may include changing its triangle count)
Is there a O(1) way to update GL state for a single change to the scene?
Because of the draw-order and single-draw-call constraints, the meshes must be laid out linearly in a VBO in that order. Thus, if a mesh is inserted in the list, the VBO must be resized by moving data, which is not O(1).
This isn't really an OpenGL problem. The work complexity has to do with how you model geometry, which happens well before you start trying to shove it into a GPU.
But there are some GL-specific things you can think about:
Separate vertex array order from draw order by using an index buffer and a DrawElements call. If you're drawing multiple entities out of one vertex buffer and you expect them to change, you can leave some padding in the vertex buffer and address vertices by index.
Think about how you're getting that vertex data to the GPU if it's changing every frame. For example, with double- buffering or MapBufferRange, the CPU can work on filling a buffer with new vertex data for the next frame while the GPU draws the current frame from a different buffer (or range).
The work you do to arrange/modify vertices every frame still can't be O(1). GPU work (and CPU/GPU transfers) tends to be thought of more in ms than order analysis terms, but there are things you can to minimize time.

OpenGL Updating VBO Data with a different size

I'm displaying text from Bitmap Fonts on screen with OpenGL, and I'm creating a VBO for vertexes, another for indexes and one for UVs.
I get a string value, and I create a single vertex, uv and index data from all the characters so I only have 1 draw call.
Now I'm trying to figure what to do when that string changes.
If it's the same length of the previous string, I can use glBufferData() and glBufferSubData(), but what should I do if it's a different size?
Can I bind the VBO, call glBufferData() with a different size and upload the new data?
Or should I just delete the VBO and create a new one?
What's the proper way to deal with this?
Allocate a bigger buffer then you need and map subranges so the driver doesn't have to reallocate the memory every time the string changes.

DX10+ multiple vertex buffers, single index buffer

I'm a bit confused as to why you can set active an array of vertex buffers but only one index buffer? Could that one index buffer address the vertices from all the vertex buffers? And if so how would i specify which buffer which index belongs to?
Another question i have is that since i'm using indexed triangle lists, the index data is roughly the same size as vertex data per mesh. I was thinking about creating one index buffer per one vertex buffer. I will be dynamically adding meshes until one of the buffers runs out at which point another pair is created. Inevitably by doing this, one of the buffers in the pair will always fill up before the other one and that leftover space will never get used. Does that space actually get marked as reserved in the gpu?
Like for instance, could i fit 4 buffers that contain 32MB of data but are created with byte width of 64MB into 128MB of vram?
The same indices must be used with all vertex buffers at the same time. The purpose of this is to allow different vertex buffers to contain different components of the vertex data. For example, you might decide store the positions in one vertex buffer and the texture coordinates in a second buffer. The zeroth index would access the first position from the first vertex buffer and the first texture coordinate from the second.
This would save bandwidth if you wanted to update the texture coordinates every frame but never change the positions.
Multiple vertex buffers are also used in instancing.
When you create a vertex or index buffer, you specify the size of the buffer. This amount of memory is then reserved in video ram and cannot be used by anything else.
So if I understand your question, no you can't fit four 64mb buffers into 128 mb of ram.

OpenGL: Buffer object performance issue

I have a question related to Buffer object performance. I have rendered a mesh using standard Vertex Arrays (not interleaved) and I wanted to change it to Buffer Object to get some performance boost. When I introduce buffers object I was in shock when I find out that using Buffers object lowers performance four times. I think that buffers should increase performance. Does it true? So, I think that I am doing something wrong...
I have render 3d tiled map and to reduce amount of needed memory I use only a single tile (vertices set) to render whole map. I change only texture coordinates and y value in vertex position for each tile of map. Buffers for position and texture coords are created with GL_DYNAMIC_DRAW parameter. The buffer for indices is created with GL_STATIC_DRAW because it doesn't change during map rendering. So, for each tile of map buffers are mapped and unmapped at least one time. Should I use only one buffer for texture coords and positions?
Thanks,
Try moving your vertex/texture coordinates with GL_MODELVIEW/GL_TEXTURE matrices, and leave buffer data alone (GL_STATIC_DRAW alone). e.g. if tile is of size 1x1, create rect (0, 0)-(1, 1) and set it's position in the world with glTranslate. Same with texture coordinates.
VBOs are not there to increase performance of drawing few quads. Their true power is seen when drawing meshes with thousands of polygons using shaders. If you don't need any forward compatibility with newer opengl versions, I see little use in using them to draw dynamically changing data.
If you need to update the buffer(s) each frame you should use GL_STREAM_DRAW (which hints that the buffer contents will likely be used only once) rather than GL_DYNAMIC_DRAW (which hints that they will be but used a couple of times before being updated).
As far as my experience goes, buffers created with GL_STREAM_DRAW will be treated similarly to plain ol' arrays, so you should expect about the same performance as for arrays when using it.
Also make sure that you call glMapBuffer with the access parameter set to GL_WRITE_ONLY, assuming you don't need to read the contents of the buffer. Otherwise, if the buffer is in video memory, it will have to be transferred from video memory to main memory and then back again (well, that's up to the driver really...) for each map call. Transferring to much data over the bus is a very real bottleneck that's quite easy to bump into.