Iphone 在iOS上的OpenGL ES着色器中混合多个纹理会导致相反的行为
我有一个OpenGL ES着色器片段着色器,它使用mix函数在视频帧上放置覆盖。这是我的着色器:Iphone 在iOS上的OpenGL ES着色器中混合多个纹理会导致相反的行为,iphone,objective-c,ios,ipad,opengl-es,Iphone,Objective C,Ios,Ipad,Opengl Es,我有一个OpenGL ES着色器片段着色器,它使用mix函数在视频帧上放置覆盖。这是我的着色器: #ifdef GL_ES precision mediump float; #endif varying vec2 textureCoordinate; uniform sampler2D videoFrameY; uniform sampler2D videoFrameUV; uniform sampler2D overlay; const mat3 yuv2rgb = mat3(
#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 = 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);
}
问题是结果是相反的。因此它们看起来像这样:
- (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);
}
(来源:) 事实上,它们在两个方面是相反的。首先,文本不是蓝色的字母,而是视频显示的字母,这就是视频显示的地方。其次,文本是镜像的。镜像可能是使用顶点值的结果,但是使用相同坐标系时视频是正确的。我相信这是一个快速的重新安排,但我不知道该调整什么。谢谢 对于混合,基于
a
的mix(x,y,a)
函数在x
和y
之间插值a
为0表示所有x
,而a
为1.0表示所有y
。您正在为文本层的alpha设置关键帧,因此对于所需的覆盖,您需要按如下方式反转顺序:
gl_FragColor = mix(vec4(rgb, 1.0), ovr, ovr.a);
关于旋转,请记住,iOS后摄像头安装在横向左侧,前摄像头安装在横向右侧,因此对于纵向方向,您需要旋转传入的视频帧。您似乎正在顶点或纹理坐标中执行该旋转。您将需要第二组不旋转的纹理坐标来对覆盖图像进行采样,或者在生成其纹理时,您需要以匹配的横向左旋转绘制标签。对于混合,使用混合(x,y,a)
函数基于a
在x
和y
之间插值a
为0表示所有x
,而a
为1.0表示所有y
。您正在为文本层的alpha设置关键帧,因此对于所需的覆盖,您需要按如下方式反转顺序:
gl_FragColor = mix(vec4(rgb, 1.0), ovr, ovr.a);
关于旋转,请记住,iOS后摄像头安装在横向左侧,前摄像头安装在横向右侧,因此对于纵向方向,您需要旋转传入的视频帧。您似乎正在顶点或纹理坐标中执行该旋转。您将需要第二组纹理坐标,这些坐标不会旋转以用于对覆盖图像进行采样,或者您需要在生成纹理时以匹配的横向左旋转绘制标签。gl\u FragColor中的更改非常有效。一年过去了,我完全忘记了顶点和位置坐标是如何工作的。我知道我的四元组的位置是(-1,-1)(1,-1)(-1,1)和(1,1)。暂时忘记了文本层,对于横向正确的设备方向,我在s和d纹理坐标方面遇到了问题。它们是按什么顺序绘制的,这样我就不会得到镜像图像?对于(1,0)(0,0)(1,1)(0,1)的tex坐标,我最终得到一个在X和Y上都镜像的图像。我将使用仿射变换来担心文本层。一切都好。我读了这个。我只是把它画在纸上,然后把科技图反方向画出来。现在我有了(0,1)(1,1)(0,0)(1,0),视频在X和Y两个方向都是正确的。至于文本,我将翻转上下文。
gl_FragColor
中的更改非常有效。一年过去了,我完全忘记了顶点和位置坐标是如何工作的。我知道我的四元组的位置是(-1,-1)(1,-1)(-1,1)和(1,1)。暂时忘记了文本层,对于横向正确的设备方向,我在s和d纹理坐标方面遇到了问题。它们是按什么顺序绘制的,这样我就不会得到镜像图像?对于(1,0)(0,0)(1,1)(0,1)的tex坐标,我最终得到一个在X和Y上都镜像的图像。我将使用仿射变换来担心文本层。一切都好。我读了这个。我只是把它画在纸上,然后把科技图反方向画出来。现在我有了(0,1)(1,1)(0,0)(1,0),视频在X和Y中都是正确的。至于文本,我将翻转上下文。