Apa tujuan dari Objek Array Vertex OpenGL?


36

Saya baru saja mulai dengan OpenGL. Saya masih belum benar-benar mengerti apa itu Objek Vertex Array dan bagaimana mereka dapat digunakan.

Jika Vertex Buffer Object digunakan untuk menyimpan data vertex (seperti posisi dan koordinat teksturnya) dan VAO hanya berisi flag status, di mana mereka dapat digunakan? Apa tujuan mereka?

Sejauh yang saya mengerti dari GL Wiki (sangat tidak lengkap dan tidak jelas), VAO digunakan untuk mengatur flag / statūs untuk setiap titik, mengikuti urutan yang dijelaskan dalam Elemen Array Buffer, tetapi wiki itu benar-benar ambigu tentang hal itu dan saya Saya tidak begitu yakin tentang apa yang benar-benar dilakukan VAO dan bagaimana saya bisa mempekerjakan mereka.

Jawaban:


49

Saya pikir Anda akan memahami tujuan mereka dengan lebih baik dengan sampel. Dengan membaca komentar Anda akan memahami bagaimana VAO digunakan.

// 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
Bisakah saya melakukan ini dengan data buffer GL_DYNAMIC_DRAW juga? Apakah bagian rendering hanya berisi glBindVertexArray (), glBufferData () dan kemudian glDrawElements ()?
Piku

Bagaimana Anda berurusan dengan normals dalam contoh ini? Maksud saya bagaimana jika Anda menambahkan GLfloat normal[3]di kelas Vertex Anda dan ingin mengunggah normals ke klien?
linello

1

VAO berguna, karena Anda tidak perlu mengatur setiap atribut setiap kali. Itu juga harus lebih cepat hanya mengikat satu VAO daripada mengatur semua atribut.


1

Ini adalah tautan favorit saya: http://www.songho.ca/opengl/gl_vertexarray.html

Ini akan membantu Anda mendapatkan pemahaman yang lebih baik tentang perbedaan antara VAO dan VBO. Juga, saya sarankan membaca bab di OpenGL yang luar biasa tentang topik ini. Itu bekerja dengan baik dalam menjelaskan dasar-dasar ini secara panjang lebar dan dengan contoh-contoh.


6
Artikel yang Anda tautkan tidak mencakup VAO's, hanya array vertex (yang telah ada lebih lama). Saya bingung tentang perbedaan spesifik antara keduanya.
Steven Lu

Tidak banyak perbedaan. VAO hanya merangkum semua status mengenai array vertex dan penggunaan serta formatnya, kecuali untuk data array itu sendiri, yang disimpan dalam VBO. Tetapi Anda benar bahwa jawaban ini (atau tautannya) tidak benar-benar berbicara tentang VAO.
Chris mengatakan Reinstate Monica

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.