Speed problems using NSImage. Solution?
Speed problems using NSImage. Solution?
- Subject: Speed problems using NSImage. Solution?
- From: "Matt R" <email@hidden>
- Date: Sat, 6 Jan 2007 19:42:37 -0800
Hi everyone, I'm new to both Cocoa and the list, so please excuse any
ignorance on my part. I was hoping I could get some advice from you all on
finding a fast, straightforward alternative to using NSImage and NSViews. To
learn cocoa I've started making a small little arcade game. In the game, the
player sees a boat (from overhead) which can rotate in a circle and drive
around the ocean.
My problem is that despite all my attempts to optimize my code, I can't seem
to obtain any reasonable speeds using NSImage drawInRect. The results are
ridiculously slow. (18fps with CPU maxed out) I have a 800x600 ocean image
which is tiled (x4) underneath the boat to allow the ocean to move and
repeat itself as the player drives around. Ontop of those, I tile another
image (x4) which sway according to a 'ripple' variable. The top tiles are
slighty transparent and produce a wavy effect as they move over the bottom
ocean images. Finally, ontop of that I have a boat which is rotated with an
NSAffineTransform according to a directional degree.
There are other drawing operations that go on for some other graphical
stuff, but after testing all of this exhaustively I've found that by far,
the large 800X600-sized images eat up the most processor power (the
NSAffineTransform also slows it down quite a bit too, tho). I can eliminate
almost all other drawing with virtually no cure for the slowness. It's those
big NSImage calls at the beginning that break the thing.
To be honest, I'm a little disturbed that only 8 drawInRect calls can
completely demolish my 2GHZ g5. I have a gig of ram, and I'm getting frame
rates of 18 and 19.
Once again I'm sorry if I'm overlooking something painfully obvious, but
I've tried my darndest to optimize this code (as well as reduce the file
size of the images, try different drawing operations within inRect,etc.
etc.), and I've looked into re-writing it with OpenGL, but because I am
still new to Cocoa, I'm realizing that redoing it in OpenGL is currently
beyond my abilities. I'm having a tough time believing that only 8 NSImage
calls are too much for a 2GHZ g5.
Can anyone offer any advice or explain why this is so slow?
I pasted some of the main portions of code below, if that is useful at all.
Thank you~
-Matt
/* Draw water
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
tempX = [controller getPlayerBoatX];
tempY = [controller getPlayerBoatY];
tx = (tempX % 800);
ty = (tempY % 600);
//as the boat moves, tile 4 images seamlessly underneath the boat.
[oceanImg drawInRect:NSMakeRect(tx,ty,800,600) fromRect:NSZeroRect
operation:NSCompositeCopy fraction:1];
[oceanImg drawInRect:NSMakeRect(tx,ty-600,800,600) fromRect:NSZeroRect
operation:NSCompositeCopy fraction:1];
[oceanImg drawInRect:NSMakeRect(tx-800,ty-600,800,600)
fromRect:NSZeroRect operation:NSCompositeCopy fraction:1];
[oceanImg drawInRect:NSMakeRect(tx-800,ty,800,600) fromRect:NSZeroRect
operation:NSCompositeCopy fraction:1];
tx = (tempX % 848) + rippleDX;
ty = (tempY % 648) + rippleDY;
[oceanWaveImg drawInRect:NSMakeRect(tx-24,ty-24,848,648)
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:.4];
[oceanWaveImg drawInRect:NSMakeRect(tx-24,ty-648-24,848,648)
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:.4];
[oceanWaveImg drawInRect:NSMakeRect(tx-848-24,ty-648-24,848,648)
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:.4];
[oceanWaveImg drawInRect:NSMakeRect(tx-848-24,ty-24,848,648)
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:.4];
//
/* Draw boat
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
//first rotate appropriately, then draw:
//boat PNG is 100x180pixels
NSImage *targetImg;
NSAffineTransform *at;
NSSize atSize;
at = [NSAffineTransform transform];
atSize = NSMakeSize(200,200);
targetImg = [[NSImage alloc] initWithSize:atSize];
[targetImg lockFocus];
xHalf = (atSize.width/2.0);
yHalf = (atSize.height/2.0);
[at translateXBy:xHalf yBy:yHalf];
bAngle = [controller getPlayerBoatAngle];
[at rotateByDegrees:-bAngle];
[at translateXBy:-xHalf yBy:-yHalf];
[at concat];
[boatImg drawInRect:NSMakeRect(50,10,100,180) fromRect:NSZeroRect
operation:NSCompositeSourceOver fraction:1];
[targetImg unlockFocus];
[targetImg
drawInRect:NSMakeRect(300+((rippleDX-25)/2.0),200+((rippleDY-25)/2.0),200,200)
fromRect:NSZeroRect operation:NSCompositeSourceOver fraction:1.0];
[targetImg release];/////////////release <--------
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden