C ++ GLSL Несколько IBO в ВАО

Я разрабатываю небольшой проект, и я использую 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);
}

0

Решение

Каждый 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, То есть на одну ВАО допускается только 1 IBO.

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

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

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

1

Другие решения


По вопросам рекламы [email protected]