中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
图形模式的显示速度分析
作者:未知 时间:2005-09-13 23:33 出处:Blog.ChinaUnix.net 责编:chinaitpower
              摘要:图形模式的显示速度分析

图形模式的显示速度分析

  原理跟文本模式一样,如果我们用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,position%65536,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;
  }
  position%=65536;
  pokeb(0xa000,position,100);
  }
 getch();
 close256();
}
  速度是不是又快了些?然而我还不满足,我要“榨干”电脑的潜力。前面都是以点为单位读取数据的,我把它们改用块复制,同时使用寄存器变量,将速度作了最后一步提升。在使用块复制时,因为显示行可能跨页,因此必需估计复制块的长度,在0xa000ffff的位置必需要做截断处理。截断数据时,要记录下跨显示页的扫描线的换页点,也就是内存中显存映射的65535位置点在屏幕上的位置。程序如下:

main()
{ register int j,n[4]=;/*第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)
  /*处理跳行跨页*/
  if(page_new!=page_end) /*处理显示行跨页*/
  {memcpy(p+position%65536,buffer,n[page_new]-100);
  selectpage(page_new+1);
  memcpy(p,buffer,300-n[page_new]);
  selectpage(page_new);
  }
  else memcpy(p+position%65536,buffer,200);
 }
 lastpage=page_new;
 getch();
 close256();
}

  经过上面一段“演练”后,对显存写屏你是不是更加了解了些呢?归纳起来,可以得到这样一个结论:在速度上 BIOS写点 < 显存单个写点 < 块复制写点,同时注意少用换页函数。

关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有