C++ GLSL Множественный IBO в VAO

Я разрабатываю небольшой проект и использую VBO, IBO и VAO, у меня есть массив вершин и их соответствующие индексы массива, я делаю то же самое с материалами (поскольку одна и та же вершина может иметь другой материал с другой стороны ) но эта ссылка в ВАО тоже ничего не отображает. Для каждого отдельного VAO должен быть IBO?

Во вложении мой код, в котором отправка данных на gpu и рендер соответственно!

Буду признателен за помощь, привет :)

void Upload(){
    GLuint ibo[2], vbo[3];

    glGenBuffers(3, vbo);
    glGenBuffers(2, ibo);
    glGenVertexArrays(1, vao);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); //Vertices
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vec3), vertices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); //Normales
    glBufferData(GL_ARRAY_BUFFER, vertex_normal.size()*sizeof(vec3), vertex_normal.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, v_indices.size()*sizeof(GLuint), v_indices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vbo[2]); //Material
    glBufferData(GL_ARRAY_BUFFER, materials.size()*sizeof(Material), materials.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices.size()*sizeof(GLuint), m_indices.data(), GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    glBindVertexArray(vao[0]);
    //Vertices:
    glEnableVertexAttribArray(attrib_vertex);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
    glVertexAttribPointer(attrib_vertex, 3, GL_FLOAT, GL_FALSE, 0, 0);
    //Normales:
    glEnableVertexAttribArray(attrib_normal);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
    glVertexAttribPointer(attrib_normal, 3, GL_FLOAT, GL_FALSE, 0, 0);
    //IBO:
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]);

    //Materiales:
    for(int i=0; i<5; ++i)
        glEnableVertexAttribArray(attrib_material+i);
    glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
    glVertexAttribPointer(attrib_material, 4, GL_FLOAT, GL_FALSE, sizeof(Material), NULL);
    glVertexAttribPointer(attrib_material+1, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, diffuse));
    glVertexAttribPointer(attrib_material+2, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, specular));
    glVertexAttribPointer(attrib_material+3, 4, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, emission));
    glVertexAttribPointer(attrib_material+4, 1, GL_FLOAT, GL_FALSE, sizeof(Material), (void*)offsetof(Material, shininess));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]);

    //Desactivando todo:
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glDisableVertexAttribArray(attrib_vertex);
    glDisableVertexAttribArray(attrib_normal);
    for(int i=0; i<5; ++i)
        glDisableVertexAttribArray(attrib_material+i);
}
void Draw(){
    glBindVertexArray(vao[0]);
    glDrawElements(GL_TRIANGLES, v_indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

person Josseline Perdomo    schedule 05.08.2014    source источник


Ответы (1)


Каждый VAO хранит значение текущего GL_ELEMENT_ARRAY_BUFFER_BINDING.

Это сохраненное значение устанавливается при вызове glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[0]) и glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo[1]).

Проблема с вашим кодом заключается в том, что ваш второй вызов glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,...) перезаписывает значение, сохраненное первым вызовом. Это происходит потому, что каждый VAO может хранить только одно значение для GL_ELEMENT_ARRAY_BUFFER_BINDING. То есть на один VAO допускается только 1 НПА.

Некоторые решения, которые я предлагаю:

  • Вы можете хранить данные материала по-другому, чтобы они соответствовали индексам в вашей сетке. Это может означать, что вам нужно продублировать данные материала.
  • Вы можете сохранить данные материала в юниформ-буферах, а затем сохранить индекс данных материала в юниформ-буфере в качестве атрибута вершины для каждой вершины.
  • Похоже, ваш материал определяет информацию об освещении. Возможно, вы могли бы разделить рендеринг на несколько проходов. (т. е. окружающий проход, рассеянный проход, зеркальный проход...) Метод рендеринга, такой как отложенное освещение, сделает это не проблемой.
  • Вы можете объединить индексы вершин и материалов в один большой IBO. (Может работать в сочетании с другими методами, которые я упомянул.)
  • Возможно, вы сможете использовать glVertexAttribDivisor, если ваши данные соответствуют шаблону.

В любом случае, главная проблема заключается в том, что вы можете иметь только 1 IBO на VAO. Вам придется проявить творческий подход, чтобы найти решение, которое подходит для вашего использования. Удачи!

person Nicolas Louis Guillemot    schedule 05.08.2014
comment
Большое спасибо за вашу помощь и извините за задержку в спасибо!! :) - person Josseline Perdomo; 01.09.2014