第 10 章 Linux的图形编程
本章重点 使用SDL图形开发库并及图形模式的初始化 基本绘图函数的应用 图片与文字的显示 动画 三维绘图 用SDL实现简单游戏设计
10.1 Linux的图形编程简介 在Linux 图形编程中,基于控制台的图形库主要有: SVGALib: 是最早基于Linux的非X的图形支持库。 FrameBuffer:出现在Linux 2.2.x内核当中的一种驱动程序接口。 GGI:新一代的图形支持库。可在 FrameBuffer, SVGALib等设备上运行。在所有平台上提供了一致的输入设备接口, 采用共享库机制, 实现低层支持库的动态装载等 。 OpenGL: 是个专业的3D程序接口,功能强大,调用方便的底层3D图形库。 SDL:是一个跨平台的多媒体游戏支持库,包含了对图形、声音、游戏杆、线程等的支持。
10.2 安装和使用SDL图形开发库 系统安装时一般都已经默认安装了SDL库,如没安装,参见附录。 SDL的基本库与附加库的库名与含义: 使用SDL库需要包含头文件:#include "SDL.h" 编译命令为: gcc –I/usr/include/SDL –lSDL 源程序名 –o 目标文件名 -lpthread 如果程序中使用了图像库和混音库,在编译的时候还需要加上相应的编译参数,分别是 -lSDL_image和-lSDL_mixer。
10.3 初始化图形模式 初始化图形模式中常用函数及功能 : 10.3 初始化图形模式 初始化图形模式中常用函数及功能 : 要加载和初始化SDL库需要调用SDL_Init()函数,该函数以一个参数来传递要激活的子系统的标记。 SDL_Init()函数说明: flags参数取值所对应的子系统对象 :
10.3 初始化图形模式 例10.1 初始化视频子系统,设置显示模式为640×480大小。设置初始颜色为红色并对颜色值进行改变,使程序执行过程中背景色渐变。编写程序10-1.c,放在/home/cx/10-1目录下。 分析 用SDL_Init(SDL_INIT_VIDEO)初始化视频子系统,并用SDL_SetVideoMode()函数设置显示模式,最后用SDL_MapRGB()设置背景颜色。 流程图如图所示
10.3 初始化图形模式 步骤1 设计编辑源程序代码。 [root@localhost root]#mkdir /home/cx/10-1 10.3 初始化图形模式 步骤1 设计编辑源程序代码。 [root@localhost root]#mkdir /home/cx/10-1 root@localhost root]#cd /home/cx/10-1 [root@localhost 10-1]#gedit 10-1.c
10.3 初始化图形模式 步骤2 编写makefile工程文件 步骤3 执行make文件 步骤4 执行可执行文件 10.3 初始化图形模式 步骤2 编写makefile工程文件 [root@localhost 10-1]#vi makefile CC = gcc AR = $(CC)ar CFLAGS= -I/usr/include/SDL -lSDL -lpthread 10-1:10-1.c $(CC) $(CFLAGS) $^ -o $@ clean: -rm -f $(EXEC) *.elf *.gdb *.o 步骤3 执行make文件 [root@localhost 10-1]# make gcc -I/usr/include/SDL -lSDL -lpthread 10-1.c -o 10-1 步骤4 执行可执行文件 [root@localhost root]#./10-1 注意:gcc编译的时候要切换到文件所在目录下。如程序运行在Fedora Core 4环境,则不需要添加参数-lpthread。
10.3 初始化图形模式 SDL_SetVideoMode函数说明
10.3 初始化图形模式 SDL_Quit()函数说明 SDL_MapRGB函数说明
10.3 初始化图形模式 SDL_FillRect函数说明
10.3 初始化图形模式 SDL_UpdateRect函数说明
10.3 初始化图形模式 SDL_Delay函数说明 SDL使用中的一些数据类型: Uint8——相当于unsigned char 10.3 初始化图形模式 SDL_Delay函数说明 SDL使用中的一些数据类型: Uint8——相当于unsigned char Uint16——16位(2字节)unsigned integer Uint32——32位(4字节)unsigned integer Uint64——64位(8字节)unsigned integer
10.3 初始化图形模式 思考题: 编写一个简单的SDL初始化程序:要求背景色为红色,让屏幕停留5秒。 10.3 初始化图形模式 思考题: 编写一个简单的SDL初始化程序:要求背景色为红色,让屏幕停留5秒。 编写一个简单的SDL初始化程序:要求背景色的红、绿、兰为随机显示值,让屏幕停留10秒。
10.4基本绘图函数的应用 本节主要应用SDL_draw函数库绘制点、线、圆等基本图形。 常用的基本绘图函数及功能:
10.4基本绘图函数的应用 例10.2 使用SDL_draw库设计一个程序,初始化视频子系统,设置显示模式为640×480,画面的色深为16位,用Draw_Line函数画两条交叉的直线,一条直线起始点的坐标为(240,180),终止点的坐标为(400,300),另一条直线起始点的坐标为(400,180),终止点的坐标为(240,300)。再用Draw_Pixel函数绘制一条正弦曲线,程序名为10-2.c,存放在/home/cx/SDL_draw-1.2.11下。 步骤1 设计编辑源程序代码。 [root@localhost SDL_draw-1.2.11]#gedit 10-2.c
10.4 基本绘图函数的应用 步骤2 编写makefile工程文件 步骤3 执行make文件 [root@localhost 10-3]#vi makefile CC = gcc CCFLAGS = -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a 10-2: 10-2.c $(CC) -o 10-2 10-2.c $(CCFLAGS) 步骤3 执行make文件 [root@localhost 10-2]# make gcc -o 10-2 10-2.c -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a
10.4 基本绘图函数的应用 步骤4 编译成功后,执行可执行文件10-2,输入如下: 步骤4 编译成功后,执行可执行文件10-2,输入如下: [root@localhost 10-2]#./10-2
10.4 基本绘图函数的应用 Draw_Line函数说明
10.4 基本绘图函数的应用 Draw_Pixel函数说明
10.4 基本绘图函数的应用 思考题: 编写一个简单的画线程序:要求设置背景色为红色,线条颜色为绿色,绘制一个边长为120的正三角形,同时让屏幕停留8秒。 线段长度无限短后就成为点,请用画线的方法画出正弦曲线。 能否用画线的方法实现动画。
10.4 基本绘图函数的应用 例10.3 使用SDL_draw库设计一个程序,初始化视频子系统,设置显示模式为640×480,画面的色深为16位,画5个黄色的同心圆,圆心坐标为(320,240),最小的圆半径为5,其他圆的半径以15的大小递增,程序名为10-3.c,存放在/home/cx/SDL_draw-1.2.11下。 步骤1 设计编辑源程序代码。 [root@localhost SDL_draw-1.2.11]#gedit 10-3.c
10.4 基本绘图函数的应用 步骤2 编写makefile工程文件 步骤3 执行make文件 [root@localhost 10-3]#vi makefile CC = gcc CCFLAGS = -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a 10-3: 10-3.c $(CC) -o 10-3 10-3.c $(CCFLAGS) 步骤3 执行make文件 [root@localhost 10-3]# make gcc -o 10-3 10-3.c -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a 步骤4 编译成功后,执行可执行文件10-3,输入如下: [root@localhost 10-3]#./10-3
10.4 基本绘图函数的应用 Draw_Circle函数说明
10.4 基本绘图函数的应用 思考题: 编写一个画圆的程序。要求设置背景色为黄色,线条颜色为蓝色,以正三角形的三个顶点为圆心,半径为60画三个圆,同时让屏幕停留8秒。 画一个半径渐渐增大、颜色随机变化的圆。 画一个圆,此圆沿着正弦曲线运动。 提示:请参考下列代码 for(i=0;i<120;i++,x=x+3,y=y+sin(x-80)) { Draw_Circle(screen,x,y, r, SDL_MapRGB(screen->format, 255,0,0)); SDL_Delay(100); Draw_Circle(screen,x,y, r, SDL_MapRGB(screen->format, 255,255,255)); Draw_Line(screen, x,y, x+3,y=y+sin(x-80),SDL_MapRGB(screen->format, 255,0,0)); SDL_UpdateRect(screen, 0, 0, 0, 0); /*更新整个屏幕*/ }
10.4 基本绘图函数的应用 10.4 使用SDL_draw库设计一个程序,初始化视频子系统,设置显示模式为640×480,画面的色深为16位。用Draw_Rect函数画两个矩形,一个矩形的左上角坐标是(80,180),宽和高分别是160和120,颜色为白色;另一个矩形的左上角坐标是(319,179),宽和高分别是242和122,颜色为黄色。用Draw_FillRect函数画一个矩形,其左上角坐标是(320,180),宽和高分别是240和120,颜色为红色。程序名为10-4.c,存放在/home/cx/SDL_draw-1.2.11下。 步骤1 设计编辑源程序代码。 [root@localhost SDL_draw-1.2.11]#gedit 10-4.c
10.4 基本绘图函数的应用 步骤2 编写makefile工程文件 步骤3 执行make文件 [root@localhost 10-4]#vi makefile CC = gcc CCFLAGS = -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a 10-4: 10-4.c $(CC) -o 10-4 10-4.c $(CCFLAGS) 步骤3 执行make文件 [root@localhost 10-4]# make gcc -o 10-4 10-4.c -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a 步骤4 编译成功后,执行可执行文件10-4,输入如下: [root@localhost 10-4]#./10-4
10.4基本绘图函数的应用 Draw_Rect函数说明 : 思考题:编写一个画矩形的程序:实现五个矩形从大到小向屏幕中心依次缩小,每个矩形间隔20个单位,要求最里面即最小的矩形宽、高分别为80和60,同时让屏幕停留5秒。
10.4基本绘图函数的应用 例10.5 使用SDL_draw库设计一个程序,初始化视频子系统,设置显示模式为640*480,表面的色深为16位,用Draw_HLine函数画一水平直线,起始点为(240,240),长度为160,颜色为白色;用Draw_VLine函数画一垂直直线,起始点为(320,180),长度为120,颜色为红色,用Draw_Ellipse函数画一椭圆,圆心(240,180),x轴径76,y轴径56,颜色为蓝色,用Draw_FillEllipse填充此椭圆,用Draw_Round画一圆角矩形,左上角坐标为(322,122),宽为156,高为116,圆角的半径为10,颜色为绿色,用Draw_FillRound填充此圆角矩形。 步骤1 设计编辑源程序代码。 [root@localhost SDL_draw-1.2.11]#gedit 10-5.c
10.4 基本绘图函数的应用 步骤2 编写makefile工程文件 步骤3 执行make文件 [root@localhost 10-5]#vi makefile CC = gcc CCFLAGS = -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a 10-5: 10-5.c $(CC) -o 10-5 10-5.c $(CCFLAGS) 步骤3 执行make文件 [root@localhost 10-5]# make gcc -o 10-5 10-5.c -Wall -I/usr/include/SDL -D_REENTRANT -I/home/cx/SDL_draw-1.2.11/include -L/usr/lib -Wl,-rpath,/usr/lib -lSDL -lpthread /home/cx/SDL_draw-1.2.11/src/.libs/libSDL_draw.a 步骤4 编译成功后,执行可执行文件10-5,输入如下: [root@localhost 10-5]#./10-5
10.4基本绘图函数的应用 Draw_HLine函数说明: Draw_VLine函数说明: Draw_Ellipse函数说明: Draw_Round函数说明:
10.5 图片与文字显示 常用的函数及功能 :
10.5 图片与文字显示 例10.6 设计一个程序,初始化视频子系统,设置显示模式为640×480,画面的色深为16位,加载位图b.bmp,并按照一定的顺序把位图排列显示。设程序名为10-6.c,存放在/home/cx/下,位图名为b.bmp也存放在该目录下。 分析 在程序中编写一个showBMP()函数,用来显示位图,在主函数中调用它。showBMP()函数中给位图分配一个surface,得到位图的大小。在主函数中先初始化视频系统,设置视频模式,指定第一张图片的位置,然后利用for循环显示图片。 步骤1 设计编辑源程序代码。 [root@localhost cx]#gedit 10-6.c
10.5 图片与文字显示 步骤2 编译程序。 步骤3 编译成功后,执行可执行文件10-6,输入如下: 10.5 图片与文字显示 步骤2 编译程序。 切换到源程序所在目录下,用gcc进行编译,编译的时候加上-lSDL和-lpthread选项。 [root@localhost cx]# gcc -I/usr/include/SDL -lSDL -lpthread 10-6.c -o 10-6 或写成makefile文件,然后执行make命令。makefile文件代码如下: CC = gcc AR = $(CC)ar CFLAGS= -I/usr/include/SDL -lSDL -lpthread 10-6:10-6.c $(CC) $(CFLAGS) $^ -o $@ clean: -rm -f $(EXEC) *.elf *.gdb *.o 步骤3 编译成功后,执行可执行文件10-6,输入如下: [root@localhost cx]#./10-6
10.5 图片与文字显示 SDL_LoadBMP函数说明: SDL_BlitSurface函数说明:
10.5 图片与文字显示 思考题:要求自行制作一张矩形位图,用位图实现屏幕左上角到屏幕右下角对角线连接(模拟图如下图所示),图片按照阶梯的形式在程序运行的时候显示出来,同时让屏幕停留5秒,在Linux下编辑、编译、运行。
10.5 图片与文字显示 例10.7 设计一个程序,初始化视频子系统,设置显示模式为640×480,画面的色深为16位,使用SDL_ttf库在屏幕上显示“Linux下TrueType字体显示示例”,字体大小为38,颜色为红色。设程序名为10-7.c,存放在/home/cx/下。 分析 显示中文字体首先要打开字库文件,字库用的是simsun.ttc文件,视频子系统的初始化和设置都和之前一样,然后分配一个专门用来显示字体的surface,使用SDL_BlitSurface()对象快速转换。 步骤1 准备工作。 把Windows下C:\WINDOWS\Fonts中的simsun.ttc文件拷贝到Linux下的/usr/share/fonts/下,用于显示中文。 步骤2 设计编辑源程序代码。 [root@localhost cx]#gedit 10-7.c
10.5 图片与文字显示 步骤3 编译程序。 切换到源程序所在目录,用gcc进行编译,在编译时需要添加-lSDL_ttf参数选项。 10.5 图片与文字显示 步骤3 编译程序。 切换到源程序所在目录,用gcc进行编译,在编译时需要添加-lSDL_ttf参数选项。 [root@localhost cx]# gcc -I/usr/include/SDL -lSDL -lpthread 10-7.c -o 10-7 -lSDL_ttf 文件保存的时候请使用UTF8格式保存,才能正常显示中文字体。
10.5 图片与文字显示 TTF_OpenFont函数说明 TTF_SetFontStyle函数说明
10.5 图片与文字显示 TTF_RenderUTF8_Blended函数说明
10.5 图片与文字显示 TTF_Init函数说明 TTF_CloseFont函数说明
10.5 图片与文字显示 TTF_Quit函数说明 思考题:编写一个程序,主要实现粗体、斜体、下划线等字体效果,同时让屏幕停留5秒。
10.6 动画 动画的常用函数: 例10.8 设计一个程序,实现矩形的运动,矩形是通过位图显示,当矩形碰到四边时,会自动反弹,按任意键退出。按程序名为10-8.c,存放在/home/cx/下,位图素材(b.bmp)也存放在该目录下。 分析 加载位图直接使用SDL_LoadBMP()函数。位图在xy方向上的坐标都以3个单位的移动量在一定的时间差内起规律性变化,向左直至键盘激发退出事件。
10.6 动画 流程图
10.6动画 步骤1 设计编辑源程序代码。 [root@localhost cx]#gedit 10-8.c
10.6动画 步骤2 编译程序。 步骤3 编译成功后,执行可执行文件10-8,输入如下: 步骤2 编译程序。 切换到源程序所在目录下,用gcc进行编译,编译的时候加上-lSDL和-lpthread选项。 [root@localhost cx]# gcc –I/usr/include/SDL –lSDL 10-8.c –o 10-8 –lpthread 步骤3 编译成功后,执行可执行文件10-8,输入如下: [root@localhost cx]#./10-8
10.6 动画 SDL_GetTicks函数说明 SDL_Flip函数说明 思考题:编写一个程序,主要实现圆球运动效果,使用键盘事件,按下Esc键退出程序。
10.7 三维绘图 三维绘图的常用函数:
10.7 三维绘图 例10.9 设计一个程序,在屏幕上绘制一个立体矩形,并按照一定的角度和方向旋转。设程序名为10-9.c,存放在/home/cx/下。 分析 创建三维立体图形要先做一系列的初始化设置,要设置视觉角度、背景色、深度缓存、选择投影矩阵等,三维绘图中比较重要的就是矩阵的运用。具体到绘制的时候,是画一个个平面,同时要注意角度的选择和设置。其中,glTranslatef函数是用来指定具体的值来多元化矩阵,glRotatef函数让对象按照某个轴旋转,两者综合运用使得三维图形有不同的效果。 步骤1 设计编辑源程序代码。 [root@localhost cx]#gedit 10-9.c
10.7 三维绘图 步骤2 程序调试。 步骤3 编译成功后,执行可执行文件10-9,输入如下: 步骤2 程序调试。 切换到源程序所在目录下,用gcc进行编译,编译的时候除了-lSDL和-lpthread选项,还需加上-lGL和-lGLU参数,因为在这程序中用到三维库的支持。 [root@localhost cx]#gcc –I/usr/include/SDL –lSDL 10-9.c –o 10-9 –lpthread –lGL -lGLU 步骤3 编译成功后,执行可执行文件10-9,输入如下: [root@localhost cx]#./10-9
10.7 三维绘图 glViewport函数说明 glClearColor函数说明
10.7 三维绘图 glClearDepth函数说明 glDepthFunc函数说明
10.7 三维绘图 glShadeModel函数说明 glMatrixMode函数说明
10.7 三维绘图 glLoadIdentity函数说明 gluPerspective函数说明
10.7 三维绘图 glTranslatef函数说明 glRotatef函数说明
10.7 三维绘图 glBegin函数说明 glColor3f函数说明
10.7 三维绘图 思考题: 编写一个程序,实现正方体的旋转方向为顺时针,并且使得旋转的速度加快,正方体的上下面颜色为红色,左右面颜色为绿色,前后面颜色为蓝色。(小提示:旋转的速度可以根据旋转的角度值改变量来实现)。 把例10.9中的正方体改成三棱锥。
10.8 游戏程序入门 例10.10 利用SDL库,综合运用以上所学的函数及方法,实现大炮打飞机的游戏。游戏初始化的时候大炮在屏幕底部中间,从屏幕的上方不断出现飞机。可以使用键盘左右方向键控制大炮的左右移动,使用空格键发射炮弹。飞机水平运行,并逐渐往下移动。大炮弹若是击中飞机,飞机爆炸。系统会立即再产生飞机,保证飞机数量为两架。假设飞机下降到大炮的位置,那么大炮就被炸毁,游戏结束。程序名为10-10.c,存放在/home/cx文件下。本题中用到的素材大炮、飞机、背景图片等放在data文件夹里,data文件夹放在/home/cx文件下。 分析 游戏实现一架大炮发射炮弹去射击飞机的游戏。LoadImage()函数把位图添加进来,RunGame()中,调用DrawObject()把大炮、飞机等初始化,collide()函数处理炮弹击中飞机的情况,根据实际情况用CreateAir()创建新的飞机,最后用collicle()处理飞机击中大炮,游戏结束。 流程图如图所示。
10.8 游戏程序入门 步骤1 设计编辑源程序代码。 [root@localhost cx]#gedit 10-10.c
10.8 游戏程序入门 步骤2 程序调试。 步骤3 程序结果运行。 10.8 游戏程序入门 步骤2 程序调试。 切换到源程序所在目录下,用gcc进行编译,编译的时候加上-lSDL和-lpthread选项。 [root@localhost cx]# gcc -I/usr/include/SDL -lSDL 10-10.c -o 10-10 –lpthread 或写成如下的makefile文件,然后执行make命令。 CC = gcc AR = $(CC)ar CFLAGS= -I/usr/include/SDL -lSDL -lpthread 10-10:10-10.c $(CC) $(CFLAGS) $^ -o $@ clean: -rm -f $(EXEC) *.elf *.gdb *.o 步骤3 程序结果运行。
10.8 游戏程序入门 思考题: 改写程序10-8.c,画一块档板,用左右键移动档板,档住下落方块,使得方块不会与底边相碰。当方块与档板相碰时,方块反弹,游戏继续,积分加1;当方块与左、上、右边相碰时反弹,积分不变;当方块与底边相碰时,游戏结束,显示积分值。 改写程序10-10.c,改变飞机、大炮的形状与数量,其余与题10-10.c类似。
思考与实验 参考SDL_draw库中关于椭圆的函数介绍,画一个椭圆。 利用画线,画圆和画矩形,自行创意设计三者结合的图形 。 编写一个程序,运用绘图、位图与文字显示的知识,实现看图识字的效果。即画一个圆,用文字标志“圆”,用位图形式导入一些图片,例如苹果位图,文字标志“苹果”,程序运行结果如下图所示:
思考与实验 参考例10.10,模仿飞机打大炮的原理,实现一个军舰发射鱼雷打怪物的游戏。要求军舰在屏幕上方,向下发射鱼雷,打击不断从屏幕下方出现的怪物,如果怪物上升到和军舰相碰的时候,游戏结束。相关的素材图片请自行准备。 调试程序,根据需要制作相关素材。