Jump to content
  • Advertisement
Sign in to follow this  
Fomas

SDL_BlitSurface() doesn't want to blit

This topic is 3982 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello boys and girls! :) The Subject says pretty much everything, after blitting one Surface onto another one the destination Surface remains black, though SDL_BlitSurface() says blitting was successful. ConstructTitle() loads title images and then blits them onto the empty Surface, which is then returned. ConstructWindow() assembles window elements such as title, border, buttons, canvas by bliting them onto the empty Surface, which is then returned. And finally the returned Window Surface is blited onto the destination Surface, which is a SetVideoMode Surface. The following code snippet is just an example and is more like a pseudocode, but it illustrates the problem very well.
Uint32 flags = SDL_SWSURFACE | SDL_SRCCOLORKEY | SDL_SRCALPHA,
       rMask = 0xff000000,
       gMask = 0x00ff0000,
       bMask = 0x0000ff00,
       aMask = 0x000000ff;

SDL_Surface *ConstructTitle()
{
    SDL_Surface *leftCorner = SDL_LoadBMP("lcorner.bmp"), // Assume loaded successully!
                *rightCorner = SDL_LoadBMP("rcorner.bmp"), // Assume loaded successully!
                *title = SDL_CreateRGBSurface(flags, 100, 100, 32,
                                              rMask, gMask, bMask, aMask);

    SDL_Rect r = {0, 0};
    SDL_BlitSurface(leftCorner, 0, title, &r);  // Works!

    r.x = leftCorner->w;
    SDL_BlitSurface(rightCorner, 0, title, &r); // Works!

    return title;
}

SDL_Surface *ConstructWindow()
{
    SDL_Surface *title = ConstructTitle();
    SDL_Surface *border = ConstructBorder();
    SDL_Surface *win = SDL_CreateRGBSurface(flags, 640, 480, 32,
                                            rMask, gMask, bMask, aMask);

    SDL_Rect r = {0, 0};
    SDL_BlitSurface(title, 0, win, &r); // Doesn't seem to work!

    r.y = title->h;
    SDL_BlitSurface(border, 0, win, &r); // Doesn't seem to work!

    return win;
}

int main()
{
    InitSDL();
    SDL_Surface *dest = SetVideoMode();

    SDL_Sufrace *win = ConstructWindow(); // Doesn't work!
    //SDL_Sufrace *win = ConstructTitle(); // Works!

    SDL_Rect r = {0, 0};
    SDL_BlitSurface(win, 0, dest, &r);
    SDL_Flip(dest);

    return 0;
}

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Butterman
Did you init SDL_video?


Yes, I did...it's not an initialisation problem, as I've shown in the code that if I call ConstructTitle() directly then it's working but if I call ConstructWindow() then it's not. It seems like, even though I don't think it's true, the returned title, border etc. inside ConstructWindow() get destroyed...but if it did then SDL_BlitSurface() inside ConstructWindow() should have returned an error.

Share this post


Link to post
Share on other sites
Ok I think I found a problem! ;) Apparently if the empty Surface is not fully filled/initialised or what ever you wanna call it, then SDL_BlitSurface() finds it hard to blit or doesn't blit at all but still doesn't give any errors, which is annoying.
I only added the SDL_FillRect() to fill the empty Surface with a color before blitting, and it seems it fixed the problem.
Here is a new code:

SDL_Surface *ConstructTitle()
{
SDL_Surface *leftCorner = SDL_LoadBMP("lcorner.bmp"), // Assume loaded successully!
*rightCorner = SDL_LoadBMP("rcorner.bmp"), // Assume loaded successully!
*title = SDL_CreateRGBSurface(flags, 100, 100, 32,
rMask, gMask, bMask, aMask);

SDL_FillRect(title, 0, SDL_MapRGB(temp->format, 0, 0, 0)); // ADD to make it work!

SDL_Rect r = {0, 0};
SDL_BlitSurface(leftCorner, 0, title, &r);

r.x = leftCorner->w;
SDL_BlitSurface(rightCorner, 0, title, &r);

return title;
}

SDL_Surface *ConstructWindow()
{
SDL_Surface *title = ConstructTitle();
SDL_Surface *border = ConstructBorder();
SDL_Surface *win = SDL_CreateRGBSurface(flags, 640, 480, 32,
rMask, gMask, bMask, aMask);

SDL_FillRect(win, 0, SDL_MapRGB(temp->format, 0, 0, 0)); // ADD to make it work!

SDL_Rect r = {0, 0};
SDL_BlitSurface(title, 0, win, &r);

r.y = title->h;
SDL_BlitSurface(border, 0, win, &r);

return win;
}

int main()
{
InitSDL();
SDL_Surface *dest = SetVideoMode();

SDL_Sufrace *win = ConstructWindow();
//SDL_Sufrace *win = ConstructTitle();

SDL_Rect r = {0, 0};
SDL_BlitSurface(win, 0, dest, &r);
SDL_Flip(dest);

return 0;
}


Share this post


Link to post
Share on other sites
This issue has also bitten me more then a few time.

SDL_CreateRGBSurface() will create and fill a 32-bit surface with zeros then return it to you. That means all the alpha components are also zero. When you try to blit an image onto the surface, the alpha components remain untouched. So when you try to blit the surface to the screen you see nothing since the entire surface is still totally transparent.

So you can either disable per-pixel blits on the source surface or fill the destination surface(FillRect) so that the alpha components are all 255. It also helps that MapRGB() will automatically return a color whose alpha component is 255 for that format.

You can check out the various interactions/behaviors when blitting between surfaces(RGB and RGBA that set or don't SDL_SRCALPHA ) by reading these docs.
BlitSurface
SetAlpha

Share this post


Link to post
Share on other sites
Quote:
Original post by Jack Sotac
This issue has also bitten me more then a few time.

SDL_CreateRGBSurface() will create and fill a 32-bit surface with zeros then return it to you. That means all the alpha components are also zero. When you try to blit an image onto the surface, the alpha components remain untouched. So when you try to blit the surface to the screen you see nothing since the entire surface is still totally transparent.

So you can either disable per-pixel blits on the source surface or fill the destination surface(FillRect) so that the alpha components are all 255. It also helps that MapRGB() will automatically return a color whose alpha component is 255 for that format.

BlitSurface
SetAlpha


Thanks a lot for clearing it out, Jack Sotac! Now it actually makes sense, cos I thought there was something wrong with blitting function.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!