Поиск…


Вступление

Объект Vertex Array хранит, как opengl должен интерпретировать набор VBOs.

По сути, это позволит вам избежать вызова glVertexAttribPointer каждый раз, когда вы хотите визуализировать новую сетку.

Если вы не хотите иметь дело с VAO, вы можете просто создать его и связать с ним во время инициализации программы и притвориться, что они не существуют.

Синтаксис

  • void glEnableVertexAttribArray (GLuint attribIndex);

  • void glDisableVertexAttribArray (GLuint attribIndex);

  • void glVertexAttribPointer (GLuint attribIndex, размер GLint, тип GLenum, нормализованный GLboolean, шаг GLsizei, указатель const GLvoid *);

  • void glVertexAttribFormat (GLuint attribIndex, размер GLint, тип GLenum, нормализованный GLboolean, относительный набор GLuint);

  • void glVertexAttribBinding (GLuint attribIndex, GLuint bindingIndex);

  • void glBindVertexBuffer (GLuint bindingIndex, буфер GLuint, смещение GLintptr, шаг GLintptr);

параметры

параметр подробности
attribIndex расположение атрибута вершины, которому будет передан массив вершин
размер количество компонентов, которые нужно вытащить из атрибута
тип Тип данных атрибута C ++ в буфере
нормированный следует ли сопоставлять целочисленные типы с диапазоном с плавающей запятой [0, 1] (для неподписанных) или [-1, 1] (для подписанных)
указатель смещение байта в буфер до первого байта данных атрибута (отбрасывается в void* по причинам, устаревшим)
смещение базовый байт смещен от начала буфера до места, где начинаются данные массива
relativeOffset смещение к определенному атрибуту относительно смещения базы для буфера
шагать количество байтов от одной вершины до следующей
буфер буферный объект, в котором хранятся массивы вершин
bindingIndex индекс, к которому будет привязан объект исходного буфера

замечания

Отдельная настройка формата VAO может взаимодействовать с glVertexAttribPointer (последняя определяется в терминах первой). Но при этом вы должны быть осторожны.

Отдельная версия формата атрибута имеет эквиваленты прямого доступа (DSA) в 4.5. Они будут иметь одинаковые параметры, но вместо использования связанного VAO измененное VAO передается явно. При использовании DSA индексный буфер для glDrawElements может быть установлен с помощью 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