Sign in to follow this  

SDL multiple layer transparency issue

This topic is 1739 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

Hi guys I have another issue with SDL recently. Here is the smallest segment possible.

Circle is a circle with a hole in the middle and square is just a square.

SDL_Surface* loadImage(std::string filename)
{
    SDL_Surface* img = IMG_Load(filename.c_str());
    if(img == NULL)
    {
        return NULL;
    }
    SDL_Surface* optimized = SDL_DisplayFormatAlpha(img);
    SDL_FreeSurface(img);
    return optimized;
}

int main(int args , char* argv[] )
{
    if(SDL_Init(SDL_INIT_EVERYTHING) == 1)
    {
        std::cout << "error" << std::endl ;
    }
    SDL_Surface* surface = SDL_SetVideoMode(100,100,32,SDL_SWSURFACE);
    SDL_Surface* circle = loadImage("circle.png");
    SDL_Surface* square = loadImage("square.png");
    SDL_PixelFormat* format = surface->format;    
    SDL_Rect rect = {0 ,0 , 100 , 100};

    // draw code
    
    SDL_Flip(surface);


 

so for the draw code , this works.

    SDL_BlitSurface(square,&rect,surface,&rect);
    SDL_BlitSurface(circle,&rect,surface,&rect);

However, I want to draw to a temporary surface first before drawing.

Then this don't work.

    SDL_PixelFormat* format = surface->format;
    SDL_Surface* temp1 = SDL_CreateRGBSurface(SDL_SWSURFACE,100,100,32,format->Rmask,format->Gmask,format->Bmask,format->Amask);
    SDL_Surface* temp2 = SDL_CreateRGBSurface(SDL_SWSURFACE,100,100,32,format->Rmask,format->Gmask,format->Bmask,format->Amask);

    SDL_BlitSurface(square,&rect,temp1,&rect);
    SDL_BlitSurface(circle,&rect,temp2,&rect);
    SDL_BlitSurface(temp1,&rect,surface,&rect);
    SDL_BlitSurface(temp2,&rect,surface,&rect);

 

When I do this, the temporary surface has a black background and the final output is only a circle.

 

I checked and I found out that surface->format->Amask is 0 , so the created surface do not have alpha enabled.

So instead of using surface-> format, i tried using circle->format instead. The result ? , nothing is drawn.

 

I tried other stuffs as well, like doing a SDL_FillRect onto temp1 and temp2 , but it still doesn't do what i want. =( 

I tried doing SDL_SetAlpha as well but still didn't work. What am i missing ? =/

 

Share this post


Link to post
Share on other sites

Thanks a lot. 

 

Here is the code that works, in case other people face the same problem.

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <iostream>


SDL_Surface* loadImage(std::string filename)
{
    SDL_Surface* img = IMG_Load(filename.c_str());
    if(img == NULL)
    {
        return NULL;
    }
    SDL_Surface* optimized = SDL_DisplayFormatAlpha(img);
    SDL_FreeSurface(img);
    return optimized;
}

int main(int args , char* argv[] )
{
    if(SDL_Init(SDL_INIT_EVERYTHING) == 1)
    {
        std::cout << "error" << std::endl ;
    }
    SDL_Surface* surface = SDL_SetVideoMode(100,100,32,SDL_SWSURFACE);
    SDL_FillRect(surface,0,SDL_MapRGBA(surface->format,100,100,100,255));

    SDL_Surface* circle = loadImage("circle.png");
    SDL_Surface* square = loadImage("square.png");

    SDL_PixelFormat* format = surface->format;
    SDL_Surface* temp1 = SDL_CreateRGBSurface(SDL_SWSURFACE,100,100,32,format->Rmask,format->Gmask,format->Bmask,format->Amask);
    SDL_Surface* temp2 = SDL_CreateRGBSurface(SDL_SWSURFACE,100,100,32,format->Rmask,format->Gmask,format->Bmask,format->Amask);

    temp1 = SDL_DisplayFormatAlpha(temp1);
    temp2 = SDL_DisplayFormatAlpha(temp2);

    SDL_SetAlpha(square,0,square->format->alpha);
    SDL_SetAlpha(circle,0,circle->format->alpha);

    SDL_Rect rect = {0 ,0 , 100 , 100};

    SDL_BlitSurface(square,&rect,temp1,&rect);
    SDL_BlitSurface(circle,&rect,temp2,&rect);
    SDL_BlitSurface(temp1,&rect,surface,&rect);
    SDL_BlitSurface(temp2,&rect,surface,&rect);

    SDL_Flip(surface);


    SDL_Delay(2000); 

 

SDL_DisplayFormatAlpha is needed to set the mask for the surface, because the original surface do not have alpha mask.

 

There is a lot of memory leak here, and many surface is not freed to reduce the length of the code.

 

Once again, thanks :P

Share this post


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