[comp.sys.mac.programmer] Drawing to an off screen bitmap

deragon@CADMAN.NYU.EDU (John Deragon) (12/07/89)

	Hi folks,
		I did a small animation program on my Macintosh Plus,
it steps through drawing each frame. The problem is, it is damn slow. 
So, faced with the fact that I cant afford a Mac IIcx, I would like to
know how I could draw frames to an offScreen Bitmap. I am using LSC 4.0.

Any code fragments, or suggestions would be greatly appreciated.

		John.

austing@Apple.COM (Glenn L. Austin) (12/07/89)

In article <8912070531.AA07560@cadman.nyu.edu> deragon@CADMAN.NYU.EDU (John Deragon) writes:
>
>
>	Hi folks,
>		I did a small animation program on my Macintosh Plus,
>it steps through drawing each frame. The problem is, it is damn slow. 
>So, faced with the fact that I cant afford a Mac IIcx, I would like to
>know how I could draw frames to an offScreen Bitmap. I am using LSC 4.0.

Drawing into an off-screen bitmap is really quite easy, if you follow a few
rules:
 1) The rowBytes *MUST* be even, otherwise the odd rows will be on an odd byte,
    just begging for address error!
 2) Create a GrafPort for the new bitmap by calling OpenPort on a newly created
    GrafPort structure.
 3) Save the current port and restore it after drawing to the off-screen port.

Some sample code (off the top of my head) in C:

  BitMap  bm;  /* my off-screen bitmap */
  GrafPort gp; /* my "off-screen grafport */
  GrafPtr  oldPort; /* the current grafport */

  GetPort(&oldPort); /* get the current grafport */
  bm.rowBytes = 20; /* 160 pixels / 8 = 20 bytes */
  SetRect(&bm.bounds, 0, 0, 160, 160); /* set the bounds (remember l,t,r,b!) */
  bm.baseAddr = NewPtrClear(20 * 160); /* create a new ptr and zero the mem */
  if (bm.baseAddr != nil)
  {
    OpenPort(&gp); /* create a new, temporary grafport */
    SetPortBits(&bm); /* set the portBits to our bitmap */
    BlockMove((Ptr) &bm.bounds, (Ptr) &gp.portRect, sizeof(Rect)); /* copy the
             rect from bounds to portRect */
    RectRgn(gp.visRgn, &bm.bounds); /* change the visRgn to match */
    SetPort(&gp); /* use our port */

    /* Draw in the port just like you would draw on the screen! */

    SetPort(oldPort); /* restore the old port before disposing our ours! */
    ClosePort(&gp); /* so that the port memory is released */

    /* The bitmap is still around and valid and contains a bitmap of your */
    /* drawing */

    DisposPtr(bm.baseAddr); /* dispose of our off-screen bitmap memory */
  }

It couldn't be easier!  In fact, if you specify the port returned from the
PrOpenPage with a SetPort, you are actually drawing into an off-screen bitmap
that gets sent to the printer!

-- 
-----------------------------------------------------------------------------
| Glenn L. Austin               | "Have you ever danced with the devil in   | 
| Communications Toolbox Hacker |  in the pale moonlight?" -The Joker       |
| Apple Computer, Inc.          | "You made me!" -Batman                    | 
| Internet:   austing@apple.com |-------------------------------------------|
| AppleLink:  AUSTIN.GLENN      | All opinions stated above are mine --     |
| Bellnet:    (408) 974-0876    |                who else would want them?  |
-----------------------------------------------------------------------------