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.

Vaillancourt
fonte

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
Pombal
fonte
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.

zacharmarz
fonte
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.

brainydexter
fonte
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
0

Aula 9 Aqui http://nccastaff.bournemouth.ac.uk/jmacey/CA1/index.html tem algumas coisas sobre isso (assim como o resto das minhas anotações) e Se você olhar a biblioteca NGL no mesmo site, eu tenho uma classe que encerra o comportamento de um VAO

JonMacey
fonte