# SDL_DisplayFormat works, but not SDL_DisplayFormatAlpha

The following code is intended to display a green square on a black background. It executes, but the green square does not show up. However, if I change SDL_DisplayFormatAlpha to SDL_DisplayFormat the square is rendered correctly.

So what don't I understand? It seems to me that I am creating *surface with an alpha mask and I am using SDL_MapRGBA to map my green color, so it would be consistent to use SDL_DisplayFormatAlpha as well.

(I removed error-checking for clarity, but none of the SDL API calls fail in this example.)

#include <SDL.h>

int main(int argc, const char *argv[])
{
SDL_Init( SDL_INIT_EVERYTHING );

SDL_Surface *screen = SDL_SetVideoMode(
640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF
);

SDL_Surface *temp = SDL_CreateRGBSurface(
SDL_HWSURFACE, 100, 100, 32, 0, 0, 0,
( SDL_BYTEORDER == SDL_BIG_ENDIAN ? 0x000000ff : 0xff000000 )
);

SDL_Surface *surface = SDL_DisplayFormatAlpha( temp );

SDL_FreeSurface( temp );

SDL_FillRect(
surface, &surface->clip_rect, SDL_MapRGBA(
screen->format, 0x00, 0xff, 0x00, 0xff
)
);

SDL_Rect r;
r.x = 50;
r.y = 50;

SDL_BlitSurface( surface, NULL, screen, &r );

SDL_Flip( screen );

SDL_Delay( 1000 );

SDL_Quit();

return 0;
}


I don’t know if this is the issue, but the masks in your SDL_CreateRGBSurface() call look wrong. Perhaps try what the SDL wiki says:

const SDL_PixelFormat& format = *screen->format;

SDL_Surface* surface = SDL_CreateRGBSurface(
SDL_HWSURFACE,
width,
height,
32,
);


Perhaps the upper bits (where the red channel ought to be) are being interpreted as the alpha channel; since they’re zero, the resulting surface would be fully transparent.

• The SDL_PixelFormat structure provides Rmask, Gmask, Bmask and Amask members. I can't tell for sure, but they are probably cross-platform, so you can skip this pre-processor condition and use screen->format->[A,G,B,A]mask. – Asakeron Nov 1 '12 at 15:09
• @Asakeron: You’re right. I had forgotten about that. Been a while since I’ve used SDL actively. – Jon Purdy Nov 1 '12 at 17:43
• Also, I don't think endianness is the problem, because Bounderby is already checking that. – Asakeron Nov 1 '12 at 18:27
• I tried this. Makes no difference. I also tried using white (0xff, 0xff, 0xff, 0xff) which also made no difference. – Bounderby Nov 2 '12 at 0:55

If you set the pixel colors in your surface before calling SDL_DisplayFormatAlpha, it might work:

int main(int argc, char *argv[])
{
SDL_Init( SDL_INIT_EVERYTHING );

SDL_Surface *screen = SDL_SetVideoMode(
640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF
);

SDL_Surface *temp = SDL_CreateRGBSurface(

Uint32 *pixels  =(Uint32*) temp->pixels;

for(int i = 0; i < 10000; i++)
{
pixels[i] = SDL_MapRGBA(screen->format, 0, 255, 0, 255);
}

SDL_Surface *surface = SDL_DisplayFormatAlpha( temp );

SDL_Rect r;
r.x = 50;
r.y = 50;

SDL_BlitSurface( surface, NULL, screen, &r );

SDL_Flip( screen );

SDL_Delay( 1000 );

SDL_Quit();

return 0;
}


I also removed your endianness check. I'm using the masks provided by the SDL_PixelFormat structure. See my comment to Jon Purdy's answer for more information.

• Hmm. This is strange. I tried filling the surface before calling SDL_DisplayFormatAlpha. Now the surface renders, but it still doesn't seem to use the alpha channel. I tested by trying to blend two surfaces. – Bounderby Nov 2 '12 at 1:01

I was using the wrong format for SDL_MapRGBA. Should have been

SDL_FillRect(
surface, NULL, SDL_MapRGBA(
surface->format, 0xff, 0xff, 0x00, 0xff
)
);


(surface->format instead of screen->format.) I thought the two would be equivalent. And they are after calling SDL_DisplayFormat(), but not after calling SDL_DisplayFormatAlpha()`. The screen surface doesn't have an alpha channel, so the format is different between the two.