iphone - 在 iOS 上的 OpenGL ES 着色器中混合多个纹理会导致相反的行为

标签 iphone objective-c ios ipad opengl-es

我有一个 OpenGL ES Shader 片段着色器,它使用混合函数在视频帧上放置一个叠加层。这是我的着色器:

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 textureCoordinate;

uniform sampler2D videoFrameY; 
uniform sampler2D videoFrameUV;
uniform sampler2D overlay;

const mat3 yuv2rgb = mat3(
                          1,        1,          1,
                          0,        -.21482,    2.12798,
                          1.28033,  -.38059,    0
                          );

void main() {
    
    vec3 yuv;
    vec4 ovr;
    
    yuv.x = texture2D(videoFrameY, textureCoordinate).r;
    yuv.yz = texture2D(videoFrameUV, textureCoordinate).rg - vec2(0.5, 0.5);
    ovr = texture2D(overlay, textureCoordinate);
    
    vec3 rgb = yuv2rgb * yuv;
    
    gl_FragColor = mix(ovr, vec4(rgb, 1.0), ovr.a);
} 

没有覆盖纹理,提供 gl_FragColor 这个:

gl_FragColor = vec4(rgb, 1.0);

工作正常,我的视频显示出来了。现在我从 CATextLayer 创建我的覆盖纹理,如下所示:

- (void)generateOverlay {
    CATextLayer *textLayer = [CATextLayer layer];
    [textLayer setString:@"Sample test string"];
    [textLayer setFont:(__bridge CFStringRef)@"Helvetica"];
    [textLayer setFontSize:(_videoHeight / 6)];
    [textLayer setAlignmentMode:kCAAlignmentLeft];
    [textLayer setBounds:CGRectMake(0, 0, _videoWidth, _videoHeight)];
    
    CGSize layerSize = textLayer.bounds.size;
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    void *imageData = malloc(layerSize.height * layerSize.width * 4);
    CGContextRef context = CGBitmapContextCreate(imageData, layerSize.width, layerSize.height, 8, 4 * layerSize.width, colorspace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorspace);
    CGContextClearRect(context, CGRectMake(0, 0, layerSize.width, layerSize.height));
    CGContextTranslateCTM(context, 0, layerSize.height - layerSize.height);
    [textLayer renderInContext:context];
    
    glActiveTexture(GL_TEXTURE2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, layerSize.width, layerSize.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
    
    CGContextRelease(context);
    free(imageData);

}

问题是结果是颠倒的。因此,它们看起来像这样:

screenshot
(来源:c.tro.pe)

事实上,它们在两个方面是颠倒的。首先,不是蓝色被 alpha 输出和视频显示,文本是 alpha,这就是视频显示的地方。第二,文字是镜像的。镜像可能是使用顶点值的结果,但是使用相同坐标的视频是正确的。我确定这是一个快速的重新排列,但我不确定要调整什么。谢谢!

最佳答案

对于混合,mix(x, y, a) 函数根据a< 在xy 之间进行插值。 0 的 a 给你所有的 x,而 1.0 的 a 给你所有的 y。您正在关闭文本层的 alpha,因此对于您想要的叠加层,您需要按如下方式反转顺序:

gl_FragColor = mix(vec4(rgb, 1.0), ovr, ovr.a);

关于旋转,请记住 iOS 后置摄像头横向安装在左侧,前置摄像头横向安装在右侧,因此对于纵向方向,您需要旋转传入的视频帧。您似乎在顶点或纹理坐标中执行该旋转。您将需要第二组未旋转的纹理坐标以用于对叠加图像进行采样,或者您需要在生成其纹理时以匹配的横向左旋转绘制标签。

关于iphone - 在 iOS 上的 OpenGL ES 着色器中混合多个纹理会导致相反的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10908710/

相关文章:

iphone - 我可以使用 Instruments "profile"使用测试用例来解决内存泄漏问题吗? (即集中运行在定义的代码区域)

ios - 通用链接中的根页面

ios - UIScrollView 页面内容无法正常工作 - iOS

iphone - iPhone 上的 YAJL

iphone - 如何在我没有子类化的 UITabBarController 上隐藏 UITabBar?

objective-c - 如何打破 Objective-C 中的 block 循环?

objective-c - 按下 UIButton 时调用 UITextField 的 textFieldDidEndEditing

android - 用户可以在 iphone 或 android 的 html 5 应用程序中看到 js 调用的来源吗?

iphone - 如何使用 UITableViewController 创建布局(附加为图像)

ios - UIImageView/TableFooterView 上的两个 init 方法