网页功能: 加入收藏 设为首页 网站搜索  
关于滚屏
发表日期:2007-01-17作者:[转贴] 出处:  


最容易想到的方法是通过BLT来移动像素,但是很明显,这种方法太慢了。

DOS时代常用的一个方法是所谓的“硬件滚屏”——通过对显卡芯片扫描屏幕缓冲区的起始地址寄存器进行递增或递减操作来实现高速平滑的屏幕滚动。到了WINDOWS时代,这个方法在硬件上行不通了,因为DirectDraw没有提供存取扫描起始地址寄存器的功能。

但是,大多数游戏图形引擎都使用了一个离屏缓冲区。虽然无法在主表面上实现“硬件滚屏”,却可以在离屏缓冲区中使用类似“硬件滚屏”的技术来提高性能。

方法是:设置一个指针,用来指向离屏缓冲区的“扫描首地址”,这个“扫描首地址”的意思是,当你把离屏缓冲区的内容COPY到主表面上的时候,把这个地址当作起始源地址,即这个地址单元的内容对应COPY到主表面的零单元,后面的地址单元依次类推。当源地址超出离屏缓冲区末尾时回绕至零单元。这样设置之后,要左右滚动一个像素时,只要将“扫描首地址”加一或减一即可;要上下滚动一个像素时,只要将“扫描首地址”加或减一个扫描行宽即可。

不过在有一点上你必须作出取舍:“硬件滚屏”同DirectDraw的Blt函数是相冲突的,一旦使用了“硬件滚屏”,你就不得不用自己的代码实现Blt的功能,因为DirectDraw的Blt函数没有“扫描首地址”这一概念,也不支持“地址回绕”。

自己写代码来实现Blt功能,并且要支持“扫描首地址”和“地址回绕”,这并不是件难办的事情。但是这里有一个小小的程序优化技巧:如何实现“地址回绕”。

DOS时代,在实模式下,“地址回绕”是硬件支持的(当然只能在64K范围内)。WINDOWS保护模式下,只有通过软件才可解决。在Blt函数中,每完成一个像素,检查一下地址指针,看看是否超出了缓冲区的末尾,一旦超出,就把指针恢复到首地址。——这样做是可行的,但是太慢了。

优化的方法是降低地址指针的检查频率,比如,每Blt完一行像素再检查一次,一旦超出,将指针减去整个缓冲区的长度。不过这样的话,指针就有可能超出缓冲区的末尾,但最大不会超出一个扫描行。因此,缓冲区的大小至少应比主表面大一个扫描行。

问题仍未解决,见下面的示意图:



图中,红色像素为有效像素(即最终将被COPY至主表面的像素)。当扫描起始地址向后推移两个单元以后,第一行中两个像素由原来的有效像素变成了无效像素,而最后一行(扩充的扫描行)中,则是两个原先无效的像素变成了有效像素。这时需要做的是把第一行中两个变为无效的像素移至最后一行中,作为新的有效像素。

根据这个例子分析,得出一个一般性规律:在改变扫描起始地址之前,必须在离屏缓冲区的第一行与最后一行之间进行某种形式的“同步”工作,具体过程是以图中的绿色分界线为准(其位置跟扫描起始地址有关),将第一行的右半部分COPY到最后一行的右半部分,将最后一行的左半部分COPY到第一行的左半部分。

至此,我们的模似“硬件滚屏”才算真正完成

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 关于滚屏
本类热点文章
  脚本系统的实现
  C++基本功和 Design Pattern系列(2) Ty..
  C++基本功和 Design Pattern系列(1) - ..
  斜45度游戏开发(提高篇)
  睱酵笴栏祘Α砞璸?? - [秈顶絞]
  斜45度游戏开发(二)
  第一次写技术文献。Collision AI
  斜视角游戏中遮挡的判断
  C语言基本功教程系列(5) - 文件, Socke..
  用rand()和srand()产生伪随机数的方法总..
  C++基本功和 Design Pattern系列(3) co..
  C语言基本功教程系列(1)
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.0043