2014-09-29 27 views
1

有没有办法让表面具有多个alpha值来正确混合?我必须使用SDL_SetSurfaceAlphaMod来修改纹理混合的方式,并覆盖整个表面的alpha通道!我制作了一个小型演示程序来展示我的意思。如何将曲面与多个alpha值混合?

我想要的是This,我得到的是this

代码

#include <SDL.h> 

void putPixel(SDL_Surface *surface, int x, int y, Uint32 pixel){ 

    Uint32 *pixels = (Uint32*)surface->pixels; 
    pixels[(y * surface->w) + x] = pixel; 
} 

// After some experimenting I found that this would get the alpha onto the surface correctly 
void FillAlpha(SDL_Surface* Surface){ 
    Uint32 Pixel; 
    Uint8 RGBA[4] = {0, 0, 0, 100}; 
    Pixel = RGBA[3]<<24 | RGBA[2]<<16 | RGBA[1]<<8 | RGBA[0]; 
    for(int x=0; x<32; x++){ 
    for(int y=0; y<32; y++){ 
     putPixel(Surface, x, y, Pixel); 
    } 
    } 
    RGBA[3] = 150; 
    Pixel = RGBA[3]<<24 | RGBA[2]<<16 | RGBA[1]<<8 | RGBA[0]; 
    for(int x=32; x<64; x++){ 
    for(int y=0; y<32; y++){ 
     putPixel(Surface, x, y, Pixel); 
    } 
    } 
} 

int main(int argc, char* args[]) 
{ 
    SDL_Window* Window = NULL; 
    SDL_Surface* Screen = NULL; 
    SDL_Surface* Alpha = NULL; 

    SDL_Event Event; 

    bool Quit = false; 

    Window = SDL_CreateWindow("Alpha test", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 128, 128, SDL_WINDOW_SHOWN); 
    if(Window == NULL) return 1; 
    Screen = SDL_GetWindowSurface(Window); 
    if(Screen == NULL) return 2; 

    Alpha = SDL_CreateRGBSurface(NULL, 64, 32, 32, 
           Screen->format->Rmask, Screen->format->Gmask, 
           Screen->format->Bmask, Screen->format->Amask); 
    if(Alpha == NULL) return 3; 
    SDL_SetSurfaceBlendMode(Alpha, SDL_BLENDMODE_BLEND); 
    FillAlpha(Alpha); 

    while(!Quit){ 
    while(SDL_PollEvent(&Event)){ 
     if(Event.type == SDL_KEYDOWN){ 
     if(Event.key.keysym.sym == SDLK_ESCAPE){ 
      Quit = true; 
     } 
     }else if(Event.type == SDL_QUIT){ 
     Quit = true; 
     } 
    } 
    SDL_FillRect(Screen, NULL, SDL_MapRGB(Screen->format, 255, 255, 255)); 
    SDL_BlitSurface(Alpha, NULL, Screen, NULL); 
    SDL_UpdateWindowSurface(Window); 
    } 

    SDL_Quit(); 
    return 0; 
} 

回答

1

好像你只是没有正确初始化您的表面。例如,在我的机器上,Screen->format->?mask产生的值不正确。所以,与其

Alpha = SDL_CreateRGBSurface(NULL, 64, 32, 32, 
    Screen->format->Rmask, Screen->format->Gmask, 
    Screen->format->Bmask, Screen->format->Amask); 

试试这个(我假设你是小端CPU):

unsigned int rmask = 0x000000ff; 
unsigned int gmask = 0x0000ff00; 
unsigned int bmask = 0x00ff0000; 
unsigned int amask = 0xff000000; 

Alpha = SDL_CreateRGBSurface(NULL, 64, 32, 32, rmask, gmask, bmask, amask); 

作进一步参考,see official wiki