/ * 声明标准图形函数头文件* /
int main( )
{
int g driver , gmode; / * 定义图形驱动器变量* /
gdriver= DETECT ; / * 设定图形驱动器为自动监测* /
initgraph( & gdriver, & gmode,c: \ tc) ;
/ * 初始化图形模式* /
line( 100, 100, 200, 200) ; / * 画线* /
getch( ) ;
clo seg raph( ) ; / * 关闭图形模式* /
return 0;
}
程序的几点说明:
(1) 对于gdriver, 是原本要求设置所希望的并且计算机提供的图形驱动器, 而gmode 则是对应于这种驱动器的使用模式。将gdriver 设置为DETECT, 让硬件自动监测图形驱动器和模式, 这将非常省力。
(2) 如果发现bg i 文件在c: \ tc 目录下, 而当前目录在c: \ \ 下, path 可以使用绝对路径, 如: c: \ \ tc; 也可以使用相对路径, 如: \ \ tc。
(3)一旦初始化了图形模式便可以作图了, 在程序中line ( 100, 100, 200, 200) 语句就是在图形模式下画一条从点( 100, 100) 到点( 200, 200) 的直线。(4) 使用closeg raph( ) 函数来退出图形状态回到默认的文本状态。
2 在图形模式下写字
在图形模式下, 仍然可以使用标准输出printf( ) ,put s( ) , putchar ( ) 将文本输出到屏幕。不过C 语言图形函数提供了一些专门用于在图形显示模式下的文本输出函数out tex txy ( ) 等。
还可以利用setcolor( ) 函数设置输出文字的颜色。用户还可以对文本字符大小进行设置, 具体实现方法有如下两个函数:
sett ex tsty le( ) / * 水平和垂直方向以相同倍数放大* /
setusercharsize( ) / * 分别定义水平和垂直放大倍数* /
3 独立图形程序的建立
当在图形模式下写好程序, 然后放在别的用户的计算机中却发现对方根本无法使用。这是因为在设置图形模式的时候, 要求有对应的BGI 文件( 对于用init graph( ) 函数直接进行图形初始化程序, 在编译和连接时并没有将相应的驱动程序* . bgi 装入到执行程序) 。而将软件复制给用户的时候并没有将BGI 文件复制给用户, 于是用户根本无法进入图形模式( 当程序进行到initgraph( ) 语句时, 从该函数中第三个形式参数char* path 所规定的路径中去找相应的驱动程序, 若没有,将出现错误:
BGI Eorro: Gra phics not initialize ( useinitgraph) )即便将所有* . bgi 文件复制给用户, 还是可能存在一个路径错误问题。
因此只能将BGI 文件( 图形驱动程序) 也一起装到程序中, 这样问题就解决了。这里提供了建立一个不需要驱动程序就能独立运行的可执行图形程序的方法, 以下是具体步骤( 这里以VGA EGA 显示器为例) :
(1) 在C 语言编译器目录下输入命令:
BGIOBJ EGAVGA
BGIOBJ 命令将驱动程序EGAVGA. BGI 转化成EGAVGA. OBJ 的目标文件。
(2) 在C 语言编译器目录下输入命令:
TLIBLIB\ GRAPHICS. LIB+ EGAVGATLIB 命令的意思是将EGABGA. OBJ 的目标模块装到GRAPHICS. LIB 库文件中。
(3) 在程序中调用initgraph( ) 函数之前加上一句:
registerbg idriver( EGAVGA_driver) ;
该函数告诉连接程序在连接时把EGAVGA 的驱动程序装入到GRA PHICS. LIB 库文件中。
分页
4 实现动画思路
为了达到动态显示由下位机传送过来的信息, 就必须使用动画技术。动画片的原理是将一幅一幅的图片排列起来, 至少以24 幅/ s 的速度连续播放, 这样以来骗过了人们迟钝的眼睛, 使人们误以为看到的一切在运动, 而忘记了这一切都只是静止图片组成的。
这一思路对做电脑动画非常有帮助, 很容易让人联想到将屏幕作为一张图片, 每次对屏幕这样的图片进行重新绘制。具体思路如下:
(1) 在屏幕上画一个将要运动的图像;
(2) 停留一些时间( 事实上非常短, 很可能只有几十到几百毫秒) ;
(3) 清除屏幕( 或者是屏幕的局部);
(4) 在刚才被清除的地方相近处( 固定增量) 重新画一个图像;
(5) 重复步骤(2) ~ (4) 。
5 简单动画实现
逻辑运算中的异或指A 与B 的非同B 与A 的非进行或操作的结果。异或逻辑运算有一个特点, 如果A 和B 是相同的, 那么结果一定为0( 1 异或1= 1* 0+0* 1= 0+ 0= 0) 。或者说, 自身异或等于没有进行任何操作。异或与图形绘制有一定的关系。
如果在一个位置画了一条红色的线, 然后在这个位置再画一次结果是红线还在那里, 没有变化。可是如果在画第一条线之前就设置用异或方式画线, 那么当画第二条线的时候奇迹便发生了屏幕上的那条红线消失了。实现清单如下:
# include
# include < stdio.h>
# include < stdlib.h>
# include < conio.h>
int main( void) {
int gdriver= DETECT , gmode;
initgraph( & gdriver, & gmode, ) ; / / 初始化图形模式
setwritemode( XOR_PUT) ; / / 设置异或模式
setcolor( RED) ; / / 设置前景颜色为红色
line( 100, 200, 500, 200) ; / / 画红线
getch( ) ;
closeg raph( ) ; / / 关闭图形模式, 恢复到文本模式
return 0;
}
在要进行异或操作之前, 使用了一个设置异或模式的函数setwritemode( ) 。异或可以帮助我们用最简单的方法二次完全重画方法擦除原先的图形。那么如何将它和动画联系起来呢?
提出的异或思路如下:
(1)设置异或模式, 然后在屏幕上画一个圆和一个正方形;
(2)停留一些时间;
(3)在刚才画圆的位置用同样的颜色再画一个圆(圆消失了) ;
(4)在刚才画圆位置相近处( 固定增量) 再画一个圆;
(5)重复步骤(2) ~ (4) 。
以下是使用异或思路实现一个运动的圆和一个静止的正方形的例程。
分页
# include < graphics. h>
# include < stdlib. h>
# include < stdio. h>
# include < conio . h>
int main( void)
{ int gdriver= DETECT, gmode;
void * ball;
int x, y, maxx ;
unsigned int size;
initgraph( & g driver, & gmode,) ;
maxx= get maxx ( ) ;
x= 0; y= 200;
rectangle( x , y+ 11, x+ 20, y+ 31) ; / / 绘制矩形
circle( x+ 10, y, 10) ; / / 绘制圆
size= imagesize( x , y- 10, x+ 20, y+ 10) ;
/ / 计算保存区域大小
ball= mallo c( size) ; / / 申请保护区域内存
getimage( x , y- 10, x+ 20, y+ 10, ball) ;
/ / 保存圆所在的位置图形到内存
while( ! kbhit( ) ) {
putimage( x, y- 10, ball, XOR_PUT) ;
/ / 用异或方式在新位置绘制圆, 圆消失
x+ = 10; / / 计算圆移动增量
if ( x> = max x ) {
x= 0;
putimage( x, y- 10, ball, XOR_PUT) ;
/ / 用异或方式在新位置绘制圆, 圆出现
delay( 1000) ; / / 延迟一定时间
} }
free(ball) ;
closegraph( ) ;
return 0;
}
该程序的运行情况, 和前面的例程的效果差不多。但从实际画点开销角度来看, 3 个圆球运行的例程是不一样的。
本例程使用XOR 异或方法重画, 每次画点开销为:
10* 4 点(重画圆形清除) + 10* 4 点(重画圆形) = 80 点
由此可见,异或在这里是最好的绘制动画的选择。