全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1244
推到 Plurk!
推到 Facebook!

圖形模式的顯示速度分析

 
conundrum
尊榮會員


發表:893
回覆:1272
積分:643
註冊:2004-01-06

發送簡訊給我
#1 引用回覆 回覆 發表時間:2004-09-23 22:45:47 IP:61.64.xxx.xxx 未訂閱
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寫點 < 顯存單個寫點 < 塊複製寫點,同時注意少用換頁函數。     
系統時間:2024-04-29 12:31:29
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!