【发布时间】:2014-04-16 04:59:19
【问题描述】:
我正在开展一个项目,该项目需要绘制大量数据,因为这些数据是由 ADC 获取的……在 1600 像素宽的监视器上每帧 50,000 行。它在配备 2007-ish Quadro FX 570 的系统上运行良好,但基本上无法跟上配备 Intel HD 4000 级芯片的机器上的数据。数据负载是 32 个通道的 200 Hz 数据,每通道每秒 40 次分批接收 5 个样本。因此,换句话说,该卡只需要达到每秒 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 值存储在单行纹理中的技术,但这似乎更像是内存优化而不是速度优化。
【问题讨论】:
-
致投票结束这个问题的人:这完全是关于 opengl 标记内 StackOverflow 的主题。
-
啊。最大纹理大小是个问题。
-
不确定这是否可行,但我将尝试使用多个帧缓冲区和 glBlitFramebuffer()。基本上,将渲染数据从 Framebuffer A 复制到 Framebuffer B 移动一个,渲染新行,然后输出 Framebuffer B。有点像 FBO 中的纹理概念,但绕过了纹理大小限制。
-
您发出多少个 OpenGL 绘图调用来渲染所有线条?加速 OpenGL 性能的一个好方法是在 /very/ 大的顶点缓冲区中构建线条几何图形,然后在一次绘制调用中将其全部提交给显卡。您可以轻松预测必要的顶点缓冲区大小,因此这应该不是问题。通常的限制确实是绘制调用的数量,而不是实际的数据带宽。
-
我是否理解正确,您基本上是在尝试渲染像 this 这样的东西,只有 32 个轨道?如果是这种情况,不要画线,每个通道画一个四边形并使用像素着色器。
标签: c++ performance opengl