持续更新 WPF 中 WindowsFormsHost 中的 OpenTK GLControl - 如何?

发布于 2024-11-18 09:14:03 字数 195 浏览 4 评论 0原文

我在 WPF 应用程序的 WindowsFormsHost 中嵌入了 OpenTK GLControl。 我想不断更新和渲染它。 在 Winforms 中,解决方案是将 UpdateAndRender 方法附加到 Application.Idle 事件,但在 WPF 中没有这样的事情。

那么(60FPS)更新我的场景和 GLControl 的最佳方法是什么?

I have an OpenTK GLControl embedden in a WindowsFormsHost in my WPF application.
I want to continuously update and render it.
In Winforms a solution would be to attach the UpdateAndRender method to the Application.Idle event, but there is no such thing in WPF.

So what would be the best way to do (60FPS) updating of my scene and GLControl ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北方的巷 2024-11-25 09:14:04

您可以使用 System.Timers.Timer 来控制渲染代码的调用频率。在包含 GLControl-in-WindowsFormsHost 的窗口中,声明一个 private System.Timers.Timer _timer;,然后当您准备好启动渲染循环时,设置计时器间隔及其事件处理程序,然后启动它,如下例所示:

    private void btnLoadModel_Click(object sender, RoutedEventArgs e)
    {
        LoadModel(); // do whatever you need to do to prepare your scene for rendering
        _timer = new System.Timers.Timer(10.0); // in milliseconds - you might have to play with this value to throttle your framerate depending on how involved your update and render code is
        _timer.Elapsed += TimerElapsed;
        _timer.Start();
    }

    private void TimerElapsed(object sender, ElapsedEventArgs e)
    {
        UpdateModel(); // this is where you'd do whatever you need to do to update your model per frame
        // Invalidate will cause the Paint event on your GLControl to fire
        _glControl.Invalidate(); // _glControl is obviously a private reference to the GLControl
    }

显然,您需要将 using System.Timers 添加到您的 using 中。

You can use a System.Timers.Timer to control how often your render code is called. In your window containing the GLControl-in-WindowsFormsHost, declare a private System.Timers.Timer _timer;, then when you're ready to start the rendering loop, set the timer interval and it's event handler, then start it up, as in the following example:

    private void btnLoadModel_Click(object sender, RoutedEventArgs e)
    {
        LoadModel(); // do whatever you need to do to prepare your scene for rendering
        _timer = new System.Timers.Timer(10.0); // in milliseconds - you might have to play with this value to throttle your framerate depending on how involved your update and render code is
        _timer.Elapsed += TimerElapsed;
        _timer.Start();
    }

    private void TimerElapsed(object sender, ElapsedEventArgs e)
    {
        UpdateModel(); // this is where you'd do whatever you need to do to update your model per frame
        // Invalidate will cause the Paint event on your GLControl to fire
        _glControl.Invalidate(); // _glControl is obviously a private reference to the GLControl
    }

You'll clearly need to add using System.Timers to your usings.

ㄟ。诗瑗 2024-11-25 09:14:04

您可以使用 Invalidate() 来实现它。这会导致 GLControl 重绘其内容。

如果您在 Paint() 末尾调用它,您可能会阻止其他 WPF 控件的某些 UI 呈现。

WPF 提供每帧渲染事件:CompositionTarget.Rendering。在 WPF 想要呈现内容之前调用此事件。订阅它并调用Invalidate:

public YourConstructor()
{
  //...
  CompositionTarget.Rendering += CompositionTarget_Rendering;
}

void CompositionTarget_Rendering(object sender, EventArgs e)
{
  _yourControl.Invalidate();
}

如果不再使用它,则需要取消订阅(以避免内存泄漏)。

这是如何:在 Per 上渲染使用来自 MSDN 的 CompositionTarget 的帧间隔。

我将 GLControl 与该方法一起使用,效果很好。我没有检查我的 FPS 有多少,但感觉很流畅。

您也可以看看这个:为什么WPF中的帧速率不规则且不限于监视器刷新?

You can use Invalidate() for it. This causes the GLControl to redraw it's content.

If you call it at the end of Paint() you may blocking some UI rendering of the other WPF controls.

WPF provides a per frame render event: CompositionTarget.Rendering. This event is called before WPF wants to render the content. Subscribe from it and call Invalidate:

public YourConstructor()
{
  //...
  CompositionTarget.Rendering += CompositionTarget_Rendering;
}

void CompositionTarget_Rendering(object sender, EventArgs e)
{
  _yourControl.Invalidate();
}

You need to unsubscribe if you don't use it anymore (to avoid memory leaks).

Here is a How to: Render on a Per Frame Interval Using CompositionTarget from MSDN.

I use GLControl with that method and it works fine. I did not checked how much FPS I have but it feels smooth.

You may also have a look on this: Why is Frame Rate in WPF Irregular and Not Limited To Monitor Refresh?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文