画面图形快速绘制技术设计_第1页
画面图形快速绘制技术设计_第2页
画面图形快速绘制技术设计_第3页
画面图形快速绘制技术设计_第4页
画面图形快速绘制技术设计_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、画面图形快速绘制技术设计在SCADA系统画面显示中,最重要的技术就是画面图形刷新技术,如果按照教科书上,如MFC深入浅出中的列子来写绘图程序,图元一多就会出现图形绘制时存在着图元绘制速度慢,使得画面整屏刷新时,在开发态会逐个显示图元,而运行态出现白屏现象。如何对该缺陷进行改进,具体工作内容需根据实际情况而定,下面提出一种基本的画面图形快速绘制技术,以供参考。       组态软件要实现图元的鼠标交互绘制,并且在运行中需对实时数据以比较高的频率进行屏幕动态刷新显示(一般每50ms刷新一次),因此,对画面窗口绘制实现要求比较高,在此设计画面窗口绘制

2、是以缓存与区域刷新两种技术的组合来实现。       缓存技术是指在画面窗口绘制过程中,不是直接将各图元的绘制效果显示在屏幕上,而是首先将窗口画面以位图形式保存到内存,然后将各图元绘制到该缓存中,最后将缓存中信息重新写回画面窗口,整体显示,使得CRT不为每一个画面的变化而进行一次整屏刷新,从而实现画面窗口的高速绘制。区域刷新技术是指在上述操作过程中只对当前刷新区域进行处理,如仅复制当前区域内屏幕信息到内存,只对与当前刷新区域相容或相交的图元进行绘制,从而进一步提高画面窗口的绘制速度。如何创建memDC的文章网上已经很多,此次不再具体描

3、述。       在程序中,各函数通过逐阶调用或消息通知运行即可实现不同方式的画面窗口绘制。如图元操作函数调用Invalidate函数或CDrawView:InvalObj(this)函数即可实现实时显示本次图元变换操作效果;在视图编辑函数中通过调用OnUpdate函数即可实现不同模式的画面窗口绘制;在工程运行过程中,动画对象也可实现对动画显示区域的动态刷新,而不需整屏刷新,避免了屏幕闪烁,提高系统运行速度。建立画面窗口绘制函数调用关系图如图1.1所示。      分析图1.1画面窗口

4、绘制函数调用关系图,可以看到最终的绘制过程都由画面视图的OnDraw()函数汇总实现,主要有两个大支流,分别对应InvalidateRect()函数和Invalidate()函数,实现单个图元的区域绘制和整屏重绘,这两种绘制方式将根据不同情况而被应用,以达到最快的画面绘制效率。 单个图元绘制    单个图元绘制指在图形开发/运行时,画面视图仅对变动的图元所占区域进行重绘,主要是采用区域绘制与缓存技术的结合方式实现。如图1.1所描述,单个图元的绘制主要发生在图元编辑操作和动画连接显示。1.图元编辑操作时,通过逻辑模块定位该图元,调用本图元类的Invalid

5、ate()函数,宣布本图元所在区域无效,调用画面逻辑模块:UpdateAllViews在图元所在逻辑模块的所有视图中重绘本图元,各视图获取该图元指针,并重绘图元所占区域;对于单个画面视图刷新,也可直接将本图元指针传给所在视图,调用该视图: InvalObj()函数,重绘图元所占区域。2. 运行时进行动画刷新时,直接关联数据改变,需要动画刷新的图元指针传给所在画面视图,调用该视图: InvalObj()函数,重绘图元所占区域。这个过程可采用两种方法,一种是在动画扫描时,每扫描到一个关联数据发生变化的动画对象,便在动画数据处理后,实现对应图元的重绘;另一种方法是全部扫描完该画面视图动画链表后对整屏

6、进行重绘。二者各有优缺点,当图元重合度小或瞬间动画图元少时,采用第一种方式具有明显速度优势;但当图元重合度大时,因单个图元的绘是采用区域绘制技术,将会造成实际绘制图元数明显大于画面视图的图元总数,此时采用第二种方式全屏绘制反而能保证刷新速度。局部刷新技术具体实现如下:每个图元更新时调用pDC->InvalidataRect(m_sz),这个时候在画面刷新时将获得该刷新区域的剪裁区,其中剪裁区分为region 和 clipRect,区别见下图: 其中蓝色的区域合集为region,用GetUpdateRgn获得,红色的区域为所有region围成的最小矩形区,用dc.GetClipB

7、ox(clipBoxRect)获得。在OnPaint函数中先获得该画面目前需要刷新的CRgn和Rect 代码 /获得所要刷新的区域 CRgn* pInvalidateRgn; CRgn rgnInvalidate; rgnInvalidate.CreateRectRgn( 0,0,0,0 ); int nRgnResult = this->GetUpdateRgn( &rgnInvalidate ); if ( nRgnResult != ERROR && nRgnResult != NULLREGION ) pInvalidateRgn = &

8、rgnInvalidate; else return; /获得需要刷新的最小剪裁矩形CRect clipBoxRect; dc.GetClipBox(clipBoxRect); if( clipBoxRect.IsRectEmpty() ) if ( rgnInvalidate.GetSafeHandle() ) rgnInvalidate.DeleteObject(); return;   将pInvalidateRgn和clipBoxRect以及memDC传入每个图元的绘制函数中,绘制前先判断该region和clipRect是否与该图元的边界有交集 Draw

9、/ <summary>/ 判断是否与矩形相交,包括包含/ </summary> BOOL CLayer:IsIntersectsWith( const CRect& rect1,const CRect& rect2 ) return ( (rect1.left < (rect2.left + rect2.Width() && (rect1.top < (rect2.top + rect2.Height() && (rect2.left < (rect1.left + rect1.Width() &

10、& (rect2.top < (rect1.top + rect1.Height() );/ <summary>/ 图层绘制函数/ </summary>void CLayer:Draw(CDC *pDC,CRect *pr,CRgn* pInvalidateRgn) int i; if(!m_enable) return ; int cnt = m_FigObjArray.GetSize(); BOOL bl=TRUE; for(i=0; i<cnt; i+) CObjBase *pFigObj = m_FigObjArray.GetAt(i); C

11、Rect pixelBounds(pFigObj->m_pt0,pFigObj->m_sz+CSize(1,1); /过滤不在剪裁区中的图元 if (!IsIntersectsWith(pixelBounds,*pr) continue; /过滤不在刷新区域中的图元 if (pInvalidateRgn) pDC->LPtoDP(&pixelBounds); if (!pInvalidateRgn->RectInRegion( pixelBounds ) continue; /只有在刷新区域内的图元才真正绘制 bl=pFigObj->DrawFig(pDC,bl);   最后将memDC的内容贴到屏幕的DC上,完成绘图 pDC->BitBlt(clipBoxRect.left,clipBoxRect.top,clipBoxRect.Width(),clipBoxRect.Height(),&mDC,0,0,SRCCOPY);  画面整屏刷新画面整屏刷新是指进行画面视图重绘

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论