OpenGL ES 1.1 - alpha 蒙版

Posted

技术标签:

【中文标题】OpenGL ES 1.1 - alpha 蒙版【英文标题】:OpenGL ES 1.1 - alpha mask 【发布时间】:2012-07-26 09:55:08 【问题描述】:

我正在使用 OpenFrameworks 和 OpenGL ES 1.1 开发 iPad 应用程序。我需要显示带有 alpha 通道的视频。为了模拟它,我有一个 RGB 视频(没有任何 alpha 通道)和另一个仅包含 alpha 通道的视频(在每个 RGB 通道上,因此白色部分对应于可见部分,黑色对应于不可见部分)。每个视频都是一个 OpenGL 纹理。

在 OpenGL ES 1.1 中没有着色器,所以我找到了这个解决方案(这里:OpenGL - mask with multiple textures):

glEnable(GL_BLEND);
// Use a simple blendfunc for drawing the background
glBlendFunc(GL_ONE, GL_ZERO);
// Draw entire background without masking
drawQuad(backgroundTexture);
// Next, we want a blendfunc that doesn't change the color of any pixels,
// but rather replaces the framebuffer alpha values with values based
// on the whiteness of the mask. In other words, if a pixel is white in the mask,
// then the corresponding framebuffer pixel's alpha will be set to 1.
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO);
// Now "draw" the mask (again, this doesn't produce a visible result, it just
// changes the alpha values in the framebuffer)
drawQuad(maskTexture);
// Finally, we want a blendfunc that makes the foreground visible only in
// areas with high alpha.
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
drawQuad(foregroundTexture);

这正是我想要做的,但 glBlendFuncSeparate() 在 OpenGL ES 1.1(或 ios)中不存在。我正在尝试用 glColorMask 来做,我发现了这个:Can't get masking to work correctly with OpenGL

但它也不好用,我猜是因为他的蒙版纹理文件包含一个“真实”的 alpha 通道,而不是我的。

【问题讨论】:

glColorAlpha 不存在;你是说 glColorMask 吗? 哦,是的,抱歉,我刚刚更正了。 alpha 通道从何而来? 从包含 RGBA 通道的初始视频中,我们导出了两个 H.264 视频:第一个只有 RGB 通道,第二个包含 RGB 通道的 alpha 信息。 【参考方案1】:

我强烈建议您改为计算单个 RGBA 纹理。

这将更容易,更快(因为您每帧发送 2 个 RGBA 纹理 - 是的,您的 RGB 纹理实际上是由硬件以 RGBA 编码的,而 A 被忽略)

glColorMask 对您没有帮助,因为它只是说“完全打开或关闭此通道”。

glBlendFuncSeparate 如果你有它可以帮助你,但同样,它不是一个好的解决方案:你通过发送两倍的数据量来破坏你的(非常有限的)iphone带宽。

更新:

由于您使用的是 OpenFrameworks,并且根据其源代码(https://github.com/openframeworks/openFrameworks/blob/master/libs/openFrameworks/gl/ofTexture.cpp 和 https://github.com/openframeworks/openFrameworks/blob/master/libs/openFrameworks/video/ofVideoPlayer.cpp):

使用 ofVideoPlayer::setUseTexture(false) 以便 ofVideoPlayer::update 不会将数据上传到显存; 使用ofVideoPlayer::getPixels获取视频数据 在 RGBA 纹理中交错结果(您可以使用 GL_RGBA ofTexture 和 ofTexture::loadData) 使用 ofTexture::Draw 进行绘制(无论如何,这都是 ofVideoPlayer 所做的)

【讨论】:

问题是我的纹理是视频,我们选择了 H.264 编解码器,因为文件比动画编解码器文件轻得多......这将是唯一的“繁重”过程,所以我猜它应该可以工作,即使在 iPad 上,你不觉得吗? 您必须在某处使用 glTexSubImage2D 将视频发送到 OpenGL,对吗?还是视频直接解码到显存? 我正在使用 OpenFrameworks 类的视频播放器:openframeworks.cc/documentation/video/ofVideoPlayer.html#draw。它通过 quicktime 加载到电影文件中,所以我猜视频是在视频内存中解码的,我错了吗? 是的,请参阅更新的答案和github.com/openframeworks/openFrameworks/blob/master/libs/… 非常感谢您的回答,但这是我所做的,而且在 iPad 上非常慢...为了交错,我为每个像素都做。这就是为什么我认为如果我用 OpenGL 混合函数来做,它会在 GPU 中做,而且效率会更高......

以上是关于OpenGL ES 1.1 - alpha 蒙版的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL:在背景图像上使用蒙版绘制颜色

OpenGL/GLSE alpha 遮罩

OpenGL ES - 如何批量渲染 500 多个带有不同 alpha、旋转和缩放的粒子?

在OpenGL中将掩码应用于视频

Alpha蒙版边界框透明与其他alpha蒙版冲突/覆盖。 XNA

OpenGL ES iOS 入门实例