¿Cómo interactúa re-glBufferData () 'ing con glVertexAttribPointer?

Aug 21 2020

Entiendo la secuencia básica: glGenBuffers () crea un "nombre de objeto de búfer", glBindBuffer () crea el objeto de búfer real (además de vincular el nombre), glBufferData () "crea e inicializa el almacén de datos de un objeto de búfer" y glVertexAttribPointer () establece el formato de los datos del búfer, además de guardar el enlace del objeto del búfer como parte del estado de la matriz del atributo de vértice.

Lo complicado de lo que no estoy seguro es si el elemento glVertexAttribPointer () sigue siendo válido si el "almacén de datos del objeto de búfer" (pero no el objeto de búfer en sí) es destruido por una nueva llamada a glBufferData (). Soy consciente de que esto no suele ser una buena idea: use glBufferSubData () cuando solo reescriba búferes, pero glBufferData () parece ser la única opción si necesita cambiar su tamaño. Además, solo tengo curiosidad.

Las páginas de referencia hacen que parezca que podría ir en cualquier dirección, en particular (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml):

Si el puntero no es NULL, un objeto de búfer con nombre distinto de cero debe vincularse al destino GL_ARRAY_BUFFER (ver glBindBuffer ), de lo contrario se genera un error. El puntero se trata como un desplazamiento de bytes en el almacén de datos del objeto de búfer. El enlace de objeto de búfer (GL_ARRAY_BUFFER_BINDING) se guarda como estado de matriz de atributo de vértice genérico (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) para el índice de índice .

Cuando se especifica una matriz de atributo de vértice genérico, el tamaño , tipo , normalizado , zancada y puntero se guardan como estado de matriz de vértice, además del enlace de objeto de búfer de matriz de vértice actual.

Parece que tanto el desplazamiento de bytes como el enlace del objeto de búfer podrían seguir siendo válidos, incluso si el almacén de datos fue reemplazado por algo diferente. Pero también pude ver que se implementa de tal manera que en el momento de la llamada, el enlace captura un puntero específico en el almacén de datos, que se invalida si se reemplaza el almacén de datos. Ninguna de las dos formas parece estar excluida por la redacción.

Respuestas

D0SBoots Aug 22 2020 at 04:45

Parece que los enlaces glVertexAttribPointer () siguen siendo válidos, incluso después de llamadas posteriores a glBufferData (). Lo determiné probándolo, lo cual no es 100% a prueba; podría estar funcionando solo en esta implementación (controladores NVidia, en mi caso).

Sin embargo, con un mensaje de error de devolución de llamada y modo de depuración activado, aparece el siguiente mensaje en la segunda llamada a glBufferData (), lo que sugiere fuertemente que esta situación es esperada / diseñada para:

[LWJGL] Mensaje de depuración de OpenGL
    ID: 0x20071
    Fuente: API
    Tipo: OTRO
    Severidad: NOTIFICACIÓN
    Mensaje: Información detallada del búfer: objeto de búfer 1 (vinculado a GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1), y GL_ARRAY_BUFFER_ARB, la sugerencia de uso es GL_DO_STATIC para las operaciones del búfer).

Los dos primeros enlaces representan mis dos llamadas a glVertexAttribPointer () y no están presentes en el mensaje que se registra la primera vez que llamo a glBufferData ().