Qual é o objetivo dos objetos Vertex Array do OpenGL?


36

Comecei com o OpenGL e ainda não entendi o que são os Vertex Array Objects e como eles podem ser empregados.

Se o objeto de buffer do vértice for usado para armazenar dados de vértice (como suas posições e coordenadas de textura) e os VAOs contiverem apenas sinalizadores de status, onde eles podem ser usados? Qual é o propósito deles?

Pelo que entendi no GL Wiki (muito incompleto e pouco claro), os VAOs são usados ​​para definir os sinalizadores / status para cada vértice, seguindo a ordem descrita no Buffer de matriz de elementos, mas o wiki era realmente ambíguo sobre isso e eu ' Não tenho muita certeza do que os VAOs realmente fazem e como eu poderia empregá-los.

Respostas:


49

Eu acho que você entenderá melhor o objetivo deles com uma amostra. Ao ler os comentários, você entenderá como os VAOs são usados.

// BEGIN INITIALIZATION
// Define some vertex data 
struct Vertex {
  GLfloat position[3];
  GLfloat texcoord[2];
};
Vertex vertexdata[NUM_VERTS] = { ... };
GLubyte indexdata[NUM_INDICES] = { 0, 1, 2, ... };

// Create and bind a VAO
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

// Create and bind a BO for vertex data
GLuint vbuffer;
glGenBuffers(1, &vbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);

// copy data into the buffer object
glBufferData(GL_ARRAY_BUFFER, NUM_VERTS * sizeof(Vertex), vertexdata, GL_STATIC_DRAW);

// set up vertex attributes
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, position));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, texcoord));

// Create and bind a BO for index data
GLuint ibuffer;
glGenBuffers(1, &ibuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);

// copy data into the buffer object
glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUM_INDICES * sizeof(GLubyte), indexdata, GL_STATIC_DRAW);

// At this point the VAO is set up with two vertex attributes
// referencing the same buffer object, and another buffer object
// as source for index data. We can now unbind the VAO, go do
// something else, and bind it again later when we want to render
// with it.

glBindVertexArray(0);

// END INITIALIZATION

// BEGIN RENDER LOOP

// This is it. Binding the VAO again restores all buffer 
// bindings and attribute settings that were previously set up
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, NUM_INDICES, GL_UNSIGNED_BYTE, (void*)0);

// END RENDER LOOP

2
Também posso fazer isso com os dados do buffer GL_DYNAMIC_DRAW? A parte de renderização conteria apenas glBindVertexArray (), glBufferData () e glDrawElements ()?
Piku

Como você lida com os normais neste exemplo? Quero dizer, e se você adicionar um GLfloat normal[3]na sua classe Vertex e quiser fazer o upload dos normais para o cliente?
Linello 29/04

1

Os VAOs são úteis, porque você não precisa configurar todos os atributos todos os dias. Também deve ser mais rápido vincular um VAO em vez de definir todos os atributos.


1

Este é o meu link favorito: http://www.songho.ca/opengl/gl_vertexarray.html

Isso deve ajudá-lo a entender melhor as diferenças entre VAO e VBOs. Além disso, eu recomendo a leitura de um capítulo no OpenGL, que pode ser destacado neste tópico. Ele faz um bom trabalho em explicar esses conceitos detalhadamente e com exemplos.


6
O artigo que você vinculou não abrange os VAO, apenas matrizes de vértices (que já existem há um tempo). Estou intrigado com as diferenças específicas entre esses dois.
Steven Lu

Não há muita diferença. O VAO apenas encapsula todos os estados relativos às matrizes de vértices e seus usos e formatos, exceto para os próprios dados da matriz, que são armazenados nas VBOs. Mas você está certo em que esta resposta (ou o link) realmente não fala sobre VAOs.
Chris diz Restabelecer Monica

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.