【问题标题】:Smooth animations with GDI+ in C++在 C++ 中使用 GDI+ 平滑动画
【发布时间】:2018-05-19 18:36:23
【问题描述】:

我无法在 C++ 中使用 GDI+ 获得简单流畅的动画。我目前的方法是使用here 描述的 WinAPI 计时器。我用SetTimer 以15ms 的间隔初始化计时器。然后,当相应的WM_TIMER 事件发生时,我将增加矩形的左上角坐标,为整个屏幕调用InvalidateRect 并绘制矩形。结果是按预期移动,但有规律的闪烁(参见video)。这似乎随​​时间间隔而变化,但它始终存在。

问题是如何修改这种方法以实现流畅的动画?我发现的大多数类似问题都与 C# 有关,其中工具集似乎有点不同。

编辑:忘了补充 - 这是一个学校项目,所以改变技术或语言对我来说并不是一个真正的选择。

【问题讨论】:

  • 做一些关于双缓冲的研究。
  • 仅使您需要擦除和绘制的窗口部分无效。
  • 您可以使用GetDC(),然后在其上绘图,而不是使整个窗口无效。您必须自己擦除背景。这将比使用InvalidateRect() 快得多。
  • 只要您确保执行以下操作,动画就会很流畅。 1 渲染新帧时,每个像素最多改变一次颜色。双缓冲是确保这一点的简单方法。 2 不要假设 Windows 计时器以恒定速率滴答作响。相反,使用计时器来触发重绘,但要根据开始时间和当前时间计算动画步骤。使用超时为 0 的计时器以尽可能快地呈现。

标签: c++ animation winapi visual-c++ gdi+


【解决方案1】:

InvalidateRect 中为bErase 使用FALSE 标志。

InvalidateRect( hwnd, NULL, FALSE );

或者处理WM_ERASEBKGND消息

LRESULT CALLBACK YourWindowProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
    switch ( msg )
    {
    case WM_ERASEBKGND:
        // Don't paint background if you are blitting from off screen surface.
        return 1;
    }
    return DefWindowProc( hwnd, msg, wparam, lparam );
}

或者把NULL刷到窗口类(用于RegisterClass)定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    • 2012-09-17
    • 2011-03-27
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多