1

我想使用 OpenGL 混合两个(或更多)16 位音频流,我需要一些帮助

基本上我想要做的是将音频数据放入我绘制到帧缓冲区对象然后读回的纹理中。这不是问题,但是以给出正确结果的方式绘制数据有点问题。

我基本上有两个问题。

  1. 为了通过绘图混合数据,我需要使用混合(alpha = 0.5),但是结果不应该有任何 alpha 通道。因此,如果我渲染到例如格式为 RGB 的帧缓冲区,alpha 混合仍然可以按我的预期工作,并且生成的 alpha 不会被写入 fbo?(我想避免必须为每个渲染通道回读 fbo)

纹理 |sR|sG|sB|

帧缓冲(之前)|dR|dG|dB|

帧缓冲(后)|dR*0.5+sR*0.5|dG*0.5+sG*0.5|dB*0.5+sB*0.5|

  1. 音频样本是有符号的 16 位整数值。是否可以通过这种方式进行签名计算?还是我需要先在 cpu 上将值转换为无符号,绘制它们,然后在 cpu 上再次使它们签名?

编辑:

我有点不清楚。我的硬件仅限于 OpenGL 3.3 硬件。我宁愿不使用 CUDA 或 OpenCL,因为我已经将 OpenGL 用于其他东西。

每个音频样本将在单独的通道中渲染,这意味着它必须与已经渲染到帧缓冲区的内容“混合”。问题是如何将像素着色器的输出写入帧缓冲区(据我所知,这种混合无法通过可编程着色器访问,并且必须使用 glBlendFunc)。

编辑2:

每个音频样本将在不同的通道中渲染,因此着色器中一次只有一个音频样本可用,这意味着它们需要在 FBO 中累积。

foreach(var audio_sample in audio_samples)
     draw(audio_sample);

不是

for(int n = 0; n < audio_samples.size(); ++n)
{
      glActiveTexture(GL_TEXTURE0 + n);
      glBindTexture(audio_sample);
}
draw_everything();
4

3 回答 3

4

坦率地说,你为什么不直接使用可编程像素着色器呢?

您必须使用 OpenGL 1 固定功能管道吗?

我只是使用在签名的 16 位灰度线性纹理上运行的可编程着色器。

编辑:

foreach(var audio_sample in audio_samples) 
 blend FBO1 + audio_sample => FBO2
 swap FBO2, FBO1 

它应该同样快,如果不是更快(感谢流式传输管道)。

于 2010-12-15T14:54:52.340 回答
2

我同意 QDot。但是,您能否告诉我们一些您面临的硬件限制?如果您有合理的现代硬件,我什至建议您使用 CUDA 或 OpenCL 路线,而不是通过 OpenGL。

于 2010-12-15T14:57:36.250 回答
1
  1. 即使目标缓冲区没有 alpha,您也应该能够进行混合。也就是说,渲染到非二次方大小(rgb16 = 6bytes/pixel)通常会导致性能损失。

  2. 签名不是典型的渲染目标格式,但它确实存在于 OpenGL 4.0 规范中(表 3.12,称为 RGB16_SNORM 或 RGB16I,取决于您是否需要标准化表示)。

附带说明一下,您glBlendFunc(GL_CONSTANT_ALPHA,GL_ONE_MINUS_CONSTANT_ALPHA)甚至不必指定每个像素的 alpha。不过,这可能不适用于所有 GL 实现。

于 2010-12-15T16:15:05.327 回答