[SDL] surface transparency

John Popplewell john at johnnypops.demon.co.uk
Mon Jul 29 19:58:00 PDT 2002


Hi,

a few things (tested on Windows):

1) you need to use SDL_DisplayFormatAlpha() to do what you require.

2) you are assuming that SDL_DisplayFormatAlpha() converts the surface
to 16bpp if the screen is 16bpp. The documentation hints at this but
that isn't what happens. (see the printf's in the attached code)

3) your get/put pixel routines only work for 16bpp and don't lock
the surfaces. This is ok for 'backbuffer' where you explicitly request
a SW_SURFACE, but who knows what kind of surface is actually returned
by SDL_DisplayFormatAlpha()?

cheers,
John.


----- Original Message -----
From: "Chris Thielen" <chris at luethy.net>
To: <sdl at libsdl.org>
Sent: Tuesday, July 30, 2002 1:23 AM
Subject: Re: [SDL] surface transparency


> On Mon, 2002-07-29 at 00:41, Krata wrote:
> > Hi,
> >  can you provide some sourcecode? Shortest example which shows
unexpected
> > behaviour?
> > Krata
>
> Yea. To avoid being rude I'll put up a sample PNG w/ transparency at
> http://chris.luethy.net/sample.png and not attach it here. Just put that
> sample in the same directory as the source code and you're see a blue
> screen, this image blitted in the upper left, but the entire background
> is black. I'd like to not have that black. The black isn't there in the
> original image. Also, is this somehow related to a misuse of
> SDL_DisplayFormatAlpha()? The colors in this example are very messed up
> when I use SDL_DisplayFormatAlpha, so I'll assume I'm not
> reading/writing the pixels correctly. Can anybody help?
>
> sample source:
> -------------- start --------------
> #include <stdio.h>
> #include <stdlib.h>
>
> #include "SDL.h"
> #include "SDL_image.h"
>
> inline Uint16 getpixel(SDL_Surface *surface, int x, int y);
> inline void putpixel(SDL_Surface *surface, int x, int y, Uint16 color);
>
> int main(void) {
> int i, j;
> SDL_Surface *screen, *temp, *sample, *backbuffer;
> SDL_Rect src, dest;
>
> if (SDL_Init(SDL_INIT_VIDEO) != 0) {
> fprintf(stderr, "Could not init SDL: %s\n", SDL_GetError());
> return (-1);
> }
>
> atexit(SDL_Quit);
>
> screen = SDL_SetVideoMode(320, 200, 16, 0);
> if (screen == NULL) {
> fprintf(stderr, "Could not set video mode.\n");
> return (-1);
> }
>
> temp = IMG_Load("sample.png");
> if (temp == NULL) {
> fprintf(stderr, "Could not load sample.png");
> return (-1);
> }
> sample = SDL_DisplayFormat(temp); // colors are messed up when using
> SDL_DisplayFormatAlpha() ... maybe related?
> SDL_FreeSurface(temp);
>
> backbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE, sample->w, sample->h,
> screen->format->BitsPerPixel, screen->format->Rmask,
> screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
>
> for (j = 0; j < sample->h; j++) {
> for (i = 0; i < sample->w; i++) {
> Uint16 color;
> color = getpixel(sample, i, j);
> putpixel(backbuffer, i, j, color);
> }
> }
>
> dest.x = 0;
> dest.y = 0;
> dest.w = 320;
> dest.h = 200;
> SDL_FillRect(screen, &dest, SDL_MapRGB(screen->format, 0, 0, 255));
>
> src.x = 0;
> src.y = 0;
> src.w = backbuffer->w;
> src.h = backbuffer->h;
> dest = src;
>
> SDL_BlitSurface(backbuffer, &src, screen, &dest);
>
> SDL_Flip(screen);
>
> SDL_Delay(5000);
>
> SDL_FreeSurface(sample);
> SDL_FreeSurface(backbuffer);
>
> return (0);
> }
>
> inline Uint16 getpixel(SDL_Surface *surface, int x, int y) {
> Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x *
> surface->format->BytesPerPixel;
> return (*(Uint16 *)p);
> }
>
> inline void putpixel(SDL_Surface *surface, int x, int y, Uint16 color) {
> Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x *
> surface->format->BytesPerPixel;
> *(Uint16 *)p = color;
> }
> -------------- end --------------
>
> > On 28 Jul 2002, Chris Thielen wrote:
> >
> > > Hello everybody,
> > > I was wondering if there's anything special that I need to do to read
> > > the transparency off an image when directly handling the image. Using
> > > IMG_Load I've brought in a PNG w/ transparency (used for the empty
> > > spaces around a non-rectangular sprite) and I do various
transformations
> > > operations w/ it, such as rotating it. Using code like the following,
I
> > > read pixels and put pixels, but, what do I have to do to also get that
> > > transparency? Using the following method and performing
transformations,
> > > the non-pixels (those that shouldnt appear) come out black. How do I
> > > read the transparency as well? Thanks.
> > >
> > > inline Uint16 getpixel(SDL_Surface *surface, int x, int y) {
> > > Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x *
> > > surface->format->BytesPerPixel;
> > > return (*(Uint16 *)p);
> > > }
> > >
> > > inline void putpixel(SDL_Surface *surface, int x, int y, Uint16 color)
{
> > > Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x *
> > > surface->format->BytesPerPixel;
> > > *(Uint16 *)p = color;
> > > }
> > >
> > > -- chris (chris at luethy.net)
>
>
> _______________________________________________
> SDL mailing list
> SDL at libsdl.org
> http://www.libsdl.org/mailman/listinfo/sdl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: src.zip
Type: application/x-zip-compressed
Size: 1386 bytes
Desc: not available
URL: <http://lists.libsdl.org/pipermail/sdl-libsdl.org/attachments/20020729/93a6eec6/attachment-0008.bin>


More information about the SDL mailing list