Projeto Virtual Worlds

Computação Gráfica 3D em C

Arquivos Mensais: abril 2017

VAOs e VBOs

Quando você lê sobre os Vertex Array Objects na especificação do OpenGL, a coisa pode ficar meio confusa. Em alguns casos você é levado a acreditar que esse objeto mantém o estado apenas dos mapas de atributos de um array de vértices (daí o nome), mas, de fato, ele mantém o estado, inclusive, dos Buffer Objects usados no mapeamento. Até 16 conjuntos de mapas de atributos e até 16 VBOs podem ter seus estados mantidos num único VAO.

VBOs, como já descrevi, existem como containers de dados que serão hospedados no servidor OpenGL, por exemplo, na memória da sua placa de vídeo, ao invés da memória do sistema. Isso acelera um bocado o processamento gráfico, mas cria uma complicação: As posições onde cada componente de um vértice contido nesse buffer precisam ser informadas para o shader através de funções como glVertexAttribPointer. Ou seja, “shader, a coordenada x,y,z está na posição 0 do VBO nº 2 e é composta com 3 floats… mas a cor do vértice está na posição 0 do VBO nº 3 (ou na posição 12 da mesma VBO nº 2) e tem tamanho…”. Esses são os “atributos” do vértice que glVerterAttribPointer dispobiliza e armazena na VAO.

Eis a primeira parte da lista de itens que uma VAO mantém:

Estado Tipo Tamanho Default
VERTEX_ATTRIB_ARRAY_ENABLED bool 16 false
VERTEX_ATTRIB_ARRAY_NORMALIZED bool 16 false
VERTEX_ATTRIB_ARRAY_INTEGER bool 16 false
VERTEX_ATTRIB_ARRAY_LONG bool 16 false
VERTEX_ATTRIB_ARRAY_SIZE uint 16 4
VERTEX_ATTRIB_ARRAY_STRIDE uint 16 0
VERTEX_ATTRIB_ARRAY_TYPE GLenum 16 GL_FLOAT
VERTEX_ATTRIB_ARRAY_POINTER void * 16 NULL
VERTEX_ATTRIB_ARRAY_DIVISOR uint 16 0

Repare que até 16 itens podem ser armazenados. A mesma coisa acontece com outros estados, exceto para o ELEMENT_ARRAY_BUFFER_BINDING, que refere-se ao VBO que contém a lista de índices que montam as faces do objeto a ser desenhado.

Quanto aos VBOs ligados ao VAO, seus estados são mantidos por 5 possíveis estados:

Estado Tipo Tamanho Default
VERTEX_ATTRIB_BUFFER_BINDING uint 16 0
VERTEX_ATTRIB_BINDING* uint 16 ?
VERTEX_ATTRIB_REL_ACTIVE_OFFSET uint 16 0
VERTEX_BINDING_OFFSET uint 16 0
VERTEX_BINDING_STRIDE uint 16 16

O VERTEX_ATTRIB_BINDING é um caso especial e vale ler a documentação da função glVertexAttrib (note a ausência de “Pointer” no final), mas, em resumo, os VBOs usados na VAO são mapeados.

Isso significa que, numa inicialização, você fez o binding de um VAO recém criado, e ajustou os atributos da estrutura de seu vértice a ser passada para o vertex shader usando até 16 VBOs, não será necessário refazer os bindings dos VBOs quando você re-selecionar a VAO antes da chamada a glDrawElements, por exemplo. O VAO mantém o binding de cada uma das 16 possíveis locations.

PS:

Existe um estado único (não são 16) extra chamado LABEL que é uma string. Mas isso é primariamente usado para debugging e não tem lá grande importância.

Anúncios