在OpenGL中快速绘制线条

时间:2014-03-28 20:01:46

标签: c++ performance opengl

我正在开发一个需要绘制大量数据的项目,因为它是由ADC获取的......在1600像素宽的显示器上,每帧有50,000行。它在具有2007-ish Quadro FX 570的系统上运行良好,但基本上无法跟上具有Intel HD 4000级芯片的机器上的数据。数据负载是每通道5次采样的每秒40次接收的32通道200Hz数据。换句话说,卡只需要达到每秒40帧或更好。

我对所有32个通道使用单个VBO,每个通道有10,000个顶点。 VBO基本上被视为每个通道的一系列环形缓冲区。当数据进入时,我根据使用的时间尺度对其进行抽取。因此,基本上,它跟踪每个通道的最小值/最大值。当为单个像素列接收到足够的数据时,它会为每个通道设置VBO中的下两个顶点并渲染一个新帧。

我使用glMapBuffer()访问数据一次,更新所有通道,使用glUnmapBuffer,然后根据需要进行渲染。

我提前手动计算变换矩阵(使用以非通用方式计算的正交变换以减少乘法),并且顶点着色器看起来像:

#version 120

varying vec4 _outColor;

uniform vec4 _lBound=vec4(-1.0);
uniform vec4 _uBound=vec4(1.0);
uniform mat4 _xform=mat4(1.0);

attribute vec2 _inPos;
attribute vec4 _inColor;

void main()
{
    gl_Position=clamp(_xform*vec4(_inPos, 0.0, 1.0), _lBound, _uBound);
    _outColor=_inColor;
}

_lBound_uBound_xform制服每个频道更新一次。所以,每帧32次。夹具用于将某些通道限制在屏幕上的y坐标范围内。

片段着色器很简单:

#version 120

varying vec4 _outColor;

void main()
{
    gl_FragColor=_outColor;
}

还有其他东西呈现在屏幕上;通道标签,例如,使用四边形和纹理图集;但是gDEBugger中的分析似乎表明线渲染占用了每帧的绝大部分时间。

尽管如此,对我来说,50,000行看起来并不是一个非常大的数字。

所以,在所有这些之后,问题是:加速画线是否有任何技巧?我尝试将它们渲染到模板缓冲区,然后剪切一个四边形,但速度较慢。我想过将线条绘制到纹理上,绘制带纹理的四边形。但是,由于不断上传大型纹理,这似乎不可扩展甚至更快。我看到了一种将y值存储在单行纹理中的技术,但这看起来更像是内存优化而不是速度优化。

3 个答案:

答案 0 :(得分:1)

由于驱动程序可能需要将GPU与CPU同步,因此映射VBO可能会降低速度。更高效的方法是将数据丢弃到GPU上,这样CPU和GPU可以更独立地运行。

  • 每次重新创建VBO,使用STATIC_DRAW创建
  • 如果您需要映射数据,请不要映射为可读(GL_WRITE_ONLY)

答案 1 :(得分:0)

如果你只是滚动一个折线图(GDI样式),只需在CPU上绘制新列并使用glTexSubImage2D更新纹理中的单个列。将其绘制为一对四边形并更新st坐标以处理滚动/包装。

如果您需要一直更新所有行,请使用GL_DYNAMIC_DRAW创建的VBO并使用glBufferSubData更新缓冲区。

答案 2 :(得分:0)

谢谢大家。我终于决定在renderbuffers支持的framebuffers之间进行blitting。效果很好。许多建议使用纹理,如果我最终需要在数据后面绘制,我可能会在未来走这条路。