[imago-devel] IMAGO images <-> SDL surfaces
Vladimir Sedach
sedachv at cpsc.ucalgary.ca
Mon Oct 18 02:55:53 UTC 2004
Hello,
I've written a bit of code to shuffle between IMAGO images and SDL
surfaces. It should be fast enough to do manipulations on small
sprites in real-time on a reasonably fast machine. It only works on
RGB(A) images, since I found the overhead for extracting/packing
channels is too high. Blitting versions forthcoming when I need them
and figure out a good interface for specifying rectangles (for some
reason SDL's don't seem all that good to me).
(large-ish) screenshot:
http://members.shaw.ca/vsedach/imago_sdl_screen.png
Vladimir
PS - I think my version of with-surface-lock is more correct than the
one that comes with cl-sdl right now (sdl:with-locked-surface).
Here are the goodies:
(declaim (optimize (speed 3) (safety 0)))
(defmacro with-surface-lock (surface &body body)
(let ((surf (gensym "surface-lock-")))
`(let ((,surf ,surface))
(when (/= 0 (sdl:lock-surface ,surf))
(error "Couldn't lock SDL surface ~A" ,surf))
(unwind-protect (progn , at body) (sdl:unlock-surface ,surf)))))
(defun convert-to-image (surface)
"Given a 24 or 32-bit depth SDL surface, returns an IMAGO RGB image
of the same width and height and RGB pixel contents."
(assert (or (= 24 (sdl:pixel-format-bits-per-pixel (sdl:surface-format
surface)))
(= 32 (sdl:pixel-format-bits-per-pixel (sdl:surface-format
surface)))))
(let* ((width (sdl:surface-w surface)) (height (sdl:surface-h surface))
(image (make-instance 'imago:rgb-image :width width :height height))
(image-array (imago:image-pixels image)))
;; Note that on 32 bit machines, width and height are 32 bit ints
(declare (type fixnum width height) (type (simple-array (unsigned-byte
32) (* *)) image-array))
(with-surface-lock surface
(dotimes (y height)
(declare (type fixnum y))
(dotimes (x width)
(declare (type fixnum x))
(setf (aref image-array y x) (sdl:get-pixel surface x y)))))
image))
(defmethod convert-to-surface ((image imago:rgb-image) &optional (depth 24))
"Given an IMAGO RGB image, returns an SDL surface of <depth> bit color
depth and the same width and height."
(let* ((width (imago:image-width image)) (height (imago:image-height
image))
(image-array (imago:image-pixels image))
(surface (sdl:create-rgb-surface sdl:+swsurface+ width height depth 0 0
0 0)))
(declare (type fixnum width height) (type (simple-array (unsigned-byte
32) (* *)) image-array))
(with-surface-lock surface
(dotimes (y height)
(declare (type fixnum y))
(dotimes (x width)
(declare (type fixnum x))
(sdl:faster-draw-pixel surface x y (aref image-array y x)))))
surface))
More information about the Imago-devel
mailing list