圖形模式的顯示速度分析 |
|
conundrum
尊榮會員 發表:893 回覆:1272 積分:643 註冊:2004-01-06 發送簡訊給我 |
http://www.truantsky.com/speed.htm 圖形模式的顯示速度分析 原理跟文本模式一樣,如果我們用for迴圈語句將螢幕用putchar語句填滿"A"和使用puts語句填滿"A"速度是不一樣的。如果你沒有進行過文本模式速度分析也無所謂,接下來往下看。 使用基本的寫點函數 VESA BIOS 提供了一個通用的圖形模式的基本寫點函數 videodot,函數形式如下: videodot(int x, int y, int color) { union REGS r; r.h.ah = 12; r.h.al = color; r.x.cx = x; r.x.dx = y; int86(0x10,&r,&r); } 然後,使用該函數我們在螢幕上先畫一個200*200的正方形,程式如下: main() { int i,j; init256();/*初始化螢幕爲640*480 256色模式,詳見-256色模式寫屏*/ for(j=100;j<300;j ) for(i=100;i<300;i ) videodot(i,j,100); getch();/*暫停以觀察螢幕*/ close256();/*恢復螢幕爲文本模式,參考文章-256色模式寫屏*/ } 也可以借用256色圖形系統的初始化函數(已去掉DAC色表設置)<點擊此處>。 怎麽樣,速度很慢吧,可以說慢得出奇。如果帝國時代或是星際爭霸也使用這種顯示方法的話,早就沒人玩了。所以,還得另尋其他方法。 使用直接寫顯存的方法 大多數軟體和遊戲均使用這種方法,這種方法的優勢是速度快,缺點是實現比較麻煩。使用這種方法,由於無法直接定址所有顯存,因此要使用換頁機制。而在何處換頁,換頁是如何對寫入資料截斷處理,是使用該方法的難點和重點。 在這裏我採取直接計算點位置的方法。原理是顯示點前按照要顯示的位置先計算出所在頁,然後再換頁顯示。程式如下: main() { int i,j; long position; init256(); for(j=100;j<300;j ) for(i=100;i<300;i ) {position=640l*j i; selectpage(position/65536);/*映射到相應的顯示頁*/ pokeb(0xa000,positione536,100);/*在相應點處顯示*/ } getch(); close256(); } 速度是不是快了一些?其實速度的潛力還可以繼續挖掘,請接著往下看。 寫顯存的加速方法 其實在上一個寫屏方法中,有一個瓶頸制約了顯示速度。因爲每寫一個點都要依次調用換頁中斷,而中斷的速度又比較慢,所以拖了顯示的後腿。 因而在寫點時不必每寫一點就換頁,可以在寫點位置不在原來頁上時,再開始換頁,這樣又可以節約一大部分時間。因此在每頁最後一個圖元點要進行跳頁。我採取的方法是用一變數記錄下前一頁的頁號,當計算後的頁號不等於前一頁號時再進行換頁。程式如下: main() { unsigned char nowpage,lastpage=8; int i,j; long position; init256(); for(j=100;j<300;j ) for(i=100;i<300;i ) {position=640l*j i; nowpage=position/65536; if(nowpage!=lastpage) {selectpage(nowpage); lastpage=nowpage; } temp%=65536; pokeb(0xa000,temp,color); } getch(); close256(); } 速度是不是又快了些?然而我還不滿足,我要“榨幹”電腦的潛力。前面都是以點爲單位讀取資料的,我把它們改用塊複製,同時使用寄存器變數,將速度作了最後一步提升。在使用塊複製時,因爲顯示行可能跨頁,因此必需估計複製塊的長度,在0xa000ffff的位置必需要做截斷處理。截斷資料時,要記錄下跨顯示頁的掃描線的換頁點,也就是記憶體中顯存映射的65535位置點在螢幕上的位置。程式如下: main() { register int j,n[4]={256,512,128,384};/*第0、1、2、3頁換頁列位置*/ register char page_new,page_old,page_end, *p=MK_FP(0xa000,0000),buffer[640]; register long position; page_old=8; init256(); selectpage(page_old); memset(buffer,100,640);/*將要複製塊置爲要拷貝的顔色*/ for(j=100;j<300;j ) {position=640l*j 100; page_new=position/65536; page_end=(position 200)/65536; if(page_new!=page_old) {selectpage(page_new);page_old=page_new;} /*處理跳行跨頁*/ if(page_new!=page_end) /*處理顯示行跨頁*/ {memcpy(p positione536,buffer,n[page_new]-100); selectpage(page_new 1); memcpy(p,buffer,300-n[page_new]); selectpage(page_new); } else memcpy(p positione536,buffer,200); } lastpage=page_new; getch(); close256(); } 經過上面一段“演練”後,對顯存寫屏你是不是更加瞭解了些呢?歸納起來,可以得到這樣一個結論:在速度上 BIOS寫點 < 顯存單個寫點 < 塊複製寫點,同時注意少用換頁函數。 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |