繁体   English   中英

GLKit从jpegs没有alphas掩盖或混合2个纹理

[英]GLKit masking or blending 2 textures both from jpegs no alphas

我正在使用GLKit,并且在24 fps时我需要采用CGImageRef(无alpha图层)并将另一个CGImageRef(无alpha图层)作为遮罩(黑白图像)并将结果渲染为GLKit纹理。

起初我尝试了这种方法:

CGImageRef actualMask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                          CGImageGetHeight(maskRef),
                                          CGImageGetBitsPerComponent(maskRef),
                                          CGImageGetBitsPerPixel(maskRef),
                                          CGImageGetBytesPerRow(maskRef),
                                          CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef masked = CGImageCreateWithMask(imgRef, actualMask);

虽然在将结果UIImage分配给UIImageView时会起作用,但这不适用于GLKit纹理(不应用蒙版)。 但是,如果我使用以下方法重绘图像:

UIImage *maskedImg = [UIImage imageWithCGImage:masked];
UIGraphicsBeginImageContext(maskedImg.size);
[maskedImg drawInRect:CGRectMake(0, 0, maskedImg.size.width, maskedImg.size.height)];
UIImage* resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

生成的图像将被掩盖并在GLKit纹理中正确渲染。 但是,这会将iPhone 4S的性能降低到大约6 fps。

我尝试过这种掩盖方法但没有成功。

我试过没有Core Graphics并使用GLKit混合,如Ray Wenderlich这个例子中所示。 但是,这需要掩模上的alpha透明度,这对我来说是一个交易破坏者。

我还找到了一个有趣的例子,说明了我想用一个名为AVAnimator的库和一个名为KittyBoom的例子。 他们在这里手动替换像素。 我想用GLKit得到同样的结果。

任何进一步的指导或指导都会对此有所帮助。 提前致谢。

GLKit是一个包含四个主要组件的框架,可以一起使用或单独使用:视图/视图控制器,数学库,纹理加载器和效果。 我从您的问题中推测您对GLKBaseEffect有疑虑的问题。

有人可能会说GLKBaseEffect在生活中的目的是让日常事务变得简单。 它主要是OpenGL ES 1.1固定功能管道的替代品,也是它的一些常见技巧。

你所追求的不是一个例行的固定功能管道任务,所以做得好意味着超越GLKBaseEffect的基本功能并编写你自己的着色器。 这是坏消息。 好消息是,一旦你进入着色器世界,这很容易。 另一个好消息是,您可以期待出色的性能 - 而不是使用CPU来进行CoreGraphics混合,您可以在GPU上进行。

如果您不熟悉OpenGL ES 2.0(或3.0)着色器,那么“硬”部分正在替换GLKBaseEffect提供的客户端OpenGL ES代码和顶点着色器以及执行相同操作的自定义代码。 不过,有很多示例代码和教程。 (因为你一直关注Ray Wenderlich的网站,我相信你会在那里找到一些好的 。)你需要做的主要事情是:

  1. 将用于glDraw命令的坐标空间中的顶点转换为剪辑空间。 对于2D东西,这非常简单,因为您可以使用与GLKBaseEffecttransform属性相同的矩阵设置。
  2. 加载你的两个纹理( GLKTextureLoader可以在这里帮助你很多)并将它们绑定到两个纹理单元。
  3. 在客户端代码中,将每个顶点与一些纹理坐标相关联。 (你可能已经这样做了。)
  4. 在顶点着色器中,从uniform输入中获取纹理坐标,并将它们传递给varying输出。 (除非您因某种原因想要转换坐标,否则无需执行任何其他操作。)

完成所有设置之后,实际完成您所效果的部分非常简单,并且它都在您的片段着色器中:

// texture units bound in client code
uniform sampler2D colorTexture;
uniform sampler2D maskTexture;

// texture coordinate passed in from vertex shader
// (and automatically interpolated across the face of the polygon)
varying mediump vec2 texCoord;

void main() {
    // read a color from the color texture
    lowp vec3 color = texture2D(colorTexture, texCoord).rgb;

    // read a gray level from the mask texture
    // (the mask is grayscale, so we only need one component
    //  of its color because the others are the same)
    lowp float maskLevel = texture2D(maskTexture, texCoord).r;

    // use the gray level from the mask as the alpha value in the output color
    gl_FragColor = vec4(color, maskLevel);
}

此外,既然你提到24 fps这样做,它表明你正在使用视频。 在这种情况下,你可以删除中间人 - 视频帧已经在GPU上处理,并将它们放在CPU上的CGImages中只会减慢你的速度。 查看CVOpenGLESTexture类和GLCameraRipple示例代码,以帮助将视频转换为纹理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM