1

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

#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);

}

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

截屏
(来源:c.tro.pe

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

4

1 回答 1

1

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

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

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

于 2012-06-06T16:23:50.920 回答