【问题标题】:How can I efficiently draw thousands of vertices?如何有效地绘制数千个顶点?
【发布时间】:2010-09-21 01:49:57
【问题描述】:

我目前正在编写一个交互式模拟器,它显示粒子系统的演变。我正在使用 Visual Studio 在 Windows 7 32 位上进行开发。

目前,我有一个函数可以在屏幕上绘制所有粒子,看起来像这样:

void Simulator::draw()
{
    glColor4f(255, 255, 255, 0);
    glBegin();
    for (size_t i = 0; i < numParticles; i++)
        glVertex3dv(p[i].pos);
    glEnd();       
}

这很好用,而且全部用于测试,但速度慢得离谱。如果我在屏幕上有 200 个粒子,不做任何其他计算(只是重复调用 draw()),我会得到大约 60 fps。但如果我使用 1000 个粒子,则运行速度仅为 15 - 20 fps。

我的问题是:如何更快地绘制粒子?我的模拟以相当不错的速度运行,并且在某个点上它实际上被绘图阻止(!)。

【问题讨论】:

  • 我设法找到了过度缓慢的根源。在错误的地方调用了一个耗时的方法。它随着粒子数量的二次方缩放,并在每帧更新时被调用。修复后,可以毫无问题地绘制 5000 个粒子。

标签: c++ performance opengl 3d


【解决方案1】:

您应该做的第一个优化是放弃 glBegin/glEnd(立即模式)并移至顶点数组 (VA) 和顶点缓冲区对象 (VBO)。

您可能还想研究 Point Sprites 来绘制粒子。

【讨论】:

    【解决方案2】:

    这会不受欢迎,我知道我讨厌它:

    改用 Direct X。

    自 Vista 以来,微软一直在试图扼杀 openGL。 所以他们很可能会让你的生活变得困难。

    所以如果 ALL ELSE 失败,您可以尝试使用 DirectX。

    但是,是的,其他人怎么说:

    -使用 DrawArrays / 元素

    -使用顶点缓冲区

    -使用点精灵

    -您可以制作一个顶点着色器,这样您就不必每帧更新整个顶点缓冲区(您只需存储初始设置,如初始化位置、初始化速度、初始化时间,然后是恒定重力,然后着色器可以计算基于单个更新的全局常量“当前时间”的每帧当前位置)

    -如果它是 open GL 中的设置(就像在 directX 中一样),请确保您使用的是硬件顶点处理)

    【讨论】:

      【解决方案3】:

      首先,如果您还没有这样做,请禁用桌面窗口管理器——它会在速度上产生巨大的差异(基本上,在打开它的情况下,您将获得大量的软件渲染)。

      其次,虽然我怀疑你是否需要这样做,但你可以改用 glDrawArraysglDrawElements(在众多可能性中只是其中的几个)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-04
        • 1970-01-01
        • 2014-08-19
        • 2011-09-15
        • 2016-04-26
        • 1970-01-01
        相关资源
        最近更新 更多