登录社区:用户名: 密码: 忘记密码 网页功能:加入收藏 设为首页 网站搜索  

文档

下载

图书

论坛

安全

源码

硬件

游戏
首页 信息 空间 VB VC Delphi Java Flash 补丁 控件 安全 黑客 电子书 笔记本 手机 MP3 杀毒 QQ群 产品库 分类信息 编程网站
  立华软件园 - 安全技术中心 - 技术文档 - 入门基础 技术文章 | 相关下载 | 电子图书 | 攻防录像 | 安全网站 | 在线论坛 | QQ群组 | 搜索   
 安全技术技术文档
  · 安全配制
  · 工具介绍
  · 黑客教学
  · 防火墙
  · 漏洞分析
  · 破解专题
  · 黑客编程
  · 入侵检测
 安全技术工具下载
  · 扫描工具
  · 攻击程序
  · 后门木马
  · 拒绝服务
  · 口令破解
  · 代理程序
  · 防火墙
  · 加密解密
  · 入侵检测
  · 攻防演示
 安全技术论坛
  · 安全配制
  · 工具介绍
  · 防火墙
  · 黑客入侵
  · 漏洞检测
  · 破解方法
 其他安全技术资源
  · 攻防演示动画
  · 电子图书
  · QQ群组讨论区
  · 其他网站资源
最新招聘信息

关于滚屏
发表日期:2007-01-17作者:[转贴] 出处:  


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

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

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

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

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

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

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

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

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



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

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

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

我来说两句】 【发送给朋友】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 关于滚屏

 ■ [欢迎对本文发表评论]
用  户:  匿名发出:
您要为您所发的言论的后果负责,故请各位遵纪守法并注意语言文明。

最新招聘信息

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