Esta es una pregunta compleja con muchos pequeños detalles que realmente importan, el rendimiento variará según la plataforma y la aplicación. Por lo tanto, debe hacer un perfil de posibles cuellos de botella antes de invertir en optimizaciones.
Dicho esto, en primer lugar, supongo que debe reducir las cargas y actualizaciones tanto como pueda, por ejemplo, usar instancias.
En segundo lugar, tenga en cuenta que las GPU no pueden transferir buffers y renderizar al mismo tiempo, por lo que el dispositivo procesa secuencialmente todos los comandos de OpenGL en la cola de comandos. Existen diferentes formas de copiar datos y / o hacer que estén disponibles para que la GPU los use.
Hay varias formas de transmitir datos a la GPU
1- glBufferDatao glBufferSubDatamétodo
Usar glBufferDatao glBufferSubDataes como memcpy. se pasa un puntero y se puede realizar una operación DMA , dije que podría porque la memoria podría estar anclada en la memoria de la CPU y utilizada directamente por la GPU sin que realmente se produzca una transferencia de memoria a la GPU, dependiendo del indicador de uso (GL_STREAM). En opinión, deberías probar esto al principio porque es más sencillo de implementar.
2- obtener un puntero a la memoria interna usando glMapBuffer
Si lo anterior no es lo suficientemente bueno que puede usar glMapBuffer, obtiene un puntero a la memoria interna, y puede usar este puntero para llenar el búfer directamente, esto es bueno con las operaciones de lectura y escritura de archivos, ya que puede asignar directamente los datos del archivo a la memoria de la GPU en lugar de copiar primero a un búfer temporal. Si no desea mapear todo el búfer, puede usarlo glMapBufferRangepara mapear una parte del búfer.
Un truco es crear un búfer grande, usar la primera mitad para renderizar y la segunda mitad para actualizar.
3- Huérfano de búfer
Con respecto a la huérfana del búfer, esto se puede hacer usando glBufferData con nulo y los mismos parámetros que tenía. El controlador devolverá el bloque de memoria una vez que no se use. Y será utilizado por la próxima llamada glBufferData (no se asignará memoria nueva).
Todos los métodos mencionados causan una gran cantidad de sincronización costosa, nuevamente las GPU no pueden transferir buffers y renderizar al mismo tiempo.
4- Unsynchronized Buffers
El método más rápido (y el más difícil de acertar) es usar buffers sin sincronización con los que puede usar el GL_MAP_UNSYNCHRONIZED_BITindicador glMapBufferRange, el problema es que no se realiza la sincronización, por lo que podríamos cargar datos en un buffer comenzar a usar, y por lo tanto arruinar todo. Puede usar múltiples buffers con bit de sincronización para facilitar un poco las cosas.