T
VAO and VBOI'll tell you about VAO and VBO at first. VAO https://www.opengl.org/wiki/Vertex_Specification#Vertex_Array_Object the facility, but only links to one or more VBOs and other conditions necessary for the construction of the facility. So we'll work with VBO. If several top attributes are stored in several VBOs, all of them will have to be managed separately. The VBO change will be readily available to users of the associated VAO.RemovalLet's start with an extreme simple case: when the peaks are removed from the end, there's no need to change anything. Just drawing a challenge.glDrawElements(GL_TRIANGLE_STRIP, num_elements - 3, GL_UNSIGNED_BYTE, nullptr);
insteadglDrawElements(GL_TRIANGLE_STRIP, num_elements, GL_UNSIGNED_BYTE, nullptr);
If the removed peaks are stored at the beginning or in the middle, the task is disposal is similar to the task of removing elements from the middle of the conventional body in memory. For example, if there is a mass:int a[] = {1,2,3,4,5,6};
We cannot remove elements 2 and 3 from it without leaving zero or any special meanings indicating that the data are removed. In order not to leave these values, we can either re-emergize the memory to a new set of necessary lengths and collate the values there or collate 5 and 6 to place 2 and 3 and remember that now the length of the mass is 4 instead of 6. The memory left behind under two elements will be wasted, but with 40000 elements, it can be ignored.The same can be applied to the mass in the videotape:We can call glBufferData for a new buffer.It is possible to replace a piece of data from the beginning of the removed piece to the end of the buffer with new values by glBufferSubData without forgetting the decrease of num_elements.Remove the copying inside the buffer https://www.opengl.org/wiki/Buffer_Object#Copying because memory regions should not intersect when copying inside the buffer.The methods listed can make sense when changing/removaling a large number of data, but, as you have noticed, they're completely unsuitable three points out of 40000. I mean, you can't completely remove the points, and you're gonna have to find a bypass.Possible solutionFunction https://www.opengl.org/wiki/GLAPI/glBufferSubData Allows the decomposition and length of the data to be replaced. It can therefore rewrite both the entire buffer and any part thereof, even one element. If we need to remove 3 of the 40000 points from the model, you don't have to remove them from the buffer! Let's just rewrite their values to the right next door. For example, have a lamb of 8 peaks on the plane: 2 3 5 7
/-------\ /\ /----8
/ \ / \ /
/ \/ \/
/1 4 6
If we do the top of 5 equal to 6, then we will have the same effect as when the top 5 is removed: there will be a cut, visually connecting the top 4 and 6, and the length of the 5-6 cut will be zero: 2 3 7
/-------\ /----8
/ \ /
/ \------/
/1 4 5,6
In the choice between the overexpenditure of memory by three peaks or the time spent on re-establishing the buffer by 40000 peaks, it is logical to give preference to the first option.Usage patternFrom your description, it seems that you'll be seldom removed, that is, not on every frame. The buffer will be used only to remove the graphs but not to transform the feedback and other such tricks. If so, in creating the buffer, don't forget the last glBufferData argument. GL_DYNAMIC_DRAW♪ However, without performance tests of a specific annex, there is no clear recommendation. With very rare updating of the buffer GL_STATIC_DRAW It could be faster. On the contrary, with a very often best choice, GL_STREAM_DRAW♪Comment from the authorA little example. Thank you, everything's up. In addition to your response, I would like to add a demo code for one of the options you listed:GLfloat* vertices = new GLfloat[9]; // элемент из 3 вершин
...
GLuint pos_Buf;
glGenBuffers(1, &pos_Buf);
// передаем данные в GPU
glBindBuffer(GL_ARRAY_BUFFER, pos_Buf);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(float), vertices, GL_STATIC_DRAW);
// освободить память после переноса данных в GPU
delete [] vertices;
...
// Если надо изменить, например, седьмой элемент массива:
// Пример изменения данных, размещенных в графической памяти
// Вариант - glUnmapBuffer
// ----------------------------------------------------
glBindBuffer(GL_ARRAY_BUFFER, pos_Buf);
data = (GLfloat *) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
data[7] = 0.4f;
glUnmapBuffer(GL_ARRAY_BUFFER);
...
// Вариант 2 - glBufferSubData
// ----------------------------------------------------
glBindBuffer(GL_ARRAY_BUFFER, pos_Buf);
GLintptr offset = 7*sizeof(float);
float pos_SubD[] = {0.0f};
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(float), pos_SubD);
...
// В нужный момент этот VBO можно удалить
glDeleteBuffers(1, &vboId);