У меня есть VAO с 3 VBO, содержащими модель с вершинами, нормалями и текстурными координатами.
Я намерен довольно часто менять все данные в этих VBO, примерно с частоты обновления от 500 мс до 20 мс. Новая модель, загруженная в VBO, может иметь меньше или больше треугольников, чем предыдущая. Таким образом, размер буфера также изменится.
Я не эксперт в OpenGL, поэтому я хотел бы получить несколько советов, если это возможно, о том, как улучшить мой код. На данный момент программа реализована следующим образом:
glBindVertexArray(*vao);
if (mesh->HasPositions()) {
glBindBuffer(GL_ARRAY_BUFFER, vbo_pos);
glBufferData(
GL_ARRAY_BUFFER,
3 * *point_count * sizeof (GLfloat),
points,
GL_DYNAMIC_DRAW
);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
free(points); // free our temporary memory
}
if (mesh->HasNormals()) {
glBindBuffer(GL_ARRAY_BUFFER, vbo_norm);
glBufferData(
GL_ARRAY_BUFFER,
3 * *point_count * sizeof (GLfloat),
normals,
GL_DYNAMIC_DRAW
);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(2);
free(normals); // free our temporary memory
}
if (mesh->HasTextureCoords(0)) {
glBindBuffer(GL_ARRAY_BUFFER, vbo_tex);
glBufferData(
GL_ARRAY_BUFFER,
2 * *point_count * sizeof (GLfloat),
texcoords,
GL_DYNAMIC_DRAW
);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(1);
free(texcoords); // free our temporary memory
}
РЕДАКТИРОВАТЬ:
Это текущее решение имеет проблему, заключающуюся в том, что рисунок не такой, каким должен быть.
Если моя первая модель большая (50 Мб), а я загружаю другую, немного меньшего размера (25 Мб), то часть предыдущей модели все еще нарисована.
Если первая модель маленькая (25Мб), а потом я поменял ее на большую (50Мб), то рисунок не меняется (или по крайней мере кажется, что не меняется). Если заряжаю после еще меньшего (216кб) рисунок меняется (но часть еще остается).
Я полагаю, что-то не так с моим управлением VBO?
glBufferData (...)
, он выделяет новое хранилище, а также эффективно помещает старое хранилище в список памяти, которую нужно освободить (то же самое относится к таким вещам, какglTexImage2D (...)
и т. д.). После того, как ожидающие команды не используют эту старую память, OpenGL может освободить ее. Причина, по которой вы хотели бы передатьNULL
при потере буфера, заключается в том, что вы собираетесь вызыватьglBufferSubData (...)
один или несколько раз позже. В этом случае данные настраиваются одновременно с их выделением. - person Andon M. Coleman   schedule 18.06.2014