GLKit掩盖或混合两个来自jpeg无纹理的纹理

我正在使用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的例子。 这里他们正在手动replace像素。 我想用GLKit得到相同的结果。

任何进一步的方向或指导将在这里有所帮助。 提前致谢。

GLKit是一个包含四个主要组件的框架,它们可以一起使用或分开使用:视图/视图控制器,math库,纹理加载器和效果。 我从你的问题推测,你有关于GLKBaseEffect的问题。

有人可能会说, GLKBaseEffect的人生目标是让日常事情变得简单。 它主要是OpenGL ES 1.1固定functionstream水线的替代品,以及一些常见的技巧。

你所追求的不是一个常规的固定functionstream水线任务,所以要做到这一点意味着超越了GLKBaseEffect的基本function,编写自己的着色器。 这是个坏消息。 好消息是,一旦你进入着色器世界,这很容易。 另一个好消息是,你可以期待出色的性能 – 而不是使用CPU来做CoreGraphics混合,你可以在GPU上完成。

如果您不熟悉OpenGL ES 2.0(或3.0)着色器,则“硬”部分将用自定义代码replaceGLKBaseEffect提供的客户端OpenGL ES代码和顶点着色器。 尽pipe如此,还有很多示例代码和教程。 (既然你已经关注了Ray Wenderlich的网站,我相信你会在那里find一些好的 )。你需要做的主要事情是:

  1. 将您用于glDraw命令的坐标空间中的顶点转换为剪辑空间。 对于二维的东西,这很容易,因为你可以使用相同的matrix设置,你正在做的GLKBaseEffecttransform属性。
  2. 加载你的两个纹理( GLKTextureLoader可以帮你很多),并将它们绑定到两个纹理单元。
  3. 在您的客户端代码中,将每个顶点与一些纹理坐标相关联。 (你可能已经这样做了。)
  4. 在顶点着色器中,从uniforminput中获取纹理坐标,并将它们传递给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,所以build议您使用video。 在这种情况下,你可以削减中间人 – video帧已经在GPU上处理了,把它们放在CPU上的CGImage中会让你放慢速度。 看看CVOpenGLESTexture类和GLCameraRipple示例代码,以帮助将video转换为纹理。