[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
drawing to offscreen bitmaps
- To: info-mcl@cambridge.apple.com
- Subject: drawing to offscreen bitmaps
- From: language@skdad.usask.ca
- Date: 07 Feb 1993 22:05:54 -0600
I've had a few requests for a sample of how to do drawing on an
off-screen bitmap in lisp, so here it is. It works well, and, infact,
the timing isn't that bad either for the fractal it draws (compared
to the equivalent C program):
;; file offscreen.lisp
;; Copyright (C) 1993 John Montbriand. All Rights Reserved.
;; an example of how to do drawing offscreen on
;; a bitmap and then displaying the results in a window.
;; successive generations of a dragon fractal are displayed
;; on the screen only after each is completed drawing.
(require 'quickdraw)
;; dragonr adapted to lisp from the pascal
;; found in Matthew Zeidenberg's article
;; "Snowflakes and Dragons" appearing
;; in the August 1985 issue of MacWorld (p. 127).
(defun dragonr (x1 y1 x2 y2 x3 y3 n)
"recursive dragon drawing routine"
(if (<= n 1)
(progn
(#_MoveTo x1 y1)
(#_LineTo x2 y2)
(#_LineTo x3 y3))
(let* ((x4 (truncate (/ (+ x1 x3) 2)))
(y4 (truncate (/ (+ y1 y3) 2)))
(x5 (+ x3 (- x2 x4)))
(y5 (+ y3 (- y2 y4))))
(dragonr x2 y2 x4 y4 x1 y1 (1- n))
(dragonr x2 y2 x5 y5 x3 y3 (1- n)))))
(defun dragon-fractal (h v size n)
(dragonr (+ h size) v h (- v size) (- h size) v n))
(defun do-dragons (generations)
(prog* ((extent 250) ; size of the window
(half (truncate (/ extent 2))) ; the middle
(mybits (make-bitmap 0 0 extent extent)) ; <- OFFSCREEN bitmap
(myport (make-record grafport)) ; <- OFFSCREEN grafport
(wind (make-instance 'window ; window for showing stuff
:view-position #@(10 50)
:view-size (make-point extent extent)
:window-title "off-screen"
:window-type :single-edge-box
:erase-anonymous-invalidations nil)))
(#_OpenPort myport) ; open a new grafport
(with-port myport ; and make it the current one
(#_TextFont #$geneva)
(#_TextSize 24)
(#_SetPortBits mybits) ; set the port's bitmap
(#_PortSize extent extent) ; and set the new size
(dotimes (i generations)
;; clear the offscreen bitmap
(#_EraseRect (pref myport grafport.portrect))
;; draw indicator
(dotimes (j generations)
(#_MoveTo (+ (* j 8) 16) 1)
(#_Line 0 (if (= i j) 10 5)))
;; draw our picture
(dragon-fractal half half (truncate (/ half 2)) i)
(with-pstrs ((s "MCL2 Dragon"))
(#_MoveTo (+ 7 i) (- extent 7 i))
(#_DrawString s))
;; copy the offscreen drawing to the screen
(copy-bits mybits
(pref (wptr wind) windowrecord.portbits)
(pref myport grafport.portrect)
(pref (wptr wind) windowrecord.portrect)
:patCopy)))
(#_ClosePort myport) ; close the port + cleanup
(dispose-record myport)
(dispose-record mybits)
(sleep 2)
(window-close wind)))
;; here's a test run (may take up to 20 seconds on older macs):
(do-dragons 14)
;; end of file offscreen.lisp