수색…
소개
Vertex Array Object는 OpenGL이 VBO 세트를 해석하는 방법을 저장합니다.
본질적으로 새로운 메쉬를 렌더링 할 때마다 glVertexAttribPointer를 호출하지 않아도됩니다.
VAO를 다루고 싶지 않다면 프로그램을 초기화 할 때 VAO를 만들고 바인딩하고 존재하지 않는 것처럼 할 수 있습니다.
통사론
void glEnableVertexAttribArray (GLuint attribIndex);
void glDisableVertexAttribArray (GLuint attribIndex);
void glVertexAttribPointer (GLuint attribIndex, GLint 크기, GLenum 유형, GLboolean 정규화, GLsizei stride, const GLvoid * 포인터);
void glVertexAttribFormat (GLuint attribIndex, GLint 크기, GLenum 유형, GLboolean 정규화, GLuint relativeoffset);
void glVertexAttribBinding (GLuint attribIndex, GLuint bindingIndex);
void glBindVertexBuffer (GLuint bindingIndex, GLuint 버퍼, GLintptr 오프셋, GLintptr 스트라이드);
매개 변수
매개 변수 | 세부 |
---|---|
attribIndex | 정점 배열이 데이터를 공급할 정점 속성의 위치 |
크기 | 속성으로부터 꺼내는 컴퍼넌트의 수 |
유형 | 버퍼에있는 속성 데이터의 C ++ 유형 |
표준화 된 | 부동 소수점 범위 [0, 1] (부호없는) 또는 [-1, 1] (부호있는)에 정수 유형을 매핑할지 여부 |
바늘 | 속성 데이터의 최초의 바이트에 대한 버퍼에의 바이트 오프셋 (기존의 이유로써 void* 에 캐스트된다) |
오프셋 | 버퍼의 선두로부터 배열 데이터의 개시 위치까지의 기본 바이트 오프셋 |
relativeOffset | 버퍼의 기본 오프셋을 기준으로 한 특정 속성에 대한 오프셋 |
보폭 | 1 개의 정점의 데이터로부터 다음의 정점의 데이터까지의 바이트 수 |
완충기 | 정점 배열이 격납되고있는 버퍼 오브젝트 |
bindingIndex | 소스 버퍼 객체가 바인드되는 인덱스 |
비고
개별 속성 포맷 VAO 설정은 glVertexAttribPointer
와 상호 작용할 수 있습니다 (후자는 전자의 관점에서 정의됩니다). 그러나 그렇게 할 때주의해야합니다.
별도의 속성 형식 버전에는 4.5에 해당하는 DSA (직접 상태 액세스)가 있습니다. 이들은 동일한 매개 변수를 갖지만 바인드 된 VAO를 사용하는 대신 수정중인 VAO가 명시 적으로 전달됩니다. glDrawElements
대한 DSA de 인덱스 버퍼를 사용하는 경우 glVertexArrayElementBuffer(vao, ebo);
사용하여 설정할 수 있습니다 glVertexArrayElementBuffer(vao, ebo);
버전 3.0
각 속성은 구성 요소 수, 유형, 정규화, 오프셋, 스트라이드 및 VBO와 연관됩니다. VBO는 명시 적으로 매개 변수로 전달되지 않지만 대신 호출시 GL_ARRAY_BUFFER에 바인드 된 버퍼입니다.
void prepareMeshForRender(Mesh mesh){
glBindVertexArray(mesh.vao);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo);
glVertexAttribPointer (posAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, pos));//will associate mesh.vbo with the posAttrLoc
glEnableVertexAttribArray(posAttrLoc);
glVertexAttribPointer (normalAttrLoc, 3, GL_FLOAT, false, sizeof(Vertex), mesh.vboOffset + offsetof(Vertex, normal));
glEnableVertexAttribArray(normalAttrLoc);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ebo); //this binding is also saved.
glBindVertexArray(0);
}
void drawMesh(Mesh[] meshes){
foreach(mesh in meshes){
glBindVertexArray(mesh.vao);
glDrawElements(GL_TRIANGLES, mesh.vertexCount, GL_UNSIGNED_INT, mesh.indexOffset);
}
}
버전 4.3
OpenGL 4.3 (또는 ARB_separate_attrib_format)은 속성에 바인딩 된 데이터의 형식과 데이터를 제공하는 버퍼 객체 소스 사이에 구분을 만드는 정점 데이터를 지정하는 다른 방법을 추가합니다. 따라서 메쉬 당 VAO가있는 대신 정점 형식 당 VAO를 가질 수 있습니다.
각 속성은 정점 포맷 및 바인딩 포인트와 연관됩니다. 버텍스 형식은 유형, 구성 요소 개수, 정규화 여부, 데이터 시작부터 특정 정점까지의 상대 오프셋으로 구성됩니다. 바인딩 포인트는 속성이 데이터를 가져 오는 버퍼를 지정합니다. 두 가지를 분리하면 정점 형식을 다시 지정하지 않고도 버퍼를 바인딩 할 수 있습니다. 단일 바인드 호출로 데이터를 여러 속성에 제공하는 버퍼를 변경할 수도 있습니다.
//accessible constant declarations
constexpr int vertexBindingPoint = 0;
constexpr int texBindingPoint = 1;// free to choose, must be less than the GL_MAX_VERTEX_ATTRIB_BINDINGS limit
//during initialization
glBindVertexArray(vao);
glVertexAttribFormat(posAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, pos));
// set the details of a single attribute
glVertexAttribBinding(posAttrLoc, vertexBindingPoint);
// which buffer binding point it is attached to
glEnableVertexAttribArray(posAttrLoc);
glVertexAttribFormat(normalAttrLoc, 3, GL_FLOAT, false, offsetof(Vertex, normal));
glVertexAttribBinding(normalAttrLoc, vertexBindingPoint);
glEnableVertexAttribArray(normalAttrLoc);
glVertexAttribFormat(texAttrLoc, 2, GL_FLOAT, false, offsetof(Texture, tex));
glVertexAttribBinding(texAttrLoc, texBindingPoint);
glEnableVertexAttribArray(texAttrLoc);
그 다음 드로를하는 동안 vao 바인딩을 유지하고 버퍼 바인딩 만 변경합니다.
void drawMesh(Mesh[] mesh){
glBindVertexArray(vao);
foreach(mesh in meshes){
glBindVertexBuffer(vertexBindingPoint, mesh.vbo, mesh.vboOffset, sizeof(Vertex));
glBindVertexBuffer(texBindingPoint, mesh.texVbo, mesh.texVboOffset, sizeof(Texture));
// bind the buffers to the binding point
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.ebo);
glDrawElements(GL_TRIANGLES, mesh.vertexCount, GL_UNSIGNED_INT, mesh.indexOffset);
//draw
}
}