引言
C語言中要實現可視化人機界面, 就必須要繪制圖像, 而printf( )函數只能用來輸出文本, 顯然不能滿足繪圖的要求。但是, C語言標準函數庫提供了一個較為強大的圖形函數庫,所有圖形函數都在頭文件graph程序包括了Graphics. h 頭文件以后, 所有圖形函數的使用都必須在圖形模式下進行。而默認模式都是文本模式, 在這種模式下所有圖形函數都是無法正常工作的。所以必須先使用一個圖形模式初始化函數將計算機設置為圖形模式。本文利用這些圖形函數提出了實現可視化人機界面的有效方法。
1 設置圖形模式
要使用C語言繪制圖形通常首先要提供一個graphics. h 頭文件, 它包含了大量的圖形繪制函數。無法立即使用這些函數, 必須首先設置屏幕為圖形模式。要將原來屏幕默認的文本模式(80列, 25 行字符模式) 設置為圖形模式, 必須對顯示卡進行操作。顯示卡實際上就是顯示適配器的通稱, 不同的顯示適配器有著不同的色彩種數和圖形分辨率。因此, 在使用圖形函數作圖之前, 必須使用一個Graphics. h圖形函數庫提供的初始化圖形模式的initgraph( )函數根據顯示適配器種類設置成為某種確定的圖形模式。
另外, 盡管在程序最開始加了# include
BGI Error: Graphics not initialized( use initag raph)下面給出一個最簡化的初始化圖形模式的例程以清楚地說明問題: # include / * 聲明標準圖形函數頭文件* / 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 點
由此可見,異或在這里是最好的繪制動畫的選擇。
(審核編輯: 智匯小新)
分享