SDL学习——画图、点阵显示 | 迟思堂工作室
A-A+

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

2014-08-30 20:57 Windows程序 暂无评论 阅读 2,611 次

很久以前,发表了几篇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: %sn",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: %sn",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(112002000xff0000);

rect(100202001000x00ff00);

put_string_ascii(10200"AbcD"0x0000ff);

FILE* fp = fopen("HZK/HZK24K""rb");

if (fp == NULL)

return -1;

put_font(fp, 10250"引刀成一快 hello,不负少年头 world"0xffffff);

sdl_doit();

sdl_exit();

return 0;

}

效果图如下图: 

SDL测试

说明:

1、其实我使用SDL主要是研究点阵显示的,原有曾经写了很多篇有关的文章,但那都是在我的开发板上的,后来开发板被我搞坏了,Linux系统启动不了,所以想了别的途径继续研究,SDL是一种,ncurses也是一种,权衡再三,还是觉得SDL更好一些。

2、本文所显示的代码只是工程的片段,因为代码还在实现过程中,所以不好将工程打包放上来,等真正完成阶段性的任务时,再发布源代码——但不知道那是何年何月的事了。

3、工程中使用了大部分以前在开发板上显示点阵的代码,也当是一个纪念。



如果本文对阁下有帮助,不妨赞助笔者以输出更多好文章,谢谢!
donate



标签:

给我留言