我想每秒钟刷新10次,能有20次更好了,用GDI作图,发现可以实现,但是CPU占用率100%,以至于显示对话框都困难了。有没有好办法加快绘制速度?绘图的代码只是从数据库中取得数据来显示文字,应该耗时比较少,而且是缓存的。
我是这样:利用内存设备句柄成员变量,在OnTimer里调用绘图函数绘制到内存设备句柄,然后调用InValidate(FALSE),在OnPaint里将整个内存设备句柄BitBlt到客户区dc。当然,使用InvalidateRect()会减少一些耗时,可是不能根本解决问题,能不能不用DirectX的情况下,尽可能提高GDI的速度?
请指教。
我是这样:利用内存设备句柄成员变量,在OnTimer里调用绘图函数绘制到内存设备句柄,然后调用InValidate(FALSE),在OnPaint里将整个内存设备句柄BitBlt到客户区dc。当然,使用InvalidateRect()会减少一些耗时,可是不能根本解决问题,能不能不用DirectX的情况下,尽可能提高GDI的速度?
请指教。
我积累了两种方法,第一:图形显示用设备环境拷贝是比较快的,也就是说把该处理的图象在内存中处理,然后贴到显示设备上,贴的这一过程很快。同时,图象的刷新是比较关键的,图象在显示设备上绘的速度与图像擦除的速度大概是9:1。所以,要自己写擦除函数,只擦除该刷新的区域,这个区域可通过裁减区域算法进行判断。
第二,可以通过DirectX双缓冲技术解决。
经过跟踪,发现主要费时间的是DrawText()调用,一个DrawText()调用竟然耗时10ms以上,难道是我使用的问题?
pDC->DrawText(szDesc, lstrlen(szDesc), rcItem, DT_TOP | DT_LEFT | DT_WORDBREAK);
因为是矢量字体,
每个字体好像还要进行插值计算
所以说游戏开发的不会用矢量字体都是用位图字体。up先我也不懂。
可以用看图软件直接看的。(嘿嘿)
一般是DIB啦,
DX里面好像是叫什么来着的,一个SURFACE。
我先把字体画出来,生成DIB,
以后就可以直接贴图上去了,
就不用再BEZIER算法来算了。当然会快一点了。
2、如果对刷新次数要求不是太严格的话,可以试试在OnIdle里绘制,在OnIdle先一个判断
if ((NowTick - beginTick)>你设定的时间)
Draw()
beginTick = NowTick
else
return
1。SetTimer设置的定时器最快只能是每秒18.2次。周期55毫秒。所以20次是不行的。
况且,Windows系统中,WM_TIMER 和 WM_PAINT消息都是优先级较低的消息,就是说,
当消息队列中还有其他消息时,系统会优先处理其他消息。这也使定时的精度得不到保证。2。Windows的消息系统本身也很费时,你在OnTimer()中用InvalidateRect(),实际上产生一个WM_PAINT消息,
然后再在OnPaint()中处理,这是绕了一个弯,如果不考虑消息体系的结构的话,直接在OnTimer中刷新就行了。解决上面两个问题的更好的办法是用多媒体定时器timeSetEvent()设置一个回调函数,
在这个回调函数中做刷新的工作。这样速度和精确度都能有很大提高。3。DrawText()这个函数确实比较费时。我想你每次显示的应该都是同一个字,
只是需要不断移动他在屏幕上的位置吧。要是这样,只需要把字写入内存DC一次,
然后每次用BitBlt()就行了,这个函数相比之下还是比较快的。4。为什么DrawText()有时是0,有时是19?有两个方面:
1。函数执行过程中的不确定因素:如硬件中断,线程调度,内存缺页错误等。
2。计时函数本身不准确。我想你大概时用GetTickCount()来计时的吧。
msdn中说这个函数在95,98下精度是55ms,NT下是10ms;不过我在98下试,精度是5ms。
其它的函数也类似,并不能反映准确的执行时间的。
QueryPerformanceCounter高一点,在有硬件支持情况下,可以达到0.8ms.
不过好象不应该加在ONTIMER里
试一下ONIDLE,或WIN API的PEEKMESSAGE后
由于windows是多任务操作系统,55MS是系统的轮训时间,没有办法更快(不同的操作系统的多任务的轮训周期不同),所以使用SetTimer触发高速显示不是好主意。使用GDI,你也可以模仿DX的切换页方式,自己建立一个MEMDC,把图片绘制其中,然后BITBLT到显示DC上。这个速度是比较快的,BITBLT不比DIRECTDRAW的速度慢。后台程序不用时间触发,自己做循环控制,至于显示对话框都困难,是因为你的循环当中没有加入消息处理机制,在网络上搜索一下,有许多关于长期处理计算,程序不响应的解决方式。
使用OnTime显示快速不快,不如在OnIdle中计算间隔时间,并绘制.