首页 > 学院 > 开发设计 > 正文

SDL点、线、面及图像加载

2019-11-08 02:13:03
字体:
来源:转载
供稿:网友

SDL画图系列之点,线,面

SDL库并没有提供直接画点的函数。不过在开发文档中提供了一个在任意视频模式下画出一个像素点的例子。我们可以写自己的画点函数。 有了画点函数意义非凡,我们可以使用它加上数学中美丽的方程绘出各种各样惊艳的图案。比如蝴蝶曲线啥的。这里简单的绘制一个点,主要用于说明使用。

#include <stdio.h>#include <stdlib.h>#include <SDL.h>#define Uint32 unsigned int#define Uint16 unsigned short/* custom draw_Point */void DrawPixel(SDL_Surface *screen, int x, int y, Uint32 color){ Uint16 *bufp; if(SDL_MUSTLOCK(screen)){ if(SDL_LockSurface(screen) < 0){ return ; } } bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color; if(SDL_MUSTLOCK(screen)){ SDL_UnlockSurface(screen); } SDL_UpdateRect(screen,x,y,1,1);}int main(){ SDL_Surface *screen; Uint32 color; if(SDL_Init(SDL_INIT_VIDEO) < 0){ fPRintf(stderr,"can not init SDL: %s/n",SDL_GetError()); exit(1); } screen = SDL_SetVideoMode(640,480,16,SDL_SWSURFACE); /* 640*480*16 */ if(screen == NULL){ fprintf(stderr,"can't set 640*480*16 video mode: %s/n",SDL_GetError()); exit(1); } atexit(SDL_Quit); color = SDL_MapRGB(screen->format,255,255,255); /* last three parameters are red, green and blue. */ DrawPixel(screen,320,240,color); SDL_Delay(3000); return 0;}

结果:在屏幕上绘制一个白点。 不过,在SDL_draw库中倒是存在着基本的绘画函数,我们包含相应的头文件,然后调用库函数即可,连接时加上选项-lSDL_draw 添加代码:

#include <SDL_draw.h>...Draw_Pixel(screen,320,240,color);SDL_UpdateRect(screen,0,0,0,0);

这种现象很有意思,为什么自定义画点函数不需要更新,但是SDL_draw库的Draw_Pixel函数需要更新呢?两者的内容不一样? 话说回来,怎么查看void Draw_Pixel(SDL_Surface *super, Sint16 x, Sint16 y, Uint32 color);的具体实现啊。

线

简单应用SDL_draw库即可,它提供了函数void Draw_Line(SDL_Surface *super, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);,我们可以在SDL_draw-1.2.13/./doc/index.html 查看相关的说明。当然我们也可以书写自己的函数。这里直接用库函数简单体验。

#include <stdio.h>#include <stdlib.h>#include <SDL.h>#include <SDL_draw.h>#define Uint32 unsigned int#define Uint16 unsigned shortint main(){ SDL_Surface *screen; Uint32 color; if(SDL_Init(SDL_INIT_VIDEO) < 0){ fprintf(stderr,"can not init SDL: %s/n",SDL_GetError()); exit(1); } screen = SDL_SetVideoMode(640,480,16,SDL_SWSURFACE); /* 640*480*16 */ if(screen == NULL){ fprintf(stderr,"can't set 640*480*16 video mode: %s/n",SDL_GetError()); exit(1); } atexit(SDL_Quit); color = SDL_MapRGB(screen->format,255,255,255); /* last three parameters are red, green and blue. */ Draw_Line(screen,10,10,300,300,color); SDL_UpdateRect(screen,0,0,0,0); SDL_Delay(3000); return 0;}shell> gcc drawLine.c -lSDL -lSDL_draw -o drawLineshell> ./drawLine

这里写图片描述

对于面而言,图形很多啊,矩形,圆形,不规则多边形等等。

void Draw_Circle(SDL_Surface *super, Sint16 x0, Sint16 y0, Uint16 r,Uint32 color);void Draw_FillCircle(SDL_Surface *super, Sint16 x0, Sint16 y0, Uint16 r, Uint32 color);void Draw_HLine(SDL_Surface *super,Sint16 x0,Sint16 y0, Sint16 x1, Uint32 color);void Draw_VLine(SDL_Surface *super, Sint16 x0,Sint16 y0, Sint16 y1, Uint32 color);void Draw_Rect(SDL_Surface *super, Sint16 x,Sint16 y, Uint16 w,Uint16 h, Uint32 color);void Draw_FillRect(SDL_Surface *super, Sint16 x,Sint16 y, Uint16 w,Uint16 h, Uint32 color);void Draw_Ellipse(SDL_Surface *super, Sint16 x0, Sint16 y0, Uint16 Xradius, Uint16 Yradius, Uint32 color);void Draw_FillEllipse(SDL_Surface *super, Sint16 x0, Sint16 y0, Uint16 Xradius, Uint16 Yradius, Uint32 color);void Draw_Round(SDL_Surface *super, Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, Uint16 corner, Uint32 color);void Draw_Round(SDL_Surface *super, Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, Uint16 corner, Uint32 color);

