Compreendendo VAO e VBO

Oct 23 2020

Estou lendo Aprenda OpenGL para atualizar os conceitos básicos, já que não tocava há muito tempo.

Especificamente, ainda acho que não consigo entender o significado de VAO e VBO, o livro continua principalmente por meio de exemplos que realmente não dá definições rigorosas.

Sobre o VBO:

Com os dados do vértice definidos, gostaríamos de enviá-los como entrada para o primeiro processo do pipeline gráfico: o sombreador de vértice. Isso é feito criando memória na GPU onde armazenamos os dados do vértice, configuramos como o OpenGL deve interpretar a memória e especifica como enviar os dados para a placa gráfica. O sombreador de vértice então processa tantos vértices quanto lhe dizemos de sua memória. Gerenciamos essa memória por meio dos chamados objetos de buffer de vértice (VBO), que podem armazenar um grande número de vértices na memória da GPU. A vantagem de usar esses objetos de buffer é que podemos enviar grandes lotes de dados de uma vez para a placa gráfica e mantê-los lá se houver memória suficiente, sem ter que enviar dados um vértice de cada vez. O envio de dados da CPU para a placa de vídeo é relativamente lento, então, sempre que podemos, tentamos enviar o máximo de dados possível de uma vez. Uma vez que os dados estão na memória da placa gráfica, o sombreador de vértice tem acesso quase instantâneo aos vértices tornando-o extremamente rápido

Então, meu entendimento de VBO eles são essencialmente objetos Buffer (grupo de bytes a serem enviados para a GPU) com a diferença de que VBO são especificamente dedicados a Vertex Data. Isso está correto?

Sobre o VAO:

Aqui, em vez disso, realmente não entendo.

Um objeto de matriz de vértice (também conhecido como VAO ) pode ser vinculado como um objeto de buffer de vértice e qualquer chamada de atributo de vértice subsequente a partir desse ponto será armazenada dentro do VAO.

O que significa que quaisquer chamadas subsequentes de atributo de vértice daquele ponto em diante serão armazenadas dentro do VAO , eu não entendo o bit "call be stored", isso significa em algum lugar no contexto opengl criado e armazenamos como alguns dados relacionados ao chamadas de atributo de vértice (como o par de entrada e saída da chamada? a saída da chamada? algo relacionado à chamada?).

Isso tem a vantagem de que, ao configurar ponteiros de atributo de vértice, você só precisa fazer essas chamadas uma vez e sempre que quisermos desenhar o objeto, podemos apenas vincular o VAO correspondente. Isso torna a alternância entre diferentes dados de vértice e configurações de atributo tão fácil quanto vincular um VAO diferente. Todo o estado que acabamos de definir é armazenado dentro do VAO.

Não entendo a vantagem aqui. Eu entendo a "chamada feita uma vez", porque eles estão armazenados no VAO (o que quer que "parte armazenada signifique"). A parte de comutação talvez signifique que eu possa criar vários VAO, cada um capturando diferentes chamadas de atributos de vértice, e posso apenas vincular cada um deles quando precisar, sem chamar novamente o atributo de vértice?

Para referência, também encontrei esta questão que pensei ter uma resposta interessante.

Respostas

3 NicolBolas Oct 23 2020 at 01:05

Então, meu entendimento de VBO eles são essencialmente objetos Buffer (grupo de bytes a serem enviados para a GPU) com a diferença de que VBO são especificamente dedicados a Vertex Data. Isso está correto?

Um "VBO" não é realmente uma coisa, e eu realmente gostaria que os tutoriais parassem de fingir que são.

Você está correto quanto à existência de objetos de buffer . Essas são matrizes lineares de dados não formatados que a GPU armazena e pode acessar para vários processos. Um desses "vários processos" para os quais a GPU pode usá-los é fornecer dados de array para operações de renderização de vértices.

Mas o buffer em si não é especial. Não se torna uma coisa diferente apenas porque você o usa para dados de vértice, e não há nenhuma regra que diga que um buffer que você está usando atualmente para dados de vértice não possa ser usado para outros usos de buffer também.

Observe que isso é diferente de como as texturas funcionam. Quando você cria um objeto de textura e o vincula como uma textura 2D, esse objeto de textura se torna para sempre uma textura 2D. Você não pode vinculá-lo posteriormente como um 1D ou um mapa de cubo ou qualquer outra coisa. Objetos de buffer não são assim; onde você os vincula define apenas como você os está usando atualmente .

O que significa "quaisquer chamadas subsequentes de atributo de vértice daquele ponto em diante serão armazenadas dentro do VAO"

Este é mais um tropo tutorial irritante: os objetos "armazenam chamadas" ou são macros ou outras coisas sem sentido.

Objetos em OpenGL não armazenam chamadas; eles armazenam o estado . Eles são como estruturas; eles têm membros de dados. Vincular um objeto ao contexto OpenGL permite que as operações OpenGL que acessam determinado estado encontrem esse estado dentro do objeto vinculado. Portanto, se você chamar uma função que modifica determinado estado proveniente de um objeto vinculado, essa função modificará o estado dentro do objeto.

Quando você vincula um VAO, está vinculando um objeto que armazena o estado usado para matrizes de vértices. Quando você chama uma função que modifica o estado de matrizes de vértices, essa função modifica o estado armazenado no VAO atualmente vinculado. Quando você renderizar, o sistema de renderização usará o estado da matriz de vértices encontrado no VAO atualmente vinculado.

2 ratchetfreak Oct 23 2020 at 19:53

Um VBO é um buffer de memória que a GPU pode acessar. É só isso.

Um VAO é um objeto que armazena ligações de vértices. Isso significa que quando você chama glVertexAttribPointer e amigos para descrever o formato do vértice, essas informações de formato são armazenadas no VAO atualmente vinculado. E quando você desenhar, ele usará as ligações de vértice no VAO atualmente vinculado.

Fingir que ele reproduz as chamadas de ligação é enganoso. É uma relíquia do motivo pelo qual o VAO foi criado, porque antes dos VAOs você precisava refazer as ligações de vértice toda vez que alterava a malha que estava desenhando. Um VAO permite que você faça isso em uma única chamada.