Solución:
El tamaño de cualquier objeto de búfer OpenGL se establece cuando llama glBufferData
. Es decir, OpenGL asignará la cantidad de memoria que especifique en el segundo argumento de glBufferData
(que no figura en el OP). De hecho, si llamas, por ejemplo glBufferData( GL_ARRAY_BUFFER, bufferSize, NULL, GL_DYNAMIC_DRAW );
OpenGL creará un búfer de bufferSize
bytes de datos no inicializados.
Puede cargar cualquier cantidad de datos (hasta el tamaño del búfer) usando glBufferSubData
, glMapBuffer
, o cualquiera de las otras rutinas para pasar datos. La única forma de cambiar el tamaño del búfer es llamar glBufferData
con un nuevo tamaño para el mismo ID de búfer (el valor devuelto por glGenBuffers
).
Dicho esto, siempre puede usar un subconjunto de los datos en el búfer (que sería similar a eliminar vértices), y si renderiza usando glDrawElements
, puede acceder aleatoriamente a los elementos del búfer. Agregar vértices a un búfer requeriría asignar un búfer más grande, y luego necesitaría volver a cargar todos los datos en el búfer.
http://www.opengl.org/wiki/GLAPI/glBufferData
glBufferData crea un nuevo almacén de datos para el objeto de búfer actualmente vinculado al destino. Se elimina cualquier almacén de datos preexistente.
Esto explica una llamada a glBufferData
“reasignará” los datos, el búfer tendrá un nuevo tamaño. Se perderán todos los datos antiguos. Si desea escribir solo en una parte del búfer, use glBufferSubData
en lugar de.
http://www.opengl.org/wiki/GLAPI/glBufferSubData
Editar: glBufferSubData
es solo si desea reemplazar datos; para cambiar el tamaño del búfer, debe llamar glBufferData
.
Además, no es necesario destruir el búfer primero y generar uno nuevo. Recuerde que GLuint es solo una especie de ‘puntero’ para OpenGL. No es el almacenamiento real, por lo que está perfectamente bien reutilizar el mismo ‘puntero’ (si aún no lo eliminó, por supuesto).
1 usando glMapBuffer
void mapBuffer(uint &id, void *data, uint size, uint type) {
glBindBuffer(type, id);
// get pointer
void *ptr = glMapBuffer(type, GL_WRITE_ONLY);
// now copy data into memory
memcpy(ptr, data, size);
// make sure to tell OpenGL we're done with the pointer
glUnmapBuffer(type);
}
2 utilizando glBufferSubData
void updateBuffer(uint &id, uint offset, void *data, uint size, uint type) {
glBindBuffer(type, id);
glBufferSubData(type, offset, size, data);
}
Especifica el tamaño en bytes de la región del almacén de datos que se reemplaza
mapBuffer(vbo, vertex.data(), sizeof(uint)*vertex.size(), GL_ARRAY_BUFFER);
resetBuffer(vbo, vertex.data(), sizeof(uint)*vertex.size(), GL_ARRAY_BUFFER);
updateBuffer(vbo, 0, vertex.data(), sizeof(uint)*vertex.size(), GL_ARRAY_BUFFER);
Si quieres, también puedes usar
glBufferData
-> pero es eliminar todos los datos antiguos y reutilizar el mismo búfer
glInvalidateBufferSubData
-> se puso NULL en todo el lugar y ahora puedes alimentar tus propios datos.