OpenGL'nin Vertex Dizi Nesnelerinin amacı nedir?


36

OpenGL ile daha yeni başladım, hala Vertex Dizi Nesnelerinin ne olduğunu ve nasıl kullanılabileceğini anlamadım.

Vertex Buffer Object, köşe verilerini depolamak için kullanılıyorsa (konumları ve doku koordinatları gibi) ve VAO'lar yalnızca durum bayrakları içeriyorsa, nerede kullanılabilirler? Amacı ne?

Anladığım kadarıyla (çok eksik ve net olmayan) GL Wiki'den, VAO'lar, Element Dizi Tamponunda açıklanan sırayı takip ederek her tepe noktası için bayrakları / statüleri ayarlamak için kullanılır, ancak wiki bu konuda gerçekten belirsizdi. VAO'ların gerçekte ne yaptıklarından ve onları nasıl işe alabileceğimden gerçekten emin değilim.

Yanıtlar:


49

Bir örnekle amaçlarını daha iyi anlayacağınızı düşünüyorum. Yorumları okuyarak VAO'ların nasıl kullanıldığını anlayacaksınız.

// 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
Bunu GL_DYNAMIC_DRAW arabellek verileriyle de yapabilir miyim? Oluşturma bölümü yalnızca glBindVertexArray (), glBufferData () ve ardından glDrawElements () öğesini içerir mi?
Piku

Bu örnekte normallerle nasıl başa çıkıyorsunuz? Yani GLfloat normal[3], Vertex sınıfınıza bir tane eklerseniz ve normalleri müşteriye yüklemek istiyorsanız?
linello

1

VAO'lar kullanışlıdır, çünkü her zaman tüm özellikleri ayarlamanız gerekmez. Ayrıca tüm özellikleri ayarlamak yerine yalnızca bir VAO'yu bağlamak daha hızlı olmalıdır.


1

Bu benim en sevdiğim bağlantı: http://www.songho.ca/opengl/gl_vertexarray.html

VAO ve VBO'lar arasındaki farkları daha iyi anlamanıza yardımcı olacaktır. Ayrıca, Id bu konuda süper OpenGL bir bölüm okumanızı öneririz. Bu temelleri uzun ve örneklerle açıklamakta iyi bir iş çıkarır.


6
Bağladığınız makale VAO'ları kapsamıyor, yalnızca köşe dizileri (uzun süredir var). Ben bu ikisi arasındaki spesifik farklılıklar üzerinde kafa yoruyorum.
Steven Lu,

Çok fazla fark yok. VAO, VBO'larda depolanan dizi verilerinin haricinde, köşe dizileri ve bunların kullanımları ve biçimleriyle ilgili tüm durumu kapsar. Ancak, bu cevabın (veya bağlantının) VAO'lar hakkında gerçekten konuşmadığı konusunda haklısın.
Chris, Monica

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.