0

I'm working on a game in which the game elements look like they are made of construction paper. To achieve the texture effect I blend a fullscreen image at the end of each draw cycle:

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();

    // ... draw things ... //

    CGContextSetBlendMode(context, kCGBlendModeHardLight);
    CGContextSetAlpha(context, 0.4);
    CGContextDrawImage(context, [self frame], [paperTexture CGImage]);
}

Unfortunately this makes the frame rate drop from 60 to what feels like ~10. Is there a better way to do this without moving into OpenGL?

Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
Hooper
  • 195
  • 13
  • Do you have to use a hard light blend mode, or could you get close enough by overlaying a semitransparent view or layer on the entire screen which contains your paper texture? That would avoid the expensive `CGContextDrawImage()` call, and would let you not have to redraw your Quartz content every frame, but be able to cache that in separate views or layers. – Brad Larson Apr 02 '12 at 00:34
  • I actually just finished converting all my graphics code to Core Animation and, like you suggest, I used an overlay layer to achieve the effect. Plain opacity doesn't look nearly as good as hard light, but it works. Heres hoping Apple implements the CA Layer filter API... – Hooper Apr 02 '12 at 18:18
  • Even so, they'd use Core Image for the filters, and [in my benchmarks](http://stackoverflow.com/a/6628208/19679), Core Image is not all that fast on iOS right now. My GPUImage is significantly faster, but it does require your source material to get into an OpenGL ES texture somehow. Perhaps something like Cocos2d could render to a texture-backed FBO and that texture could be fed into GPUImage for hard light blend compositing (the paper image would only need to be uploaded once). That would be the fastest way I could think of achieving this exact effect. – Brad Larson Apr 02 '12 at 19:32

1 Answers1

0

Check out GPUImage which I've heard has really good performance.

wbyoung
  • 22,383
  • 2
  • 34
  • 40
  • Not quite what I'm looking for. That looks like it is for running filters on images in memory. I need to overlay onto the screen, not an image. Yes, I could create an image from the current CGContext, filter that, and then draw it back onto the screen, however I think any GPU benefits would be canceled by all the image creation, copy and draw. – Hooper Mar 30 '12 at 18:44