Sign in to follow this  
ZwodahS

SDL multiple layer transparency issue

Recommended Posts

ZwodahS    483

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
ZwodahS    483

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

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this