수색…


소개

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

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
    }
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow