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.