Modify Buffer in OpenGL - performance

I have a modifiable terrain which is stored in a vertex buffer. Because of its large number of vertices, I do not want to upload all vertices again every time the terrain is modified. What I do by now is to split the terrain into smaller chunks so that I only have to recreate the buffer of the area containing the modification of the terrain.
But how can I just add or remove some vertices of an existing buffer?

You can either use glBufferSubData as datenwolf said, or if you are planning on making a lot of modifications and accessing randomly the data, you may want to map the buffer into client memory using glMapBuffer and later unmap it with glUnmapBuffer. (Then, based on the access specifiers you chose, you can edit the data as a C array)

You can change data in an existing buffer using glBufferSubData

Related

Why Directx11 doesn't support multiple index buffers in IASetIndexBuffer

You can set multiple vertex buffers with IASetVertexBuffers,
but there is no plural version of IASetIndexBuffer.
What is the point of creating (non-interleaved) multiple vertex buffer datas if you wont be able to refer them with individual index buffers
(assume i have a struct called vector3 with 3 floats x,y,z)
let say i have a model of human with 250.000 vertices and 1.000.000 triangles;
i will create a vertex buffer with size of 250.000 * sizeof(vector3)
for vertex LOCATIONS and also,
i will create another vertex buffer with size of 1.000.000 * 3 *
sizeof(vector3) for vertex NORMALS (and propably another for diffuse
texture)
i can set these vertex buffers like:
ID3D11Buffer* vbs[2] = { meshHandle->VertexBuffer_Position, meshHandle->VertexBuffer_Normal };
uint strides[] = { Vector3f_size, Vector3f_size };
uint offsets[] = { 0, 0 };
ImmediateContext->IASetVertexBuffers(0, 2, vbs, strides, offsets);
how can i set seperated index buffers for these vertex datas if IASetIndexBuffer only supports 1 index buffer
and also (i know there are techniques for decals like creating extra triangles from the original model but)
let say i want to render a small texture like a SCAR on this human model's face (let say forehead), and this scar will only spread through 4 triangles,
is it possible creating a uv buffer (with only 4 triangles) and creating 3 different index buffers for locations, normals and UVs for only 4 triangles but using the same original vertex buffers (same data from full human model). i dont want to create tonnes of uv data which will never be rendered beside characters forehead (and i dont want to re-use, re-create vertex position datas for this secondary texture layers (decals))
EDIT:
i realized i didnt properly ask a question, so my question is:
did i misunderstand non-interleaved model structure (is it being used
for some other reason instead having non-aligned vertex components)?
or am i approaching non-interleaved structure wrong (is there a way
defining multiple non-aligned vertex buffers and drawing them with
only one index buffer)?
The reason you can't have more than on Index buffer bound at a time is because you need to specify a Fixed number of primitives when you make a call to DrawIndexed.
So in your example, if you have one index buffer with 3000 primitives and another with 12000 primitives, the pipeline would have no idea how to match the first set to the second set.
If is generally normal that some vertex data (mostly position) eventually requires to be duplicated across your vertex buffer, since your buffers requires to be the same size.
Index buffer works as a "lookup table", so your data across vertex buffers need to be consistent.
Non interleaved model structure has many advantages:
First using separate buffers can lead to better performances if you need to draw the models several times and some draws do not require attributes.
For example, when you render a shadow map, you will need to access only positions, so in interleaved mode, you still need to bind a large data structure and access elements in a non contiguous way (Input Assembler does that). In case of non interleaved data, Position will be contiguous in memory so fetch will be much faster.
Also non interleaved allows to more easily do some processing on some attributes, it is common nowadays to perform some displacement or skinning in a compute shader, so in that case you can also easily create another Position+Normal buffer, perform your skinning on those and attach them in the pipeline once processed (And you can keep UV buffer intact).
If you want to draw non aligned Vertex buffers, you could use Structured Buffers instead (and use SV_VertexID and some custom lookup tables in your shader code).

OpenGL VAO: a shared instancing VBO among non-shared

I have different meshes with different VBOs, some may have normals, some not, etc. Every mesh also has its VAO with all VBOs being bound.
Then I draw all meshes with instancing. I plan to use a shared global VBO of mat4 to store dynamically calculated transformations every frame. Every VAO also needs to point at this shared VBO additionally. Also the number of every mesh instances may vary.
But I guess we want to reduce the amount of data uploading commands to GPU, that's why I want to accumulate all the matrices in a contiguous memory and send it in a single glBufferSubData command.
Different batches of different instanced meshes want to use different segments of the shared VBO to read the matrices from. So I need to update VAOs each frame as well.
The question is: how should I perform this in a better way? And is such an architecture actually a good one? I guess I should use glBindVertexBuffer for the shared VBO on each VAO, so I update the offset and size of the segments, and VAOs are lightweight, but is it really a standard solution?
You should not be concerned with updating VAOs. In fact, you should not have one VAO per mesh at all; have one VAO per vertex format (aka: the stuff set by glVertexAttribFormat and glEnable/DisableVertexAttrib), and try to make all of your meshes use the same vertex format. Setting buffer binding state is much cheaper than setting vertex format state.
So the idea ought to be that you bind a VAO for a vertex format, then iterate through all of the objects that use that format, using glBindVertexBuffer as needed for their individual data.

