SDL学习——画图、点阵显示

论坛 期权论坛 脚本     
匿名技术用户   2020-12-22 17:13   86   0

很久以前,发表了几篇SDLWindows编译的文章,同时也参考网上的一个十分简单的例子写了测试的程序,本文章将以此为基础并添加自己的代码。

回首第1篇关于SDL的文章,那已是去年12月份写的了,时间过得真快。

本文主要写一下在SDL中如何画像素点,以及如何显示字符(中文、英文)

画像素点:


static void SDL_PixelNolock(SDL_Surface* surface, int x, int y, Uint32 color)
{
int bpp = surface->format->BytesPerPixel;
Uint8* p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

switch (bpp)
{
case 4:
*(Uint32 *)p = color;
break;
case 1:
*p = color;
break;
case 2:
*(Uint16 *)p = color;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (color >> 16) & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = color & 0xff;
}
else
{
p[0] = color & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = (color >> 16) & 0xff;
}
break;
}
}

static void SDL_PixelColor(SDL_Surface* surface, int x, int y, Uint32 color)
{
if (SDL_MUSTLOCK(surface))
{
if (SDL_LockSurface(surface) < 0)
{
return;
}
}

SDL_PixelNolock(surface, x, y, color);

if (SDL_MUSTLOCK(surface))
{
SDL_UnlockSurface(surface);
}
}

void SDL_Pixel(SDL_Surface* surface, int x, int y, Uint32 color)
{
SDL_PixelColor(surface, x, y, color);
}

上面给的是大部分SDL资料中常用的函数。另外,tslib中也有相关的实现画像素的函数,可以参考笔者之前发布的文章。

为了兼容以前写的代码,只好将SDL有关的函数全部封装起来。事实上,只要给出画像素的函数,其它模块完全不用修改,因为它们都是与具体平台无关。在这里,主要是指画图函数以及字符显示函数。实际上使用的需要封装的函数如下:

// somebody must implement these functions
extern int graphic_init(void);
extern void pixel(int x, int y, uint32 color);
extern void myrefresh();
// if you are using color index to show color, do it
extern void init_color(uint32 palette[], int len);

主要涉及图像界面的初始化、画像素、刷新等等。

我们的重点不在SDL高深的用法,所以只需要进行必要的初始化,并按SDL的套路写函数即可。下面是初始化SDL的相关函数:

/////////////////////////////////////////////////////////////////
const int WINDOW_WIDTH = 480;
const int WINDOW_HEIGHT = 320;
const char* WINDOW_TITLE = "SDL Hello World -- by Late Lee";

SDL_Surface* g_screen = NULL;

int InitGraphic(SDL_Surface** screen)
{
const SDL_VideoInfo *info;
Uint8 video_bpp;
Uint32 videoflags;

// Initialize SDL
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
return 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 | SDL_DOUBLEBUF;

// Set 640x480 video mode
if ( (*screen=SDL_SetVideoMode(WINDOW_WIDTH,WINDOW_HEIGHT,video_bpp,videoflags)) == NULL ) {
fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",640,480,SDL_GetError());
return 2;
}

SDL_WM_SetCaption(WINDOW_TITLE, 0);

return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////

int sdl_init(void)
{
return InitGraphic(&g_screen);
}

void sdl_doit()
{
SDL_Event event;
int done = 0;

while (!done)
{
/* Slow down polling */
SDL_Delay(500);

/* Check for events */
while (SDL_PollEvent(&event))
{
switch (event.type)
{
//case SDL_KEYDOWN:
/* Any keypress quits the app... */
case SDL_QUIT:
done = 1;
break;
default:
break;
}
}
}
}

void sdl_exit()
{
SDL_Quit();
}

int graphic_init(void)
{
return InitGraphic(&g_screen);
}

void pixel(int x, int y, Uint32 color)
{
SDL_Pixel(g_screen, x, y, color);
}

void myrefresh()
{
SDL_Flip(g_screen);
}

代码很简单,SDL相关的操作就3个:初始化SDL,SDL事件处理,退出SDL。

测试代码如下:

int sdl_test()
{
sdl_init();

line(1, 1, 200, 200, 0xff0000);
rect(100, 20, 200, 100, 0x00ff00);

put_string_ascii(10, 200, "AbcD", 0x0000ff);
FILE* fp = fopen("HZK/HZK24K", "rb");
if (fp == NULL)
return -1;
put_font(fp, 10, 250, "引刀成一快 hello,不负少年头 world", 0xffffff);

sdl_doit();
sdl_exit();

return 0;
}

效果图如下图:

说明:

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:7942463
帖子:1588486
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP