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

Reply via email to