Re: [lispbuilder] proper usage and requirements of surfaces in lispbuilder-sdl

31 views
Skip to first unread message

Elliott Slaughter

unread,
Nov 9, 2014, 2:49:26 PM11/9/14
to lispb...@googlegroups.com
Sorry for the slow response. I'm digging myself out of work right so my response time might be quite long.

I believe the key to your questions are understanding surfaces. If I'm misunderstanding your issue, please let me know.

You should think of surfaces like arrays. They're basically places where you can store (image) data temporarily, before moving that data elsewhere (e.g. the screen). As you've noticed in your other email, there are different kinds of surfaces, which (potentially) live in different places: software surfaces are guaranteed to live in main memory, while hardware surfaces may potentially live on the GPU (though note that they're aren't guaranteed to, and in fact that GPU itself may be on the same die as the CPU).

As you have noticed, you don't *need* surfaces in a lot of cases, except the surface which represents the display itself (which is usually bound to *default-surface*). But you may still want to use surfaces anyway, for convenience, or potentially for performance. For example:

1. Some operations like sdl:load-image are very slow, because they need to load the image from disk, decode it, etc. You probably don't want to call sdl:load-image on every time through your main loop, and you definitely don't want to call it for every single object at every time step. Instead, you would load the image once, save it in a variable somewhere (you don't need a draw call because load-image already returns a surface), and use that surface instead of loading the image over again.

2. For some composite operations, like mirroring, you would prefer not to do the work required to draw the scene multiple times (e.g. 2 for a single mirror). So instead, you can make a new surface, draw everything to that surface, and then blit that to the screen as many times as you want, and potentially save a factor of N in the draw time (depending on how expensive the original operation was).

Transparency should be automatic as long as any intermediate surfaces have transparency enabled. This means making sure load-image understands the transparency of the source image, and making sure that any other surfaces you use have transparency enabled. The screen itself doesn't need transparency, but it would probably help to make sure it follows the same format (bit depth) as your images to avoid any conversions during blitting.

If you have any other questions, please let me know (and hopefully I won't be quite so abysmally slow at answering this time).

On Sun, Sep 21, 2014 at 7:30 AM, Başar Erdivanlı <berdi...@gmail.com> wrote:
I can't display a transparent png image (created with GIMP, checkerboard visible) with lispbuilder-sdl. I read some of the sdl and lispbuilder-sdl docs and checked the forums, the questions of David O'toole and answers of Luke J Crook, but I still need a solid explanation for how to use the surfaces in plain language.

As far as I understood:

1) To display a rectangle using draw-box, we don't need to draw or create a surface, since the draw-box function uses the *default-surface* already:

(defun draw-box (rect &key
(clipping nil) (surface *default-surface*)
(color *default-color*) (stroke-color nil) (alpha nil))
(unless surface
(setf surface *default-display*))
........

2) Now I think that, we should also not need to draw or create a surface to load an image, because wiki page says:
"SURFACE represents an area of graphical memory that can be drawn or rendered to, for example the video framebuffer or an image that is loaded from disk."

3) And the load-image function also converts an image to a surface (taken from this file):

    (defun load-image (filename)
(sdl:convert-surface :surface (sdl:load-image (merge-pathnames filename sdl:*default-asset-path*)
:color-key (sdl:color :r 255 :g 255 :b 255))
:free t))

4) But all the examples I found use draw-surface or create-surface to load an image, like (sdl:draw-surface (sdl:load-image "xx.png")). I'm confused by the blitting and alpha transparency.

5) To display a transparent image on top of another surface, we need to copy the non-transparent pixels onto the destination surface, and merge the transparent pixels with the corresponding pixels of the destination surface.
    Unfortunately, I tried all the combinations of :surface-alpha and :channel-alpha and it didn't work. I'm probably overdoing something wrong.

Can someone explain me the requirements for displaying a complex scene including transparent images on top of each other, step by step?

I would appreciate sth simple like this:

To display a background color, you don't need to create a surface, as the *default-surface* is enough. Just clear-display with a sdl color.
To display a colored shape, you don't need to create a surface, as the draw-shape functions use the *default-surface* already.
To display an image, you need a surface first (really?), so draw-surface, and then, load-image on top of it.
  

--
You received this message because you are subscribed to the Google Groups "Lispbuilder" group.
To unsubscribe from this group and stop receiving emails from it, send an email to lispbuilder...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Elliott Slaughter

"Don't worry about what anybody else is going to do. The best way to predict the future is to invent it." - Alan Kay
Reply all
Reply to author
Forward
0 new messages