Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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;
}
share|improve this question

3 Answers 3

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,
  format.Rmask,
  format.Gmask,
  format.Bmask,
  format.Amask
);

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.

share|improve this answer
    
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(
    SDL_HWSURFACE, 100, 100, 32, screen->format.Rmask, screen->format.Amask, screen->format.Bmask, screen->format.Amask);

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.

share|improve this answer
    
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
up vote 0 down vote accepted

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.