c++ - original - opengl download
Diferencia en glGenBuffers y glCreateBuffers (3)
Especificación de OpenGL 4.5 - 6.1 Creación y vinculación de objetos del búfer:
Se crea un objeto de búfer vinculando un nombre devuelto por GenBuffers a un destino de búfer. La vinculación se efectúa llamando
void BindBuffer (enum target, uint buffer);
el objetivo debe ser uno de los objetivos enumerados en la tabla 6.1. Si el objeto buffer llamado buffer no ha sido previamente enlazado, el GL crea un nuevo vector de estado, inicializado con un buffer de memoria de tamaño cero y que comprende todo el estado y con los mismos valores iniciales listados en la tabla 6.2.
Por lo tanto, la diferencia entre glGenBuffers
y glCreateBuffers
es que glGenBuffers
solo devuelve un nombre no utilizado, mientras que glCreateBuffers
también crea e inicializa el vector de estado descrito anteriormente.
Uso:
Se recomienda usar glGenBuffers
+ glBindBuffer
, porque
el GL puede tomar diferentes decisiones sobre la ubicación y el diseño del almacenamiento según el enlace inicial.
Como en glCreateBuffers
no se glCreateBuffers
ninguna vinculación inicial, no se puede hacer esta elección.
Dado que estamos usando OpenGL 4.5 o tenemos soporte para la extensión GL_ARB_direct_state_access
, tenemos la nueva función glCreateBuffers
.
Esta función tiene una firma idéntica a glGenBuffers
, pero especifica:
devuelve
n
nombres de búfer no utilizados anteriormente enbuffers
, cada uno de los cuales representa un nuevo objeto de búfer inicializado como si se hubiera vinculado a un destino no especificado
glGenBuffers
tiene la siguiente especificación:
Los nombres de objetos almacenados en el búfer devueltos por una llamada a
glGenBuffers
no son devueltos por llamadas posteriores, a menos que primero se eliminen conglDeleteBuffers
.
Por lo tanto, cualquier nombre de búfer devuelto por glCreateBuffers
nunca volverá a usarse por sí mismo, pero podría ser usado por glGenBuffers
.
Parece que glCreateBuffers
siempre creará nuevos objetos de búfer y devolverá sus nombres, y glGenBuffers
solo creará nuevos búferes si no hay búferes anteriores que se hayan eliminado desde entonces.
¿Qué ventaja tiene agregar esta función?
¿Cuándo debo usar glCreateBuffers
sobre glGenBuffers
?
PD
Creo que esto representa todas las funciones glCreate*
agregadas por GL_ARB_direct_state_access
Lo que está notando aquí es básicamente poner en orden la API para mantener la consistencia contra Shader y la creación de objetos del programa. Esos siempre se han generado e inicializado en una sola llamada y eran la única parte de la API que funcionaba de esa manera. Todos los demás objetos se reservaron primero utilizando glGen* (...)
y luego se inicializaron vinculando el nombre reservado a un destino.
De hecho, antes de GL 3.0 se glGen* (...)
omitir glGen* (...)
completo y crear un objeto simplemente vinculando un número único en alguna parte.
En GL 4.5, a cada tipo de objeto se le dio una función glCreate* (...)
que los genera y los inicializa en una sola llamada en GL 4.5. Esta metodología encaja muy bien con Direct State Access, donde modificar (en este caso crear) un objeto no requiere alterar (y potencialmente restaurar) un estado vinculante.
Muchos objetos requieren un objetivo ( por ejemplo, texturas) cuando se utiliza la API de esta manera, pero los objetos del búfer son para todos los efectos sin tipo. Es por eso que la firma API es idéntica. Cuando crea un objeto de memoria intermedia con esta interfaz, se "inicializa como si se hubiera vinculado a un objetivo no especificado". Eso sería una completa tontería para la mayoría de los tipos de objetos en GL; necesitan un objetivo para inicializarlos adecuadamente.
La principal consideración aquí es que puede querer crear y configurar el estado de un objeto en GL sin afectar a algún otro fragmento de código que espere que el objeto vinculado a un determinado objetivo permanezca sin cambios. Para eso se creó Direct State Access, y esa es la razón principal por la que existen estas funciones.
En teoría, como señala Dari, la inicialización de un objeto de búfer al vincularlo a un objetivo específico potencialmente da al conductor pistas sobre su uso previsto. Sin embargo, no pondría mucho glBufferData (...)
en eso, eso es tan dudoso como el uso real glBufferData (...)
cuándo se glBufferData (...)
; una sugerencia en el mejor de los casos
glCreateBuffers
no tiene un objetivo porque los objetos del búfer no están escritos. El primer objetivo vinculante solo se utilizó como una pista en OpenGL. Y Khronos consideró darle a glCreateBuffers
un parámetro target
, pero ellos decidieron no hacerlo:
NamedBufferData (y la función correspondiente del EXT original) no incluyen el parámetro <target>. ¿Las implementaciones pueden hacer suposiciones iniciales sobre el uso de un almacén de datos basado en este parámetro? ¿A donde se fué? ¿Deberíamos traerlo de vuelta?
RESUELTO: No es necesario un parámetro objetivo para el búfer. Las implementaciones [sic] no hacen una suposición de uso basada en el parámetro <target>. Solo una extensión de proveedor lo hace AMD_pinned_memory. Un [sic] para un enfoque consistente para especificar un uso de búfer sería agregar un nuevo indicador para ese parámetro <flags> de BufferStorage.
Énfasis añadido.