我无法弄清楚如何在屏幕表面上绘制半透明的红色矩形。 这是我到目前为止的代码:
#!/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
它导致黑色背景上的红色不透明矩形,这不是我想要实现的。
答案 0 :(得分:3)
您不能将SDL_FillRect用于透明度。该函数将使用值color
覆盖曲面。把它想象成一个“memset”。
来自docs的引用:如果颜色值包含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;
}