在SDL_draw库文件夹中,有一个sdldrawtest.c的文件,我们编译连接,可以发现多边形的效果。

root@Ubuntu1:/home/edemon/SDL_draw-1.2.13# gcc sdldrawtest.c -o sdlTest -lSDL -lSDL_drawroot@ubuntu1:/home/edemon/SDL_draw-1.2.13# ./sdlTest

这里写图片描述

SDL之加载图像

在博文linux图形编程之SDL中,我们使用SDL库函数SDL_LoadBMP(const char *)加载过图片,但是这局限于BMP图片,有其他的方法来处理更多格式的图片吗? SDL有许多的开发库,比如:

作用
SDL 基本库
SDL_image 图像库
SDL_mixer 混音库
SDL_net 网路库
SDL_ttf TrueType字体

我们想要的方案就在图象库中。 SDL_image支持的图像格式:BMP, GIF, JPEG, LBM, PCX, PNG, PNM, TGA, TIFF, WEBP, XCF, XPM, XV。 下载SDL_image-1.2.2.tar.gz,网址:http://www.libsdl.org/projects/SDL_image/release/ 然后解压,进入文件夹后,安装三部曲,./configure; make; make install 安装的时候Linux最好联网,我在不联网的情况下安装时,jpglib库就没能正常安装。 安装过程中有这样的信息:

chmod 644 /usr/local/lib/libSDL_image.aPATH="$PATH:/sbin" ldconfig -n /usr/local/lib----------------------------------------------------------------------Libraries have been installed in: /usr/local/lib.../bin/sh ./mkinstalldirs /usr/local/bin /bin/sh ./libtool --mode=install /usr/bin/install -c showimage /usr/local/bin/showimage/usr/bin/install -c .libs/showimage /usr/local/bin/showimage/bin/sh ./mkinstalldirs /usr/local/include/SDL /usr/bin/install -c -m 644 SDL_image.h /usr/local/include/SDL/SDL_image.hmake[1]: Leaving directory '/home/edemon/SDL_image-1.2.2'

为以后的方便编译连接,直接将/usr/local/lib下的image的相关文件复制到/usr/lib下。

shell> cd /usr/local/libshell> sudo cp *image* /usr/lib/

头文件复制到/usr/include下:edemon@ubuntu1:~/SDL_image-1.2.2$ sudo cp SDL_image.h /usr/include/ 我们可以看到他和/usr/local/include/SDL下的SDL_image.h是没有区别的。 edemon@ubuntu1:/usr/local/include/SDL$ diff SDL_image.h /home/edemon/SDL_image-1.2.2/SDL_image.h 在同样的操作步骤后,我不明白,为什么SDL基本库可以通过man来查阅函数,但是SDL_image库中的函数就不能。 接下来,我们使用函数IMG_LOAD()来加载一张png图片。 cat LoadPic.c

#include <stdio.h>#include <stdlib.h>#include <SDL.h>#include <SDL_image.h>int main(){//#define LOAD_PNG char *file = "/home/edemon/Pictures/quan.png"; SDL_Surface *screen; SDL_Surface *picture; if(SDL_Init(SDL_INIT_VIDEO) < 0){ fprintf(stderr,"SDL_INIT_VIDEO error %s/n",SDL_GetError()); exit(1); } picture = IMG_Load(file); if(picture == NULL){ fprintf(stderr,"IMG_Load error %s/n",SDL_GetError()); exit(1); } screen = SDL_SetVideoMode(picture->w,picture->h,16,SDL_SWSURFACE); if(screen == NULL){ fprintf(stderr,"couldn't set 640*480*16 bits color model, error is %s/n",SDL_GetError()); exit(1); } /* int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect); */ if(SDL_BlitSurface(picture,NULL,screen,NULL) < 0){ fprintf(stderr,"SDL_BlitSurface error %s/n",SDL_GetError()); exit(1); } SDL_UpdateRect(screen, 0, 0, 0, 0); atexit(SDL_Quit); SDL_FreeSurface(picture); SDL_Delay(5000); SDL_FreeSurface(screen); return 0;}shell> gcc LoadPic.c -lSDL -lSDL_imageshell> ./a.out

在我的ubuntu上始终不支持JPG(JPEG)啊,坑了我一晚上。这是为什么,我的代码有问题? 自己将LoadPic.c中加载png图片改成加载jpg图片。

./a.out IMG_Load error Unsupported image format

在SDL_image文件夹中查看源码IMG_jpg.c,我们发现函数SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src)#ifdef LOAD_JPG代码区间内,于是预先定义LOAD_JPG,在主函数外添加#define LOAD_JPG,还是一样的效果。 那么我就使用安装生成的showimage进行测试,发现这样仍然有这样的提示信息:Unsupported image format

shell> /usr/local/bin/showimage /home/edemon/Pictures/sum.jpg Couldn't load /home/edemon/Pictures/sum.jpg: Unsupported image format

先记着吧。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表