摘 要:針對(duì)實(shí)際的航空數(shù)字化儀表,給出了SVGA顯示模式下動(dòng)畫顯示的實(shí)現(xiàn)過程,其中包括了直接寫屏技術(shù)、雙緩沖技術(shù)等,并提出了一種利用顯存自身實(shí)現(xiàn)雙緩沖動(dòng)畫顯示的新方法。
關(guān)鍵詞:數(shù)字化儀表;SVGA;動(dòng)畫;雙緩沖
一、 引言
目前飛機(jī)座艙顯示系統(tǒng)中使用的電子顯示儀表,基本上沿用傳統(tǒng)的指針顯示形式。而計(jì)算機(jī)成像的彩色動(dòng)畫顯示格式,則突破了傳統(tǒng)的顯示形式,使飛行員能迅速掌握瞬息變化的動(dòng)態(tài)信息,做到一目了然,直接提高飛行員的作戰(zhàn)能力。在座艙顯示系統(tǒng)中最常見的顯示方式就是指針指示。這就涉及到指針的動(dòng)態(tài)顯示原理, C語言標(biāo)準(zhǔn)圖形函數(shù)通常強(qiáng)調(diào)更高的通用性,于是必然付出函數(shù)效率很低的代價(jià),另外也不支持256色的顯示模式,不能滿足座艙顯示系統(tǒng)的要求,所以本人開發(fā)了一套SVGA256色顯示模式下的圖形函數(shù)庫,從顯示模式設(shè)置的的底層開始,到運(yùn)用顯存自身實(shí)現(xiàn)雙緩沖顯示技術(shù),大大提高了效率與顯示質(zhì)量。
二、 常用動(dòng)畫顯示技術(shù)介紹
圖形動(dòng)畫技術(shù)有很多種,對(duì)C語言編程比較適合的主要包括:
1) 重畫技術(shù):
畫了擦,擦了再畫,或者一張一張貼(覆蓋)上去。這是最常用的一種技術(shù),操作比較簡(jiǎn)單,又分為全屏重畫和局部重畫兩種,但動(dòng)畫效果較差,存在閃爍現(xiàn)象。
2) 異或技術(shù):
通過對(duì)寫入點(diǎn)和屏幕顏色進(jìn)行邏輯異或運(yùn)算,來實(shí)現(xiàn)擦除和重畫運(yùn)動(dòng)部分的動(dòng)畫。具體的說就是如果在同一個(gè)位置用異或的方法畫兩個(gè)顏色相同的點(diǎn),點(diǎn)會(huì)消失;而用不同顏色畫點(diǎn),點(diǎn)會(huì)變成第三種顏色。這種方法由于也存在二次擦除的過程,所以也會(huì)有閃爍現(xiàn)象。
3) 調(diào)色板技術(shù):
利用預(yù)先設(shè)置的動(dòng)作圖片和顯示適配中彩色表(調(diào)色板寄存器)通過屏幕的顏色變化來實(shí)現(xiàn)動(dòng)畫的技術(shù)。在SVGA顯示模式下,256種顏色分別對(duì)應(yīng)256個(gè)調(diào)色板寄存器,而每種顏色又是由R、G、B(范圍都是0-255)三原色的值配出來的,每一個(gè)寄存器中的值可由程序進(jìn)行設(shè)置,即可以通過程序改變這256個(gè)索引顏色的實(shí)際顏色。于是可以先將幾個(gè)索引顏色設(shè)置為黑色,然后使用這幾個(gè)索引顏色依次繪制出動(dòng)畫元素每個(gè)動(dòng)畫動(dòng)作,這樣每次將當(dāng)前位置動(dòng)作所用的索引顏色值設(shè)為當(dāng)前顏色,其它動(dòng)作的索引顏色設(shè)為黑色,就可以實(shí)現(xiàn)動(dòng)畫顯示。
這種動(dòng)畫方法由于不對(duì)屏幕進(jìn)行操作,所以畫面及其穩(wěn)定、流暢,無閃爍現(xiàn)象。但由于動(dòng)畫的所有動(dòng)作都必須在動(dòng)畫之前完成,而且要用不同的索引顏色,所以這種方法無法處理復(fù)雜的動(dòng)畫元素。對(duì)于機(jī)載顯示系統(tǒng)來說,指針的實(shí)際位置很多,而且要根據(jù)實(shí)際情況而定,所以無法采用調(diào)色板技術(shù)實(shí)現(xiàn)指針的動(dòng)畫顯示。
本人所開發(fā)的某機(jī)載顯示系統(tǒng)中,需要256色支持,所以采用了SVGA顯示模式,運(yùn)用重畫技術(shù)與雙緩沖技術(shù)相結(jié)合來實(shí)現(xiàn)儀表中指針及其它圖像的動(dòng)態(tài)顯示。重畫技術(shù)是編程人員最容易想到的一種動(dòng)畫方法,它來自于人們對(duì)動(dòng)畫顯示最基本的理解——將前一次顯示的圖形擦去再在當(dāng)前位置畫上要顯示的圖形。但這種方法存在著一個(gè)致命的缺點(diǎn),那就是圖形閃爍問題。閃爍現(xiàn)象主要是由于將擦寫的操作過程放在觀眾面前造成的,于是我們可以考慮將操作放到幕后,待操作完成后再將它快速映射到屏幕上去。事實(shí)上這將大大提高動(dòng)畫顯示的速度和穩(wěn)定性。在C語言標(biāo)準(zhǔn)圖形函數(shù)中也提供了setvisualpage()和 setactivepage()兩個(gè)函數(shù)來實(shí)現(xiàn)這一思想,但這兩個(gè)函數(shù)的操作是對(duì)整個(gè)屏幕進(jìn)行映射,效率較低,而且在SVGA顯示模式下無法應(yīng)用,所以必須從SVGA模式的設(shè)置、顯示原理的底層出發(fā)來實(shí)現(xiàn)最終的動(dòng)畫顯示。
三、 SVGA顯示模式設(shè)置
SVGA顯示模式建立在VESA標(biāo)準(zhǔn)之上,可以提供多種高分辨率的256色圖形模式(表1)。VESA-BIOS功能也是通過中斷10h來實(shí)現(xiàn)的,所有功能的調(diào)用格式為:AH=4Fh,AL=VESA功能代碼,功能代碼為00h,返回VESA基本信息;功能代碼為01h,返回VESA特定模式信息;功能代碼為02h,設(shè)置顯示;功能代碼為03h,返回當(dāng)前顯示模式;功能代碼為05h,控制VRAM存儲(chǔ)段。
表1 SVGA模式下分辨率表
下面給出SVGA設(shè)置的基本操作函數(shù):
1) 設(shè)置顯示模式
void InitMode(int mode) //mode為顯示方式號(hào)(表1中的中斷號(hào))
?。?
if(mode >= 0x100)
?。?
asm mov ax, 4f02h //設(shè)置顯示方式功能號(hào)AL=02h
asm mov bx, mode //bx=顯示方式號(hào)
asm int 10h
?。?
else
?。?
asm mov ah,0;
asm mov al,mode;
asm int 10h;
}
?。?
2) 設(shè)置VRAM段
void SelectPage(int page)//page為VRAM存儲(chǔ)段號(hào)
?。?
asm pusha
asm mov ax, 4f05h //VRAM存儲(chǔ)段控制功能號(hào)AL=05h
asm mov bx, 0 //bx=0000h為設(shè)置VRAM段號(hào),bx=0100h為檢測(cè)VRAM段號(hào)
asm mov dx, page //dx=要設(shè)置的VRAM存儲(chǔ)段段號(hào)(0~15)
asm int 10h
asm popa
?。?
四、 直接寫屏技術(shù)的實(shí)現(xiàn)
直接寫屏技術(shù)就是計(jì)算出屏幕上的點(diǎn)所對(duì)應(yīng)的顯示內(nèi)存位置,然后根據(jù)常規(guī)的坐標(biāo)計(jì)算將圖形通過點(diǎn)的形式保存到對(duì)應(yīng)位置的顯示內(nèi)存中去。用直接寫屏技術(shù),畫一滿屏的點(diǎn),只要用0.05秒左右,這就是說,直接寫屏比用C語言的函數(shù)寫屏,起碼快出了二十左右。
本系統(tǒng)選擇的SVGA模式顯示分辨率為640×480,256色,屏幕上的一個(gè)象素點(diǎn)在顯存中占用一個(gè)字節(jié)。該模式采用了內(nèi)存分段處理技術(shù),即將整個(gè)顯存劃分為若干個(gè)段,使每段大小為64K,起始地址為A000:0000H,可以通過對(duì)段進(jìn)行讀寫操作來實(shí)現(xiàn)對(duì)整個(gè)顯存的訪問。如果用(x,y)表示屏幕上的一個(gè)象素點(diǎn),那么該象素點(diǎn)在顯存中的地址計(jì)算公式為:
VRAM段號(hào)=(y×640+x)/65536(/為整除);
段內(nèi)偏移地址=(y×640+x)%65536(%為取余)
下面給出向顯存寫點(diǎn)的具體實(shí)現(xiàn)函數(shù):
void PutPixel(int x, int y, unsigned char color)
?。?
long Location;
int Page = 0, off = 0;
Location = ((long)y<<9) + ((long)y<<7) + x; //Location=y*640+x
Page = Location >> 16; //Page=Location/65536
off = Location & 0xffff; //off=Location%65536
SelectPage(Page); //選擇VRAM段
?。╲ideo_buffer + off) = color; // video_buffer為顯存首地址
?。?
五、 利用顯存自身實(shí)現(xiàn)雙緩沖動(dòng)畫顯示
通常緩沖技術(shù)的具體過程可以理解為:有兩個(gè)屏幕,一個(gè)是當(dāng)前屏幕,一個(gè)是繪制屏幕。當(dāng)前屏幕實(shí)際上就是我們可以直接看到的屏幕(顯存),而繪制屏幕就是我們開設(shè)的與顯存大小相同的內(nèi)存區(qū)域。我們將一張畫面繪制到繪制屏幕(申請(qǐng)的內(nèi)存)中去,等當(dāng)前屏幕顯示了足夠的時(shí)間后再將其替換上去。所以,當(dāng)前屏幕上從未進(jìn)行過任何繪制操作,所有操作都在繪制屏幕上完成。這樣在當(dāng)前屏幕上就只看到了完工的畫面,可以很好的消除由擦寫帶來的閃爍現(xiàn)象。
在系統(tǒng)的開發(fā)過程中,我們發(fā)現(xiàn)很難申請(qǐng)到與屏幕大小相同的內(nèi)存空間,根據(jù)系統(tǒng)自身的特點(diǎn),利用顯存自身來實(shí)現(xiàn)上述的雙緩沖思想。
本機(jī)載顯示系統(tǒng)采用的顯示器尺寸為320×240,而選用的SVGA模式分辨率為640×480,實(shí)際在該系統(tǒng)顯示屏幕上只顯示出了實(shí)際尺寸左上部320×240的區(qū)域,而其它的區(qū)域是顯示不出來的。這樣就給我們提供了一個(gè)現(xiàn)有的空間作為擦寫專用的繪制屏幕,而不必去另外申請(qǐng)內(nèi)間。實(shí)際,采用右上部分320×240的區(qū)域作為繪制屏幕(觀眾是看不到的),在直接寫屏?xí)r只需將橫坐標(biāo)增加320個(gè)象素單位,就可以將圖形繪制在幕后,待完成了擦除、重畫的操作后再將繪制屏幕上的圖像平移到顯示屏幕上,這樣就利用現(xiàn)有的顯存實(shí)現(xiàn)了雙緩沖的動(dòng)畫顯示。
[align=center]
圖1 利用顯存自身實(shí)現(xiàn)雙緩沖動(dòng)畫顯示示意圖[/align]
在將繪制屏幕的圖像copy到當(dāng)前屏幕時(shí),應(yīng)十分注意同一行存在兩個(gè)段值時(shí)的移動(dòng)方法。0-101行都在0號(hào)段內(nèi),103-203行都在1號(hào)段內(nèi),205-239行都在2號(hào)段內(nèi),這些行都可以直接調(diào)用匯編函數(shù)實(shí)現(xiàn)段內(nèi)轉(zhuǎn)移。102、204兩行內(nèi)都存在兩個(gè)段號(hào),需借助臨時(shí)緩存實(shí)現(xiàn)平移。下面給出字傳送的實(shí)際函數(shù):
void MoveWord(unsigned char far * dest, unsigned char far * sour, unsigned int size)
?。?
asm push ds
asm mov cx,size
asm les di,dest
asm lds si,sour
asm cld
asm rep movsw //傳送字
asm pop ds
?。?
綜上,可以得到該顯示系統(tǒng)動(dòng)畫顯示的流程圖如下:
[align=center]
圖2 動(dòng)畫顯示流程圖[/align]
六、 結(jié)論
本人所開發(fā)的某機(jī)載顯示系統(tǒng)中,采用上述動(dòng)畫顯示方法,很好的解決了儀表中指針閃爍的問題,大大提高了效率,并且在實(shí)際系統(tǒng)中對(duì)指針進(jìn)行了消抖與平滑的處理,使儀表的顯示效果得到很大的改善。