정점 배열 객체는 무엇입니까?
저는 오늘이 튜토리얼에서 OpenGL을 배우기 시작했습니다 : http://openglbook.com/the-book/
저는 삼각형을 그리는 2 장에 도달했고 VAO를 제외한 모든 것을 이해합니다 (이 두문자어는 괜찮습니까?). 튜토리얼에는 다음 코드가 있습니다.
glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId);
나는 코드가 필요하다는 것을 이해하지만 그것이 무엇을하는지 전혀 모른다. 이 시점 이후에는 VaoId를 사용하지 않지만 (파괴 제외) 코드가 없으면 작동하지 않습니다. 바인딩이 필요하기 때문이라고 생각하지만 그 이유는 모르겠습니다. 이 정확한 코드가 모든 OpenGL 프로그램의 일부 여야합니까? 이 튜토리얼에서는 VAO를 다음과 같이 설명합니다.
Vertex Array Object (또는 VAO)는 Vertex Buffer Object (또는 VBO)에 정점 속성이 저장되는 방법을 설명하는 객체입니다. 이것은 VAO가 정점 데이터를 저장하는 실제 객체가 아니라 정점 데이터의 설명 자임을 의미합니다. 정점 속성은 glVertexAttribPointer 함수와 두 자매 함수 인 glVertexAttribIPointer 및 glVertexAttribLPointer로 설명 할 수 있습니다. 첫 번째는 아래에서 살펴볼 것입니다.
VAO가 정점 속성을 어떻게 설명하는지 이해하지 못합니다. 나는 그것들을 어떤 식으로도 설명하지 않았습니다. glVertexAttribPointer에서 정보를 얻습니까? 나는 이것이 틀림 없다고 생각한다. VAO는 단순히 glVertexAttribPointer의 정보에 대한 대상입니까?
참고로 내가 따르는 튜토리얼이 허용됩니까? 주의해야 할 사항이나 따라야 할 더 나은 튜토리얼이 있습니까?
"Vertex Array Object"는 OpenGL ARB Subcommittee for Silly Names에서 제공합니다.
기하학 객체로 생각하십시오. (오래된 SGI 수행자 프로그래머로서 저는 그것들을 지오 셋이라고 부릅니다.) 객체의 인스턴스 변수 / 멤버는 정점 포인터, 일반 포인터, 색상 포인터, attrib N 포인터, ...
VAO가 처음 바인딩되면 다음을 호출하여 이러한 멤버를 할당합니다.
glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer...;
glEnableClientState(GL_NORMAL_ARRAY); glNormalPointer...;
등등. 활성화 된 속성과 제공하는 포인터는 VAO에 저장됩니다.
그 후 VAO를 다시 바인딩하면 모든 속성과 포인터도 현재 상태가됩니다. 따라서 한 번의 glBindVertexArray
호출은 이전에 모든 속성을 설정하는 데 필요한 모든 코드와 동일합니다. 자체 구조체 나 객체를 만들지 않고도 함수 나 메서드간에 지오메트리를 전달할 때 편리합니다.
(한 번 설정, 다중 사용은 VAO를 사용하는 가장 쉬운 방법이지만 바인딩하고 더 많은 활성화 / 포인터 호출을 수행하여 속성을 변경할 수도 있습니다. VAO는 상수가 아닙니다.)
Patrick의 질문에 대한 추가 정보 :
새로 생성 된 VAO의 기본값은 비어 있다는 것입니다 (AFAIK). 지오메트리가 전혀없고 꼭지점이 아니므로 그리려고하면 OpenGL 오류가 발생합니다. 이것은 "모든 것을 False / NULL / 0으로 초기화"에서와 같이 합리적으로 정상입니다.
glEnableClientState
설정 을 할 때만 필요 합니다. VAO는 각 포인터에 대한 활성화 / 비활성화 상태를 기억합니다.
예 VAO는 저장됩니다 glEnableVertexAttribArray
및 glVertexAttrib
. 이전 vertex, normal, color, ... 배열은 속성 배열과 동일하며 vertex == # 0 등등입니다.
Vertex Array Objects는 워드 프로세싱 프로그램 등의 매크로 와 같습니다. 여기에 좋은 설명이 있습니다 .
매크로는 단지 기억 당신이 호출 할 때 등의 활성화이 속성 바인드 그 버퍼로 당신이 한 행동을 glBindVertexArray( yourVAOId )
단순히, 다시 재생 하는 속성 포인터 바인딩과 바인딩을 버퍼.
따라서 다음 그리기 호출은 VAO에 의해 바인딩 된 모든 것을 사용합니다.
VAO는 정점 데이터를 저장하지 않습니다 . 아니요. 정점 데이터는 정점 버퍼 또는 클라이언트 메모리 배열에 저장됩니다.
VAO는 OpenGL 파이프 라인의 정점 가져 오기 단계를 나타내는 객체이며 정점 셰이더에 입력을 제공하는 데 사용됩니다.
다음과 같이 정점 배열 객체를 만들 수 있습니다.
GLuint vao;
glCreateVertexArrays(1, &vao);
glBindVertexArray(vao);
먼저 간단한 예를 들어 보겠습니다. 셰이더 코드에서 이러한 입력 매개 변수를 고려하십시오.
layout (location = 0) in vec4 offset; // input vertex attribute
이 속성을 채우려면 다음을 사용할 수 있습니다.
glVertexAttrib4fv(0, attrib); // updates the value of input attribute 0
정점 배열 객체는 이러한 정적 속성 값을 저장하지만 더 많은 작업을 수행 할 수 있습니다.
정점 배열 객체를 만든 후 상태 채우기를 시작할 수 있습니다. OpenGL에 우리가 제공하는 버퍼 객체에 저장된 데이터를 사용하여 자동으로 채우도록 요청할 것입니다. 각 정점 속성은 여러 정점 버퍼 바인딩 중 하나에 바인딩 된 버퍼에서 데이터를 가져옵니다. 이를 위해 우리는 glVertexArrayAttribBinding(GLuint vao, GLuint attribindex, GLuint bindingindex)
. 또한이 glVertexArrayVertexBuffer()
함수를 사용하여 버퍼를 정점 버퍼 바인딩 중 하나에 바인딩합니다. 이 glVertexArrayAttribFormat()
함수를 사용하여 데이터의 레이아웃과 형식을 설명하고 마지막으로를 호출하여 속성의 자동 채우기를 활성화 glEnableVertexAttribArray()
합니다.
When a vertex attribute is enabled, OpenGL will feed data to the vertex shader based on the format and location information you’ve provided with glVertexArrayVertexBuffer()
and glVertexArrayAttribFormat()
. When the attribute is disabled, the vertex shader will be provided with the static information you provide with a call to glVertexAttrib*()
.
// First, bind a vertex buffer to the VAO
glVertexArrayVertexBuffer(vao, 0, buffer, 0, sizeof(vmath::vec4));
// Now, describe the data to OpenGL, tell it where it is, and turn on automatic
// vertex fetching for the specified attribute
glVertexArrayAttribFormat(vao, 0, 4, GL_FLOAT, GL_FALSE, 0);
glEnableVertexArrayAttrib(vao, 0);
And code in a shader
layout (location = 0) in vec4 position;
After all you need to call to glDeleteVertexArrays(1, &vao)
.
You can read OpenGL SuperBible to understand it better.
I always think about VAO as an array of data buffers used by OpenGL. Using modern OpenGL you will create a VAO and Vertex Buffer Objects.
//vaoB is a buffer
glGenVertexArrays(1, vaoB); //creates one VAO
glBindVertexArray(vao.get(0));
glGenBuffers(vbo.length, vbo, 0); //vbo is a buffer
glBindVertexArray(vao.get(1));
glGenBuffers(vbo1.length, vbo1, 0); //vbo1 is a buffer
glBindVertexArray(vao.get(2));
glGenBuffers(vbo2.length, vbo2, 0); //vbo2 is a buffer
The next step is to bind data to a buffer:
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER,vertBuf.limit()*4, vertBuf, GL_STATIC_DRAW); //vertf buf is a floatbuffer of vertices
At this point OpenGL Sees:
Now we can use glVertexAttribPointer to tell OpenGL what the data in the buffer represents:
glBindBuffer(GL_ARRAY_BUFFER, 0); //bind VBO at 0
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); //each vertex has 3 components of size GL_FLOAT with 0 stride (space) between them and the first component starts at 0 (start of data)
OpenGL now has the data in the buffer and knows how the data is organized into vertices. The same process can be applied to texture coordinates etc but for texture coordinates there would be two values.
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER,coordBuf.limit()*4, coordBuf, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0);
Next you can bind texture and draw arrays, you will want to create a Vert and Frag shader, compile and attach it to a program (not included here).
glActiveTexture(textureID); //bind our texture
glBindTexture(GL_TEXTURE_2D, textureID);
glDrawArrays(GL_TRIANGLES,0,6); //in this case 6 indices are used for two triangles forming a square
참고URL : https://stackoverflow.com/questions/11821336/what-are-vertex-array-objects
'program tip' 카테고리의 다른 글
내 네트워크의 다른 컴퓨터에서 내 IIS 호스팅 사이트보기 (0) | 2020.08.25 |
---|---|
암호를 서버 측으로 보내기 전에 해시해야합니까? (0) | 2020.08.25 |
메타 패키지에 따른 netstandard 라이브러리의 응용 프로그램 의미는 무엇입니까? (0) | 2020.08.24 |
SQL 조인 대 SQL 하위 쿼리 (성능)? (0) | 2020.08.24 |
자바 스크립트 배열의 Big O (0) | 2020.08.24 |