Anthony, I'll add a faster WITH-PIXEL macro which will hopefully provide some speedup. CL-GD has something similar and I have been meaning to add this to lispbuilder-sdl for a while.
DRAW-PIXEL is faster than DRAW-POINT. DRAW-POINT will lock the surface prior to calling DRAW-PIXEL on each pixel write. You can speed things up yourself by placing all DRAW-PIXEL calls within a WITH-POSSIBLE-LOCK-AND-UPDATE. You really need to make sure that the SDL surface is locked prior to hitting the surface directly with a pixel read or write, and then unlocked following the write. This is what WITH-POSSIBLE-LOCK-AND-UPDATE does. I think that I have used the rotozoom function in sdl_gfx before and it worked for me. I'll try find the example code I used and post it to the group. With regards to accessing a foreign byte array directly from CFFI (as opposed to a single element of the array at a time), I believe that this is actively being worked on by the CFFI developers. Once we have this then most of the functionality provided by sdl_gfx can be replaced by Lisp code. Right now the functions performed by sdl_gfx are WAY faster than anything that can be done in Lisp. And thanks for the rotation function below. - Luke Anthony Fairchild wrote: > Hello again, > > I've been playing around with lispbuilder-SDL a bit over the holiday > weekend and started writing a simple jigsaw puzzle-like game. I'm > very happy with what I have so far but I'm running into a bit of > slowness when doing direct pixel manipulation, specifically, rotating > images. > > I've looked at rotozoom in the gfx package and I could not get it to > work (that's another issue altogether). Rotating an image seemed like > such a simple thing anyway, so I wrote my own > likely-over-complicated-and-bug-ridden function to do it: > > (defun rotate-surface(surf degrees) > "rotates a surface 0, 90, 180, or 270 degrees" > (let ((degrees (normalize-degrees degrees))) > (if (= 0 degrees) > ;; in the case of 0 degrees, just copy surface > (copy-and-blit-surface surf) > ;; else do rotation > (let* ((w (surf-w surf)) > (h (surf-h surf)) > (new-w (if (or (= 90 degrees) > (= 270 degrees)) h w)) > (new-h (if (or (= 90 degrees) > (= 270 degrees)) w h)) > (new-surf (create-surface new-w new-h :surface surf)) > (new-x (case degrees > (90 #'(lambda (x y)(declare (ignore x))(+ (1- > new-w) (- 0 y)))) > (180 #'(lambda (x y)(declare (ignore y))(+ (1- > new-w) (- 0 x)))) > (270 #'(lambda (x y)(declare (ignore x))y)))) > (new-y (case degrees > (90 #'(lambda (x y)(declare (ignore y))x)) > (180 #'(lambda (x y)(declare (ignore x))(+ (1- > new-h) (- 0 y)))) > (270 #'(lambda (x y)(declare (ignore y))(+ (1- > new-h) (- 0 x))))))) > (loop :for x :from 0 :to (1- w) > :do (loop :for y :from 0 :to (1- h) > :do (let ((pixel (get-pixel :position (point x y) > :surface surf))) > (draw-pixel (funcall new-x x y) > (funcall new-y x y) :surface new-surf > :color (sdl:sdl_maprgb > (sdl:pixelformat sdl:*default-surface*) > (color-r pixel) > (color-g pixel) > (color-b pixel))) > #+nil(draw-point :position (point (funcall new-x x > y) > (funcall new-y x y)) > :surface new-surf > :color pixel)))) > new-surf)))) > > The function works but the pixel access is very slow. It seems like I > need some way to directly access the surface memory, perhaps with a 2d > byte array? Maybe this is not possible with CFFI, or maybe the > solution is right under my nose and I'm not seeing it. > > Any suggestions? > > Thanks, > > Anthony > _______________________________________________ > application-builder mailing list > application-builder@lispniks.com > http://www.lispniks.com/mailman/listinfo/application-builder > _______________________________________________ application-builder mailing list application-builder@lispniks.com http://www.lispniks.com/mailman/listinfo/application-builder