Saltar al contenido

¿Cuál es la forma correcta de modificar el búfer de vértices de OpenGL?

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *