views:

215

answers:

4

I am looking for a raster graphics framework for Mac OS X. Specifically, I want some kind of view that I can manipulate (at least conceptually) like a matrix of pixels. My program will generate the pixel data programmatically.

QuickDraw fits that description nicely, but is deprecated. As far as I can tell, there is nothing equivalent in Core Graphics. Am I missing something?

A plain C framework would be preferable to an Objective-C one, but I'm not too fussy.

+3  A: 

What about dividing the width and height of the view by itself, then draw width x height squares? You could just use an NSPoint and increase it by one until it hits width x height.

Sneakyness
This might seem like a pain, but it is honestly much more powerful than you're expecting it to be, and you will be very happy with the results.
Sneakyness
Wouldn't that be very wasteful? For each pixel, you'd have to update the four CGFloats that make up the rectangle, and call CGContextFillRect (or NSRectFill, or NSBezierPath's fillRect: method). Seems like an awful lot of work just to draw a single pixel, no?
sarnesjo
Those rects are only going to be defined once, nothing changes location or size-wise after that.
Sneakyness
That is actually a good point.
sarnesjo
There's a reason this has two upvotes, you know.
Sneakyness
In Adium, we switched from filling one row at a time (about 16 rows per contact) to using CGShading, because filling hundreds of one-pixel-tall paths was very slow. Filling thousands or millions of one-pixel-square paths would be even slower.
Peter Hosey
+3  A: 

QD was deprecated because there is no way to do implement it efficiently with the the current generation of fully composited UIs and GPU HW. For that reason there is nothing quite like QD on the system, and there won't be. Allowing direct access to the backing store forces at best forces a lot more bus transactions to and from the GPU, and at worst may prevent a texture from being loaded on to the card itself, and some cases may cause software fallbacks.

It is clear there are sometimes reasons people need pixel level access to a backing store, so there are some mechanisms to do it, but there are no real convenience methods and if you can find some way to avoid it you should. If you can't avoid it you can use CoreGraphics to create a bitmap context using CGBitmapContextCreate where you have access to the backing store and can manipulate the backing store directly. It is not simple to work with, and it is slow.

Louis Gerbarg
Thank you for the detailed explanation. When you say slow, just how slow are we talking about here? For instance, would it be slower than drawing one rectangle per pixel, as proposed above? (A stupid question, no doubt, but graphics programming really is not my forte.)
sarnesjo
It depends exactly what you are doing, it will probably be faster than the doing a rect per pixel. Thinking about it a bit more you could set it up as an OpenGL surface and do something similiar. That would give you better control and you could map the textures for decent performance so long as you never read the pixels, just write to them.
Louis Gerbarg
+2  A: 

The Simple Directmedia Layer has pixel access. It may be over kill as it is a porting library, but the entire API is in plain C. I do not know what it uses as an underlying MacOS API uses. Best to check the website to see if it is suitable for your purposes.

Alternatively, you could use OpenGL textures.

Marc
I did look at SDL, and I think it may be a good solution in the general case. However, the program I'm working on is part of a course I'm taking, and I need to keep dependencies on external libraries down to the absolute minimum.
sarnesjo
A: 

The best way to do this is Core Image. It's designed for working with pixels, and it's very fast because it lets you do the work on the graphics card.

Peter Hosey