⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 testalpha.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
字号:
/* Simple program:  Fill a colormap with gray and stripe it down the screen,		    Then move an alpha valued sprite around the screen. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "SDL.h"#define FRAME_TICKS	(1000/30)		/* 30 frames/second *//* Create a "light" -- a yellowish surface with variable alpha */SDL_Surface *CreateLight(SDL_Surface *screen, int radius){	Uint8  trans, alphamask;	int    range, addition;	int    xdist, ydist;	Uint16 x, y;	Uint16 skip;	Uint32 pixel;	SDL_Surface *light;#ifdef LIGHT_16BIT	Uint16 *buf;	/* Create a 16 (4/4/4/4) bpp square with a full 4-bit alpha channel */	/* Note: this isn't any faster than a 32 bit alpha surface */	alphamask = 0x0000000F;	light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 16,			0x0000F000, 0x00000F00, 0x000000F0, alphamask);#else	Uint32 *buf;	/* Create a 32 (8/8/8/8) bpp square with a full 8-bit alpha channel */	alphamask = 0x000000FF;	light = SDL_CreateRGBSurface(SDL_SWSURFACE, 2*radius, 2*radius, 32,			0xFF000000, 0x00FF0000, 0x0000FF00, alphamask);	if ( light == NULL ) {		fprintf(stderr, "Couldn't create light: %s\n", SDL_GetError());		return(NULL);	}#endif	/* Fill with a light yellow-orange color */	skip = light->pitch-(light->w*light->format->BytesPerPixel);#ifdef LIGHT_16BIT	buf = (Uint16 *)light->pixels;#else	buf = (Uint32 *)light->pixels;#endif        /* Get a tranparent pixel value - we'll add alpha later */	pixel = SDL_MapRGBA(light->format, 0xFF, 0xDD, 0x88, 0);	for ( y=0; y<light->h; ++y ) {		for ( x=0; x<light->w; ++x ) {			*buf++ = pixel;		}		buf += skip;	/* Almost always 0, but just in case... */	}	/* Calculate alpha values for the surface. */#ifdef LIGHT_16BIT	buf = (Uint16 *)light->pixels;#else	buf = (Uint32 *)light->pixels;#endif	for ( y=0; y<light->h; ++y ) {		for ( x=0; x<light->w; ++x ) {			/* Slow distance formula (from center of light) */			xdist = x-(light->w/2);			ydist = y-(light->h/2);			range = (int)sqrt(xdist*xdist+ydist*ydist);			/* Scale distance to range of transparency (0-255) */			if ( range > radius ) {				trans = alphamask;			} else {				/* Increasing transparency with distance */				trans = (Uint8)((range*alphamask)/radius);				/* Lights are very transparent */				addition = (alphamask+1)/8;				if ( (int)trans+addition > alphamask ) {					trans = alphamask;				} else {					trans += addition;				}			}			/* We set the alpha component as the right N bits */			*buf++ |= (255-trans);		}		buf += skip;	/* Almost always 0, but just in case... */	}	/* Enable RLE acceleration of this alpha surface */	SDL_SetAlpha(light, SDL_SRCALPHA|SDL_RLEACCEL, 0);	/* We're done! */	return(light);}static Uint32 flashes = 0;static Uint32 flashtime = 0;void FlashLight(SDL_Surface *screen, SDL_Surface *light, int x, int y){	SDL_Rect position;	Uint32   ticks1;	Uint32   ticks2;	/* Easy, center light */	position.x = x-(light->w/2);	position.y = y-(light->h/2);	position.w = light->w;	position.h = light->h;	ticks1 = SDL_GetTicks();	SDL_BlitSurface(light, NULL, screen, &position);	ticks2 = SDL_GetTicks();	SDL_UpdateRects(screen, 1, &position);	++flashes;	/* Update time spend doing alpha blitting */	flashtime += (ticks2-ticks1);}static int sprite_visible = 0;static SDL_Surface *sprite;static SDL_Surface *backing;static SDL_Rect    position;static int         x_vel, y_vel;static int	   alpha_vel;int LoadSprite(SDL_Surface *screen, char *file){	SDL_Surface *converted;	/* Load the sprite image */	sprite = SDL_LoadBMP(file);	if ( sprite == NULL ) {		fprintf(stderr, "Couldn't load %s: %s", file, SDL_GetError());		return(-1);	}	/* Set transparent pixel as the pixel at (0,0) */	if ( sprite->format->palette ) {		SDL_SetColorKey(sprite, SDL_SRCCOLORKEY,						*(Uint8 *)sprite->pixels);	}	/* Convert sprite to video format */	converted = SDL_DisplayFormat(sprite);	SDL_FreeSurface(sprite);	if ( converted == NULL ) {		fprintf(stderr, "Couldn't convert background: %s\n",							SDL_GetError());		return(-1);	}	sprite = converted;	/* Create the background */	backing = SDL_CreateRGBSurface(SDL_SWSURFACE, sprite->w, sprite->h, 8,								0, 0, 0, 0);	if ( backing == NULL ) {		fprintf(stderr, "Couldn't create background: %s\n",							SDL_GetError());		SDL_FreeSurface(sprite);		return(-1);	}	/* Convert background to video format */	converted = SDL_DisplayFormat(backing);	SDL_FreeSurface(backing);	if ( converted == NULL ) {		fprintf(stderr, "Couldn't convert background: %s\n",							SDL_GetError());		SDL_FreeSurface(sprite);		return(-1);	}	backing = converted;	/* Set the initial position of the sprite */	position.x = (screen->w-sprite->w)/2;	position.y = (screen->h-sprite->h)/2;	position.w = sprite->w;	position.h = sprite->h;	x_vel = 0; y_vel = 0;	alpha_vel = 1;	/* We're ready to roll. :) */	return(0);}void AttractSprite(Uint16 x, Uint16 y){	x_vel = ((int)x-position.x)/10;	y_vel = ((int)y-position.y)/10;}void MoveSprite(SDL_Surface *screen, SDL_Surface *light){	SDL_Rect updates[2];	int alpha;	/* Erase the sprite if it was visible */	if ( sprite_visible ) {		updates[0] = position;		SDL_BlitSurface(backing, NULL, screen, &updates[0]);	} else {		updates[0].x = 0; updates[0].y = 0;		updates[0].w = 0; updates[0].h = 0;		sprite_visible = 1;	}	/* Since the sprite is off the screen, we can do other drawing	   without being overwritten by the saved area behind the sprite.	 */	if ( light != NULL ) {		int x, y;		SDL_GetMouseState(&x, &y);		FlashLight(screen, light, x, y);	}	   	/* Move the sprite, bounce at the wall */	position.x += x_vel;	if ( (position.x < 0) || (position.x >= screen->w) ) {		x_vel = -x_vel;		position.x += x_vel;	}	position.y += y_vel;	if ( (position.y < 0) || (position.y >= screen->h) ) {		y_vel = -y_vel;		position.y += y_vel;	}	/* Update transparency (fade in and out) */	alpha = sprite->format->alpha;	if ( (alpha+alpha_vel) < 0 ) {		alpha_vel = -alpha_vel;	} else	if ( (alpha+alpha_vel) > 255 ) {		alpha_vel = -alpha_vel;	}	SDL_SetAlpha(sprite, SDL_SRCALPHA, (Uint8)(alpha+alpha_vel));	/* Save the area behind the sprite */	updates[1] = position;	SDL_BlitSurface(screen, &updates[1], backing, NULL);		/* Blit the sprite onto the screen */	updates[1] = position;	SDL_BlitSurface(sprite, NULL, screen, &updates[1]);	/* Make it so! */	SDL_UpdateRects(screen, 2, updates);}void WarpSprite(SDL_Surface *screen, int x, int y){	SDL_Rect updates[2];	/* Erase, move, Draw, update */	updates[0] = position;	SDL_BlitSurface(backing, NULL, screen, &updates[0]);	position.x = x-sprite->w/2;	/* Center about X */	position.y = y-sprite->h/2;	/* Center about Y */	updates[1] = position;	SDL_BlitSurface(screen, &updates[1], backing, NULL);	updates[1] = position;	SDL_BlitSurface(sprite, NULL, screen, &updates[1]);	SDL_UpdateRects(screen, 2, updates);}int main(int argc, char *argv[]){	const SDL_VideoInfo *info;	SDL_Surface *screen;	Uint8  video_bpp;	Uint32 videoflags;	Uint8 *buffer;	int    i, done;	SDL_Event event;	SDL_Surface *light;	int mouse_pressed;	Uint32 ticks, lastticks;	/* Initialize SDL */	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {		fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());		exit(1);	}	atexit(SDL_Quit);	/* Alpha blending doesn't work well at 8-bit color */	info = SDL_GetVideoInfo();	if ( info->vfmt->BitsPerPixel > 8 ) {		video_bpp = info->vfmt->BitsPerPixel;	} else {		video_bpp = 16;	}	videoflags = SDL_SWSURFACE;	while ( argc > 1 ) {		--argc;		if ( strcmp(argv[argc-1], "-bpp") == 0 ) {			video_bpp = atoi(argv[argc]);			--argc;		} else		if ( strcmp(argv[argc], "-hw") == 0 ) {			videoflags |= SDL_HWSURFACE;		} else		if ( strcmp(argv[argc], "-warp") == 0 ) {			videoflags |= SDL_HWPALETTE;		} else		if ( strcmp(argv[argc], "-fullscreen") == 0 ) {			videoflags |= SDL_FULLSCREEN;		} else {			fprintf(stderr, 			"Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n",								argv[0]);			exit(1);		}	}	/* Set 640x480 video mode */	if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) {		fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n",						video_bpp, SDL_GetError());		exit(2);	}	/* Set the surface pixels and refresh! */	if ( SDL_LockSurface(screen) < 0 ) {		fprintf(stderr, "Couldn't lock the display surface: %s\n",							SDL_GetError());		exit(2);	}	buffer=(Uint8 *)screen->pixels;	for ( i=0; i<screen->h; ++i ) {		memset(buffer,(i*255)/screen->h, screen->pitch);		buffer += screen->pitch;	}	SDL_UnlockSurface(screen);	SDL_UpdateRect(screen, 0, 0, 0, 0);	/* Create the light */	light = CreateLight(screen, 82);	if ( light == NULL ) {		exit(1);	}	/* Load the sprite */	if ( LoadSprite(screen, "icon.bmp") < 0 ) {		SDL_FreeSurface(light);		exit(1);	}	/* Set a clipping rectangle to clip the outside edge of the screen */	{ SDL_Rect clip;		clip.x = 32;		clip.y = 32;		clip.w = screen->w-(2*32);		clip.h = screen->h-(2*32);		SDL_SetClipRect(screen, &clip);	}	/* Wait for a keystroke */	lastticks = SDL_GetTicks();	done = 0;	mouse_pressed = 0;	while ( !done ) {		/* Update the frame -- move the sprite */		if ( mouse_pressed ) {			MoveSprite(screen, light);			mouse_pressed = 0;		} else {			MoveSprite(screen, NULL);		}		/* Slow down the loop to 30 frames/second */		ticks = SDL_GetTicks();		if ( (ticks-lastticks) < FRAME_TICKS ) {#ifdef CHECK_SLEEP_GRANULARITYfprintf(stderr, "Sleeping %d ticks\n", FRAME_TICKS-(ticks-lastticks));#endif			SDL_Delay(FRAME_TICKS-(ticks-lastticks));#ifdef CHECK_SLEEP_GRANULARITYfprintf(stderr, "Slept %d ticks\n", (SDL_GetTicks()-ticks));#endif		}		lastticks = ticks;		/* Check for events */		while ( SDL_PollEvent(&event) ) {			switch (event.type) {				/* Attract sprite while mouse is held down */				case SDL_MOUSEMOTION:					if (event.motion.state != 0) {						AttractSprite(event.motion.x,								event.motion.y);						mouse_pressed = 1;					}					break;				case SDL_MOUSEBUTTONDOWN:					if ( event.button.button == 1 ) {						AttractSprite(event.button.x,						              event.button.y);						mouse_pressed = 1;					} else {						SDL_Rect area;						area.x = event.button.x-16;						area.y = event.button.y-16;						area.w = 32;						area.h = 32;						SDL_FillRect(screen, &area, 0);						SDL_UpdateRects(screen,1,&area);					}					break;				case SDL_KEYDOWN:					/* Any keypress quits the app... */				case SDL_QUIT:					done = 1;					break;				default:					break;			}		}	}	SDL_FreeSurface(light);	SDL_FreeSurface(sprite);	SDL_FreeSurface(backing);	/* Print out some timing information */	if ( flashes > 0 ) {		printf("%d alpha blits, ~%4.4f ms per blit\n", 			flashes, (float)flashtime/flashes);	}	return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -