Como re-glBufferData () 'ing interage com glVertexAttribPointer?

Aug 21 2020

Eu entendo a sequência básica: glGenBuffers () cria um "nome de objeto de buffer", glBindBuffer () cria o objeto de buffer real (bem como vincula o nome), glBufferData () "cria e inicializa o armazenamento de dados de um objeto de buffer" e glVertexAttribPointer () define o formato dos dados do buffer, bem como salva a ligação do objeto buffer como parte do estado do array de atributos do vértice.

A coisa complicada de que não tenho certeza é se o material glVertexAttribPointer () permanece válido se o "armazenamento de dados do objeto de buffer" (mas não o próprio objeto de buffer) é destruído por uma nova chamada para glBufferData (). Estou ciente de que normalmente isso não é uma boa ideia - use glBufferSubData () ao apenas reescrever buffers - mas glBufferData () parece ser a única opção se precisar ser redimensionado. Além disso, estou apenas curioso.

As páginas de referência fazem parecer que poderia acontecer de qualquer maneira - em particular (https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glVertexAttribPointer.xhtml):

Se o ponteiro não for NULL, um objeto de buffer nomeado diferente de zero deve ser vinculado ao alvo GL_ARRAY_BUFFER (consulte glBindBuffer ), caso contrário, um erro será gerado. o ponteiro é tratado como um deslocamento de byte no armazenamento de dados do objeto buffer. A vinculação do objeto de buffer (GL_ARRAY_BUFFER_BINDING) é salva como estado de matriz de atributo de vértice genérico (GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) para índice de índice .

Quando uma matriz de atributo de vértice genérica é especificada, tamanho , tipo , normalizado , passo e ponteiro são salvos como estado da matriz de vértice, além da ligação do objeto de buffer da matriz de vértice atual.

Parece que o deslocamento de byte e a vinculação do objeto de buffer podem permanecer válidos, mesmo se o armazenamento de dados for substituído por algo diferente. Mas também pude ver isso sendo implementado de forma que, no momento da chamada, a vinculação capture um ponteiro específico para o armazenamento de dados, que se torna invalidado se o armazenamento de dados for substituído. Nenhuma das formas parece ser impedida pelo texto.

Respostas

D0SBoots Aug 22 2020 at 04:45

Parece que as ligações glVertexAttribPointer () permanecem válidas, mesmo após chamadas subsequentes para glBufferData (). Eu determinei isso experimentando, o que não é 100% prova - pode estar funcionando apenas nesta implementação (drivers NVidia, no meu caso).

No entanto, com um retorno de chamada de mensagem de erro e modo de depuração ativados, recebo a seguinte mensagem na segunda chamada para glBufferData (), o que sugere fortemente que esta situação é esperada / projetada para:

[LWJGL] Mensagem de depuração OpenGL
    ID: 0x20071
    Fonte: API
    Tipo: OUTRO
    Gravidade: NOTIFICAÇÃO
    Mensagem: Informações detalhadas do buffer: Objeto de buffer 1 (vinculado a GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (1) e GL_ARRAY_BUFFER_ARB, a dica de uso de memória do GL_STATIC_ARB como o objeto de memória de buffer usará GL_STATIC_DRAW).

As duas primeiras ligações representam minhas duas chamadas para glVertexAttribPointer () e não estão presentes na mensagem que é registrada na primeira vez que chamo glBufferData ().