基于GDI开发windows动态绘图优化解决方案.docVIP

基于GDI开发windows动态绘图优化解决方案.doc

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
基于GDI开发windows动态绘图优化解决方案

基于GDI开发windows动态绘图优化解决方案   摘要: GDI作为开发WINDOWS平台的常用接口,在开发动态绘图方面具有一定的劣势,就是针对动态绘图开发中易出现的一系列问题,使用幕布、局部剪裁等方式实现提高GDI接口的绘图效率的目的。   关键词: GDI;动态绘图;幕布;局部剪裁   中图分类号:TP319文献标识码:A文章编号:1671-7597(2011)0720174-01      谈到动态绘图,人们首先想到的自然是PC游戏。程序员在选择开发接口时,普遍比较喜欢选择DIRECTDRAW或者OPENGL。无论是2D还是3D游戏,作为游戏开发这两套开发库在硬件支持方面和图形处理效率方面优势明显,但是缺点是开发繁琐度有所增加,而且做好的成品必须要求系统事先安装有相应的接口驱动才能使用。因此在开发一般性应用程序如办公软件或科学测绘软件时候,程序员一般还是会优先考虑使用微软通用图形接口GDI(Graphics Device Interface)开发一些简单性的图形应用。当然GDI的缺点非常明显,就是对动态绘屏的处理效率比较低,若实现动画效果时候,代码稍微处理不当就会发生闪屏、顿屏、CPU占有率高的情况。因此我们就此情况考虑优化设计理念,让GDI动态绘图时实现接近DIRECT和OPENGL的连贯效果。   首先我们先分析一下造成GDI开发闪屏和CPU使用率偏高的原因。在开发GDI应用程序的时,一般都会在onpaint 消息函数中处理绘图过程。基本步骤是首先初始化窗口dc,然后使用相应绘图函数将图形一个一个的叠加在这个dc上。每次强制重绘则调用Invalidate函数强制重绘。这时系统会清空窗口dc,然后再调用onpaint函数,将图形一个一个叠加到这个“画板”上的;另外一种常见方法是,处理重绘过程的时候,首先用背景色“涂”掉整个dc后再依次叠加图形到上面。无论如何,这时闪烁都会发生了。因为两者的一个共同点是重绘前都有瞬间dc中的图形是被“涂掉”的。再快的计算机也会感觉到瞬间的不连贯。   为了解决类似问题,首先要避免使用Invalidate的习惯,因为Invalidate   会重绘窗口所有元件后并发出onpaint消息,而对于我们只绘制部分窗口dc的需求是多余的。所以应该尽可能的在函数体内创建屏幕clientdc,进行直接绘制,而不是使用onpaint函数体处理。另外为了避免背景重绘造成的闪烁,我们借鉴程序员在开发游戏程序时普遍习惯使用“幕布”的办法。原理很简单,提前创建一个全局CDC变量dc1。绘图时,将所有图形体首先绘制到dc1上,最后再执行bitblt将dc1一次性复制到屏幕dc上,如图1。虽然整个过程多了一个bitblt操作,但是效果很明显,闪烁消失了,而且也有“动画”的感觉了。      使用了幕布的方法,在一定程度上可以有效防止闪烁并且连贯的输出动态效果。不过,在某些特殊情况下,比如背景相当大,动画就会明显迟钝。FPS(每秒钟显示的帧数)和背景大小形成反比。这时我们就必须采取进一步优化方案来尽可能的提高FPS。我们可以初步分析出造成动画迟钝的原因是CPU占有率上升。而整个操作过程中占CPU耗时最多的操作过程正是绘制背景的过程。因为它是一点不落的对幕布dc进行一对一复制。但是如果不执行这个操作也不可行,不清空原始画面,下一帧必会出现重影。所以我们考虑进行局部剪裁的办法,复制的部分则是窗口dc可视的矩形范围。      1)将窗口可视dc矩形区域对于幕布dc的相对位置信息保存入全局变量rect中。   2)将背景图所属rect区域内的矩形复制到幕布dc中。   3)依次计算各需要图形元素体所占据的最大矩形区域,并提取矩形顶点,根据重叠算法{(x,y)|x∈{Xmin,Xmax},y∈{Ymin,Ymax}}依次判断哪些图形体会出现在rect区域内,并绘制有重叠的图形体元素到幕布dc。   4)将幕布dc的rect区域复制到窗口dc中。   经过优化处理后,我们既在背景覆盖这一步骤节约了大量的CPU处理时间,又免去了不必要的图形元素的绘制过程,FPS可以得到一个质的飞跃。   局部剪裁的剪裁区域是一个变量,是随着窗口的位置、大小而变化的,而剪裁区域相对于实际图形区域也是随时变化的(随操作人员鼠标拖动而改变显示区域)。在用户仅执行预览操作的时候,仍然执行剪裁法的全部操作过程,则明显过于繁琐,不利于快速绘图。因为图形数据信息是不变的,相当于每执行一下局部预览时都要执行剪裁法的全部过程。因此我们可以在剪裁算法的基础上继续做一步优化设计以应对动态处理后的拖屏操作。即再增设一个与背景等同大小的幕布dc,每次在完成一组动态绘图的最后一帧后,对这块幕布进行与窗口dc一样的全尺度非剪裁性绘制。

文档评论(0)

bokegood + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档