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

很久以前,发表了几篇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(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;
}

效果图如下图: 

说明:

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

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

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

发布了481 篇原创文章 · 获赞 245 · 访问量 110万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览