2013-11-24 100 views
0

我無法弄清楚如何在屏幕表面上繪製一個半透明的紅色矩形。 這裏是我到目前爲止的代碼:SDL:繪製一個半透明的矩形

#!/usr/bin/perl 

use SDL; 
use SDL::Video; 
use SDL::Surface; 
use SDL::Rect; 

# the size of the window box or the screen resolution if fullscreen 
my $screen_width = 800; 
my $screen_height = 600; 

SDL::init(SDL_INIT_VIDEO); 

# setting video mode 
my $screen_surface = SDL::Video::set_video_mode($screen_width, $screen_height, 32, SDL_ANYFORMAT|SDL_SRCALPHA); 

# drawing something somewhere 
my $mapped_color = SDL::Video::map_RGBA($screen_surface->format(), 255, 0, 0, 128); #should be half-transparent, I suppose? 

SDL::Video::fill_rect($screen_surface, 
SDL::Rect->new($screen_width/4, $screen_height/4, 
       $screen_width/2, $screen_height/2), $mapped_color); 

# update an area on the screen so its visible 
SDL::Video::update_rect($screen_surface, 0, 0, $screen_width, $screen_height); 

sleep(5); # just to have time to see it 

它導致在黑色的背景,這不是我所試圖達到的紅色不透明的矩形。

回答

3

您無法使用SDL_FillRect進行透明處理。該函數將使用值color覆蓋曲面。把它想象成一個「memset」。

來自文檔的報價:如果顏色值包含一個alpha值,那麼目的地只是用該alpha信息「填充」,不會發生混合。

使用SDL_BlitSurface獲得透明度。首先創建一個紋理填充顏色,然後blit。

我做了一個小測試,案例實踐:

#include <SDL.h> 

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 

SDL_Surface* CreateSurface(int width , int height) 
{ 
    uint32_t rmask , gmask , bmask , amask ; 

    /* SDL interprets each pixel as a 32-bit number, so our masks must depend 
     on the endianness (byte order) of the machine */ 
    #if SDL_BYTEORDER == SDL_BIG_ENDIAN 
     rmask = 0xff000000; 
     gmask = 0x00ff0000; 
     bmask = 0x0000ff00; 
     amask = 0x000000ff; 
    #else 
     rmask = 0x000000ff; 
     gmask = 0x0000ff00; 
     bmask = 0x00ff0000; 
     amask = 0xff000000; 
    #endif 

    SDL_Surface* surface = SDL_CreateRGBSurface(0 , width , height , 32 , rmask , gmask , bmask , amask) ; 
    if(surface == NULL) 
    { 
     (void)fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError()); 
     exit(1); 
    } 

return surface ; 
} 

void Quit(void) 
{ 
    SDL_Quit() ; 
    exit(0) ; 
} 


int main(int argc, char *argv[]) 
{ 
    (void)argc ; 
    (void)argv ; 

    int init = !(SDL_Init(SDL_INIT_EVERYTHING)); 
    if(!init) 
     Quit() ; 


    SDL_Surface* screen = SDL_SetVideoMode(800 , 600 , 32 , 0) ; 
    if(!screen) 
     Quit() ; 

    int run = true ; 

    while(run) 
    { 

     SDL_Event event ; 
     while(SDL_PollEvent(&event)) 
     { 
      switch(event.type) 
      { 
       case SDL_QUIT: 
        run = false ; 
        break; 
      } 
     } 

     SDL_Surface* s = CreateSurface(300 ,300) ; 
     (void)SDL_FillRect(s , NULL , 0xAA0000FF) ; 


     SDL_Rect rect = { 100 , 100 } ; 
     (void)SDL_BlitSurface(s , NULL , screen , &rect) ; 

     rect.x = 200 ; 
     rect.y = 200 ; 
     (void)SDL_FillRect(s , NULL , 0x440000FF) ; 
     (void)SDL_BlitSurface(s , NULL , screen , &rect) ; 

     SDL_FreeSurface(s) ; 

     (void)SDL_Flip(screen) ; 
     SDL_Delay(15) ; 

     (void)SDL_FillRect(screen , NULL , 0x00FFFF) ; 
    } 

    Quit() ; 

    return 0; 
} 
+0

謝謝,它幫助! – varnie

+0

我需要問,爲什麼你把「(void)」?這是否讓編譯器忽略返回值並不保存它? –

相關問題