OpenGL batching and disabling objects

I'm combining the vertex data that has the same format in a single VBO, assigning vertex attributes based on a material that these object use and rendering them with a single glDrawArrays() call.
It is all working out great until I have to disable some objects (say object1) from being rendered at runtime. Is this even possible, assuming I've already set up all the vertex attributes and stuff? Would it be better not to use batching at all, and have vbo/vao per object (then, if an object's disabled, just don't call glDraw*() on it) ?
Batching requires putting all of your data in one buffer, but batching is not limited to that. Batching is about reducing the number of draw calls. Putting your data in one buffer is necessary for that, but not sufficient.
Putting all of your vertex data in one buffer alone has performance advantages, relative to having to switch buffers and vertex formats. You don't need to go all the way to batching everything into a single draw call to improve performance over using a buffer for each individual object.
In OpenGL, as discussed in this video, the primary cost of multiple draw calls isn't the draw call itself. It's the state changes you usually do between draw calls.
You've put your vertex data in the same buffer, and you must have managed to eliminate stage changes between objects if you could render everything with one draw call. At that point, you've already gained most of the performance you're going to. Accept that and move on to other lower-hanging fruit.

Omit list of vertices in a buffer

I have a buffer which contains vertex information which I use for glDrawArrays. The triangles in the buffer are spaced around the screen as sprites. I would like somehow to omit drawing some of those items without having to update the entire buffer.
Is there someway I can modify the vertices so that nothing will be drawn when they are encountered? I don't wish to completely remove it since that involves updating the entire buffer again.
I'm targetted some devices with only OpenGL ES 2.0 support.
You can use glDrawElements and provide an indices buffer.
glDrawArrays has offset and count parameters. You can use these parameters to draw only the elements within the buffer that are visible. This results in multiple glDrawArray calls for a single buffer.
An other alternative is to skip the triangles within the shader using the discard command in the fragment shader. In this case you have to provide information about which triangles need to be rendered to the shader (e.g. by uniforms)

Performance of using a large number of small VBOs

I wanted to know whether OpenGL VBOs are meant to be used only for large geometry arrays, or whether it makes sense to use them even for small arrays. I have code that positions a variety of geometry relative to other geometry, but some of the "leaf" geometry objects are quite small, 10x10 quad spheres and the like (200 triangles apiece). I may have a very large number of these small leaf objects. I want to be able to have a different transform matrix for each of these small leaf objects. It seems I have 2 options:
Use a separate VBO for each leaf object. I may end up with a large number of VBOs.
I could store data for multiple objects in one VBO, and apply the appropriate transforms myself when changing the data for a given leaf object. This seems strange because part of the point of OpenGL is to efficiently do large numbers of matrix ops in hardware. I would be doing in software something OpenGL is designed to do very well in hardware.
Is having a large number of VBOs inefficient, or should I just go ahead and choose option 1? Are there any better ways to deal with the situation of having lots of small objects? Should I instead be using vertex arrays or anything like that?
The most optimal solution if your data is static and consists of one object would be to use display lists and one VBO for only one mesh. Otherwise the general rule is that you want to avoid doing anything other than rendering in the main draw loop.
If you'll never need to add or remove an object after initialization (or morph any object) then it's probably more efficient to bind a single buffer permanently and change the stride/offset values to render different objects.
If you've only got a base set of geometry that will remain static, use a single VBO for that and separate VBOs for the geometry that can be added/removed/morphed.
If you can drop objects in or remove objects at will, each object should have it's own VBO to make memory management much simpler.
some good info is located at: http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
I think that 200 triangles per one mesh is not so small number and maybe the performance with VBO for each of that meshes will not decrease so much. Unfortunately it is depended on hardware spec.
One huge buffer will no gain huge performance difference... I think that the best option would be to store several (but not all) objects per one VBO.
renderin using one buffer:
there is no problem with that... you simply have one buffer that is bound and then you can use glDrawArrays with different parameters. For instance if one mesh consists of 100 verts, and in th buffer you have 10 of those meshes you can use
glDrawArrays(triangles, 0, 100);
glDrawArrays(triangles, 100, 100);
glDrawArrays(triangles, ..., 100);
glDrawArrays(triangles, 900, 100);
in that way you minimize changing buffers and still you are able to render it quite efficient.
Are those "small" objects the same? do they have the same geometry but different transformations/materials? Because maybe it is worth using "instancing"?

Resources