OpenGL의 정점 배열 객체의 목적은 무엇입니까?


36

방금 OpenGL로 시작했습니다. Vertex Array Objects가 무엇인지, 어떻게 사용할 수 있는지 이해하지 못했습니다.

정점 버퍼 객체를 사용하여 정점 데이터 (예 : 위치 및 텍스처 좌표)를 저장하고 VAO에 상태 플래그 만 포함되어 있으면 어디에서 사용할 수 있습니까? 그들의 목적은 무엇입니까?

내가 (매우 불완전하고 불명확 한) GL 위키에서 이해하는 한, VAO는 요소 배열 버퍼에 설명 된 순서에 따라 모든 정점에 대한 플래그 / 상태를 설정하는 데 사용되지만 위키는 그것에 대해 모호합니다. VAO가 실제로 무엇을하고 어떻게 VAO를 사용할 수 있는지 잘 모르겠습니다.

답변:


49

나는 샘플로 그들의 목적을 더 잘 이해할 것이라고 생각합니다. 주석을 읽으면 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
GL_DYNAMIC_DRAW 버퍼 데이터로도 이것을 할 수 있습니까? 렌더링 부분에 glBindVertexArray (), glBufferData () 및 glDrawElements () 만 포함됩니까?
— Piku

이 예제에서 법선을 어떻게 다루나요? GLfloat normal[3]Vertex 클래스에 를 추가 하고 법선을 클라이언트에 업로드하려면 어떻게해야합니까?
— linello

1

VAO는 모든 속성을 매번 설정할 필요가 없기 때문에 유용합니다. 또한 모든 속성을 설정하는 대신 하나의 VAO를 바인딩하는 것이 더 빠릅니다.


1

이것은 내가 가장 좋아하는 링크입니다 : http://www.songho.ca/opengl/gl_vertexarray.html

VAO와 VBO의 차이점을 더 잘 이해하는 데 도움이됩니다. 또한이 주제에 대해 OpenGL에서 장을 읽는 것이 좋습니다. 이 기본 사항을 자세하게 설명하고 예제를 통해 잘 설명합니다.


6
링크 한 기사는 VAO와 버텍스 배열 (오랜 시간이 더 오래 걸렸습니다) 만 다루지 않습니다. 나는이 두 가지의 차이점에 대해 당황하고 있습니다.
— Steven Lu

큰 차이는 없습니다. VAO는 VBO에 저장된 배열 데이터 자체를 제외하고 정점 배열과 그 사용법 및 형식에 관한 모든 상태를 캡슐화합니다. 그러나이 답변 (또는 링크)이 실제로 VAO에 대해 이야기하지 않는다는 것이 맞습니다.
— Chris는 Reinstate Monica

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.