Surface transparency

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 (@Christopher_Thielen)

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)

Hi,
can you provide some sourcecode? Shortest example which shows unexpected
behaviour?
KrataOn 28 Jul 2002, Chris Thielen 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 Mon, 2002-07-29 at 00:41, Krata wrote:

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 (@Christopher_Thielen)

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@luethy.net (Christopher Thielen)
To:
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.bin

  1. 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)

Does SDL_DisplayFormatAlpha() always return a 32bpp surface?

  1. 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()?

Is there any way to gaurantee SDL_DisplayFormatAlpha() returns a
SW_SURFACE?

– chris (@Christopher_Thielen)On Mon, 2002-07-29 at 19:56, John Popplewell wrote:

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 (@Christopher_Thielen)


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Hi,

Does SDL_DisplayFormatAlpha() always return a 32bpp surface?

Good question. Looking at the source (SDL_video.c) it would
appear that it does! There is a hard-coded ‘32’ used here:

SDL_AllocFormat(32, rmask, gmask, bmask, amask);

Of course, this isn’t mentioned in the docs (is it?) so presumably
it could change.

Is there any way to gaurantee SDL_DisplayFormatAlpha() returns a
SW_SURFACE?

Looking at the source again, it appears that if SDL_SetVideoMode()
returns a SW surface then SDL_DisplayFormatAlpha() can only return
SW surfaces. Also, it will only create HW surfaces with an alpha
channel if HW alpha blits are supported.

Looks like your lucks in :slight_smile:

cheers,
John.> ----- Original Message -----

From: chris@luethy.net (Christopher Thielen)
To:
Sent: Tuesday, July 30, 2002 6:00 AM
Subject: Re: [SDL] surface transparency

On Mon, 2002-07-29 at 19:56, John Popplewell wrote:

  1. 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)

Does SDL_DisplayFormatAlpha() always return a 32bpp surface?

  1. 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()?

Is there any way to gaurantee SDL_DisplayFormatAlpha() returns a
SW_SURFACE?

– chris (chris at luethy.net)

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


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Does SDL_DisplayFormatAlpha() always return a 32bpp surface?

Good question. Looking at the source (SDL_video.c) it would
appear that it does! There is a hard-coded ‘32’ used here:

SDL_AllocFormat(32, rmask, gmask, bmask, amask);

Of course, this isn’t mentioned in the docs (is it?) so presumably
it could change.

Is there any way to gaurantee SDL_DisplayFormatAlpha() returns a
SW_SURFACE?

Looking at the source again, it appears that if SDL_SetVideoMode()
returns a SW surface then SDL_DisplayFormatAlpha() can only return
SW surfaces. Also, it will only create HW surfaces with an alpha
channel if HW alpha blits are supported.
Looks like your lucks in :slight_smile:

Thanks John, I’ve got everything working now. :slight_smile:

– chris (@Christopher_Thielen)On Mon, 2002-07-29 at 23:14, John Popplewell wrote:

----- Original Message -----
From: “Chris Thielen” <@Christopher_Thielen>
To:
Sent: Tuesday, July 30, 2002 6:00 AM
Subject: Re: [SDL] surface transparency

On Mon, 2002-07-29 at 19:56, John Popplewell wrote:

  1. 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)

Does SDL_DisplayFormatAlpha() always return a 32bpp surface?

  1. 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()?

Is there any way to gaurantee SDL_DisplayFormatAlpha() returns a
SW_SURFACE?

– chris (@Christopher_Thielen)

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 (@Christopher_Thielen)


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

how would i do this in 16bpp? SDL_DisplayFormatAlpha() returns a 32-bit
surface, but I’d only like to blit 16-bit surfaces. so, w/
SDL_CreateRGBSurface() i can make a 16-bit surface, but whenever I use
the code that was attached to this (the raw get and put functions) it
doesn’t quite work. How do I keep the transparency but end up w/ my
final surface (the one I use putpixel on) as a 16bpp surface?

