c++ - OpenGL 主循环绘制巨大的点 vector

标签 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 循环吗? 例如,是否可以直接旋转点?

最佳答案

瓶颈是glVertex的无数次调用。这称为立即模式,由 glBegin ... glEnd block 表示,它已被弃用超过 10 年。即时模式也随着 15 年前顶点数组的引入而过时。所以不要使用它。

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

无论如何,假设DensePoint写成

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

您可以将 glBegin...glEnd block 替换为

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,您可以通过着色器自由定义顶点属性。但是从上面的代码开始很容易。

关于c++ - OpenGL 主循环绘制巨大的点 vector ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28797000/

相关文章:

c++ - c++ mfc dev 中可以使用的最大图标大小是多少?

c++ - C++ 中带有模板的装饰器模式

c++ - 可变参数模板成员函数的部分特化

OpenGL 规范规定 `GLint` 必须是 32 位宽,但 gl.xml 天真地将其定义为 `int` 而不是 `int32_t` 。为什么?

c++ - 使用 C++ 自动执行下拉菜单、按钮点击

c++ - CString::LoadString() 是线程安全的吗?

c++ - 编译器错误,使用静态多态性模拟 C++ 单元测试

c++ - 专门化模板类的功能

opengl - GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 始终返回 0

c++ - glActiveTexture 默认行为不符合预期