Re: Speed problems using NSImage. Solution?
Re: Speed problems using NSImage. Solution?
- Subject: Re: Speed problems using NSImage. Solution?
- From: "douglas a. welton" <email@hidden>
- Date: Sun, 7 Jan 2007 13:19:41 -0500
Hi Matt,
My suggestion would be that you look into doing this using a Quartz
Composition with QCView and friends. Check out the documentation and
several sample code projects at the ADC site.
As an alternate, approach, I'd suggest that you look at doing this
with CIImages using CIFilters like CIRippleTransition()
Both options will move the drawing stuff off to the GPU and (most
assuredly) give you a better frame rate for rendering.
later,
douglas
On Jan 6, 2007, at 10:42 PM, Matt R wrote:
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