Увеличенная загрузка сбоев страниц является второстепенным признаком действительно плохого цикла рендеринга. Современные графические процессоры работают с (большими / -ными) буферами вершинных и индексных данных. При использовании промежуточного режима glBegin
… glEnd
драйвер вынужден создавать такие буферы на месте. Чтобы ускорить процесс, существует множество эвристик, в том числе драйверы, которые также помечают страницы так, чтобы они получали уведомления, если содержимое страниц изменяется, и буферы создаются заново только при необходимости.
Перепишите его, чтобы использовать индексированные треугольники в массиве вершин. В этом режиме лучше всего работают графические процессоры и драйверы OpenGL.
Даже массив вершин на стороне клиента значительно ускорит процесс, поскольку драйвер может затем объединить буферную копию. Конечно, лучше всего было бы, если бы вы просто поместили m_vertices
в объект буфера вершин.
#include <vector>
#include <utility>
// overloaded wrappers to deduce the
// GL type from the type of the index buffer vector
namespace gl_wrap {
void DrawElements(
GLenum mode, GLsizei count,
std::vector<GLubyte> const &idx_buffer,
size_t offset )
{
glDrawElements(mode, count, GL_UNSIGNED_BYTE, idx_buffer.data()+offset);
}
void DrawElements(
GLenum mode, GLsizei count,
std::vector<GLushort> const &idx_buffer,
size_t offset )
{
glDrawElements(mode, count, GL_UNSIGNED_SHORT, idx_buffer.data()+offset);
}
void DrawElements(
GLenum mode, GLsizei count,
std::vector<GLuint> const &idx_buffer,
size_t offset )
{
glDrawElements(mode, count, GL_UNSIGNED_INT, idx_buffer.data()+offset);
}
}
void MyGLWidget::paintGL() {
glBegin(GL_TRIANGLE_STRIP);
std::vector<std::pair<size_t,size_t>> strips;
size_t i_prev = 0, i = 0;
for( auto idx : m_indices ){
++i;
if( idx < 0 ){
strips.push_back(std::make_pair(i_prev, i-i_prev));
i_prev = i;
}
}
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_DOUBLE, 0, m_vertices.data());
for( auto const &s : strips ){
gl_wrap::DrawElements(GL_TRIANGLE_STRIP, m_indices.data(), s.second, s.first);
}
glDisableClientState(GL_VERTEX_ARRAY);
}