OpenGL主循环绘制巨大的矢量点

时间:2015-03-01 17:56:41

标签: c++ opengl mfc

我有一个MFC应用程序,主绘制循环必须绘制一组巨大的点。现在,这完成如下:

void CmodguiView::OnDraw(CDC* /*pDC*/) {

  wglMakeCurrent(m_hDC, m_hRC);

  // Clear color and depth buffer bits
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  const std::vector<DensePoint> *pts;
  pts = getPts();

  if (pts) {
    glBegin(GL_POINTS);
    for (auto &&pt : *pts) {
        glColor3ub(pt.r, pt.g, pt.b);
        glVertex3f(pt.x, pt.y, pt.z);
    }
    glEnd();


    SwapBuffers(m_hDC);
  }

}

如何优化此功能?我可以避免for循环吗? 例如,是否可以直接旋转点?

1 个答案:

答案 0 :(得分:3)

瓶颈是glVertex的无数次调用。这被称为立即模式,由glBegin ... glEnd块表示,它已经被弃用了10多年。 15年前,随着顶点阵列的引入,立即模式也变得过时了。所以不要使用它。

相反,你应该使用顶点数组。您可以将它们与缓冲区对象组合以进一步提高性能。

无论如何,假设DensePoint被写为

struct DensePoint {
    GLubyte r,g,b;
    GLfloat x,y,z;
};

您可以用

替换glBegin ... glEnd块
std::vector<DensePoint> const * const pts = getPts();
if(pts) {
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);

    glColorPointer (3, GL_UNSIGNED_BYTE,
                    sizeof(DensePoint), &((*pts)[0].r));
    glVertexPointer(3, GL_FLOAT,
                    sizeof(DensePoint), &((*pts)[0].x));

    glDrawArrays(GL_POINTS, 0, pts->size());
}

请注意,这仍然使用旧的OpenGL-1.1固定功能管道并将数据保留在CPU /系统内存中,因此这将获得的吞吐量不如现代基于VBO的绘图操作。使用现代OpenGL,您还可以通过着色器自由定义顶点属性。但是从上面的代码开始就很容易就可以了。