Jaki jest cel obiektów wierzchołków tablicy OpenGL?


36

Właśnie zacząłem od OpenGL. Nadal tak naprawdę nie rozumiem, czym są obiekty tablic wierzchołków i jak można je wykorzystać.

Jeśli obiekty bufora wierzchołków są używane do przechowywania danych wierzchołków (takich jak ich pozycje i współrzędne tekstury), a VAO zawierają tylko flagi stanu, gdzie można ich użyć? Jaki jest ich cel?

O ile rozumiem z (bardzo niepełnej i niejasnej) GL Wiki, VAO są używane do ustawiania flag / statūs dla każdego wierzchołka, zgodnie z kolejnością opisaną w buforze tablicy elementów, ale wiki była bardzo niejednoznaczna i ja ' Nie jestem pewien, co naprawdę robią VAO i jak mogę je zatrudnić.

Odpowiedzi:


49

Myślę, że dzięki próbce zrozumiesz ich cel. Czytając komentarze, zrozumiesz, w jaki sposób używane są VAO.

// 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
Czy mogę to zrobić również z danymi bufora GL_DYNAMIC_DRAW? Czy część renderująca zawierałaby tylko glBindVertexArray (), glBufferData (), a następnie glDrawElements ()?
— Piku,

Jak radzisz sobie z normalnymi w tym przykładzie? Mam na myśli co jeśli dodasz a GLfloat normal[3]do klasy Vertex i chcesz załadować normalne do klienta?
— linello

1

VAO są przydatne, ponieważ nie musisz konfigurować za każdym razem wszystkich atrybutów. Powinno być także szybsze, wystarczy powiązać jedno VAO, a nie ustawić wszystkie atrybuty.


1

To jest mój ulubiony link: http://www.songho.ca/opengl/gl_vertexarray.html

Powinno to pomóc w lepszym zrozumieniu różnic między VAO i VBO. Ponadto polecam przeczytać rozdział w OpenGL znakomity na ten temat. Dobrze objaśnia te podstawowe zasady i podaje przykłady.


6
Artykuł, który podłączyłeś, nie obejmuje VAO, a jedynie tablice wierzchołków (które istniały nieco dłużej). Zastanawiam się nad konkretnymi różnicami między nimi.
— Steven Lu,

Nie ma dużej różnicy. VAO po prostu podsumowuje wszystkie stany dotyczące tablic wierzchołków oraz ich zastosowań i formatów, z wyjątkiem samych danych tablicowych, które są przechowywane w VBO. Ale masz rację, że ta odpowiedź (lub link) tak naprawdę nie mówi o VAO.
— Chris mówi Przywróć Monikę

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.