细节
动画采取相同的图像,并将其向右移动到屏幕上;像素数量由当前时间与动画开始时间之间的差异以及时间结束决定,以使用timeGetTime
与1ms resolution一起应用于整个窗口宽度的分数完成.动画吸引没有处理应用程序消息的循环;它调用了内部无效的(VCL库)方法Repaint
,然后调用相关窗口的UpdateWindow
,直接使用WM_PAINT调用消息过程.绘画处理程序的VCL实现使用BeginBufferedPaint.绘画本身是双重缓冲的.
这样做的目的是尽可能高的帧率,以便在屏幕上获得平滑的动画. (绘图使用双缓冲来消除闪烁,并确保任何一个屏幕上的整个图像或帧,通过调用消息过程直接进行消息和更新,而不进行其他消息处理.使用现代技术例如,用于Aero构图的BeginBufferedPaint))在其中,绘画是在几个BitBlt调用中完成的(一个用于动画的左侧,即移动在屏幕之外,还有一个用于动画的右侧,即屏幕上移动的内容. )
观看动画时,清晰可见tearing.这种情况发生在具有不同显卡的多个系统上的Windows Vista,7和8.1上.
处理这个问题的方法是降低绘制速度,或者在再次绘制之前尝试等待VSync.这可能是错误的做法,所以这个问题的答案可能是“完成其他事情:X”.如果是的话,很棒:)
(我真正想要的是要求DWM在这个特定的窗口中编写/使用全画幅的方法.)
我尝试了以下方法,没有一个删除所有可见的撕裂.所以问题是,在使用DWM组合时是否有可能避免撕裂,如果是这样呢?
方法尝试:
>通过GetDeviceCaps(Application.MainForm.Handle,VREFRESH)获取显示器刷新率;睡眠1 /刷新率毫秒.稍稍改善画面尽可能快,但可能是一厢情愿.感觉上略微平滑的动画率. (调整:正常睡眠和使用timeGetTime的高分辨率旋转等待)
>使用DwmSetPresentParameters
尝试将更新限制为与代码绘制相同的速率. (变化:大量的缓冲区(cBuffer = 8)(无可见效果);指定监视器刷新率/ 1的源速率和使用上述代码进行睡眠(与刚尝试睡眠方式相同);指定每帧刷新1,10等(无可见效果);改变源帧覆盖(无可见效果)
>以各种方式使用DwmGetCompositionTimingInfo
:
>
>虽然cFramesPending> 0,旋转
>
>获取cFrame(框架组合)并旋转,而此数字不变;
>
>通过添加qpcVBlank qpcRefreshPeriod计算睡眠时间,然后QueryPerformanceCounter返回的时间少于此值,旋转
>所有这些方法也通过绘画而变化,然后再次喷涂/睡觉;或反过来:睡觉然后画画.
几乎似乎有任何明显的效果,并且有什么影响是很难限定,可能只是由于帧率较低.没有防止撕裂,即没有使DWM使用窗口的DC的内容的“整体”副本组成窗口.
忠告赞:)