– chris (@Christopher_Thielen)On Mon, 2002-07-29 at 19:56, John Popplewell wrote:

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” <@Christopher_Thielen>
To:
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 (@Christopher_Thielen)


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Hi Guys
A surface or an image AFAIK can not be faded, as we cant change the
Alpha of a surface with transparent bits, so i use this i wrote to allow me
to fade a temp SW surface such as an image, the output from SDL_TTF
Blended or Rotozoom, and i thought i would share it, it steps through the
whole surface adjusting the alpha byte of each pixel. Yes it could be a lot
faster, like only adjusting the alpha byte and stepping over the colour
bytes, but it does what it says on the tin, so for now here it is.

void SurfaceTrans(SDL_Surface * Src,double PercentTrans)
{
Uint8 Sbpp = Src->format->BytesPerPixel;
Uint8 Sbits;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int amask = 0x000000ff;
int cmask = 0xffffff00;
int Shift = 0;
#else
int amask = 0xff000000;
int cmask = 0x00ffffff;
int Shift = 24;
#endif
int x,y;
Uint32 Pixels;
Uint32 Alpha;
for(y=0;yh;y++)
{
for(x=0;xw;x++)
{
Sbits = ((Uint8 )Src->pixels+(ySrc->pitch)+(x
Sbpp));
Pixels = *((Uint32 )(Sbits));
Alpha = (Pixels&amask)>>Shift;
Alpha
=PercentTrans;
*((Uint32 *)(Sbits)) = (Pixels & cmask)|(Alpha<<Shift);
}
}
}

i hope this works for you, and if anyone wants to make it faster , please
post the code.

Trish x

Patricia Curtis <patricia.curtis gmail.com> writes:

One thing I can think of straight away is this. Since you already have #if’d
code, why not do it to the shift operations as well as the definitions? A shift
of 0 doesn’t achieve much, but does waste a few cycles if you don’t need to do
it. Here’s my re-write (note that the Shift variable can disappear in one case,
too):

void SurfaceTrans(SDL_Surface * Src,double PercentTrans)
{
Uint8 Sbpp = Src->format->BytesPerPixel;
Uint8 Sbits;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
int amask = 0x000000ff;
int cmask = 0xffffff00;
// Shift no longer needed in this case, since it is not used!
#else
int amask = 0xff000000;
int cmask = 0x00ffffff;
int Shift = 24;
#endif
int x,y;
Uint32 Pixels;
Uint32 Alpha;
for(y=0;yh;y++)
{
for(x=0;xw;x++)
{
Sbits = ((Uint8 )Src->pixels+(ySrc->pitch)+(x
Sbpp));
Pixels = *((Uint32 )(Sbits));
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
Alpha = Pixels & mask;
#else
Alpha = (Pixels&amask)>>Shift;
#endif
Alpha
=PercentTrans;

#if SDL_BYTEORDER == SDL_BIG_ENDIAN
*((Uint32 *)(Sbits)) = (Pixels & cmask)|Alpha;
#else
*((Uint32 *)(Sbits)) = (Pixels & cmask)|(Alpha<<Shift);
#endif
}
}
}

Only problem is that the code is a lot less readable… But if speed is of the
essence…

-J

If your surface doesn’t contain an alpha channel you could get away
with using SDL_SetAlpha maybe?
http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fSetAlpha

This willl allow your function to work with non RGBA surfaces.
If it does contain an alpha channel you could fall back to your routine.

It could be as simple as:
if( Src->format->Amask ) {
SDL_SetAlpha(Src,SDL_SRCALPHA, (Uint8)(SDL_ALPHA_OPAQUE * PercentTrans));
return;
}

I don’t have a compiler here to test this on unfortunately, apologies
in advance if this doesn’t work.On 16/07/07, Patricia Curtis <patricia.curtis at gmail.com> wrote:

Hi Guys
A surface or an image AFAIK can not be faded, as we cant change the
Alpha of a surface with transparent bits, so i use this i wrote to allow me
to fade a temp SW surface such as an image, the output from SDL_TTF Blended
or Rotozoom, and i thought i would share it, it steps through the whole
surface adjusting the alpha byte of each pixel. Yes it could be a lot
faster, like only adjusting the alpha byte and stepping over the colour
bytes, but it does what it says on the tin, so for now here it is.