Opengl 打开RenderFrame和OnUpdate Frame上的TK差异?

Opengl 打开RenderFrame和OnUpdate Frame上的TK差异?,opengl,methods,overriding,opentk,subscribe,Opengl,Methods,Overriding,Opentk,Subscribe,我目前正在使用OpenTK框架和OpenGL在C#中编写一个Jump n'Run游戏 OpenTK提供了预设功能,如GameWindow.Run()或游戏窗口.onUpdate框架()onRenderFrame() 就我所想,所有绘制OpenGL元素或原语的动作都应该属于onRenderFrame,而像玩家移动这样的游戏事件应该在OnUpdate frame中执行,所以这些动作可以在渲染新帧之前提前计算 我说得对吗?在onRenderFrame方法中执行所有操作是否会有所不同?OpenTK建议不

我目前正在使用OpenTK框架和OpenGL在C#中编写一个Jump n'Run游戏

OpenTK提供了预设功能,如
GameWindow.Run()
游戏窗口.onUpdate框架()
onRenderFrame()

就我所想,所有绘制OpenGL元素或原语的动作都应该属于onRenderFrame,而像玩家移动这样的游戏事件应该在OnUpdate frame中执行,所以这些动作可以在渲染新帧之前提前计算

我说得对吗?在onRenderFrame方法中执行所有操作是否会有所不同?OpenTK建议不要重写这些方法,而是订阅它们的事件(onRenderFrameEvent)

什么是订阅,我如何订阅事件而不是覆盖方法

protected override void OnUpdateFrame(FrameEventArgs e)
{
    base.OnUpdateFrame(e);

    this.gameObjects.moveObjects();

    this.player.Move();
    if (this.player.jumpstate == true) this.player.Jump();
}

protected override void OnRenderFrame(FrameEventArgs e)
{
    base.OnRenderFrame(e);

    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    Matrix4 modelview = Matrix4.LookAt(Vector3.Zero, Vector3.UnitZ, Vector3.UnitY);
    GL.MatrixMode(MatrixMode.Modelview);
    GL.LoadMatrix(ref modelview);

    GL.LoadIdentity();
    GL.Translate(0.0f, 0.0f, -3.5f);

    this.gameObjects.drawObjects();
    this.player.Draw();

    SwapBuffers();
}

正如评论所说:在
UpdateFrame
事件中更新您的世界,并在
RenderFrame
中渲染它

当你意识到你的游戏将在完全不同的硬件上运行时,这是有意义的。某些计算机可能只能以15fps的速度渲染游戏。其他人将实现稳定的60帧/秒。拥有120Hz显示器的玩家希望你的游戏以120fps的速度运行,以充分发挥他们系统的潜力

在所有这些情况下,您希望您的游戏逻辑以相同的速度运行,并给出相同的结果

实现这一点的最简单方法是在
GameWindow.Run()
中设置固定的
updatename
速率:

此代码段指示OpenTK每秒引发60个
UpdateFrame
事件,以及系统可以处理的最多
RenderFrame
事件,直到监视器的刷新率。当在较慢的系统上运行时,OpenTK将删除
RenderFrame
事件,以确保每秒发生60个
UpdateFrame
事件。这通常称为“固定时间步”

看看为什么这是可取的

请参阅为什么不应在
渲染帧
事件中执行世界更新(简短版本:在《雷神之锤3》中,高fps的数值不准确允许玩家跳得更高并获得竞争优势。)

编辑:有关问题的第二部分,请参阅。例如:

using (var game = new GameWindow())
{
    game.RenderFrame += (sender, e) =>
    {
        GL.Clear(ClearBufferMask.ColorBufferBit);
        game.SwapBuffers();
    };
}

与从
GameWindow
继承并重载其
OnRenderFrame
方法相比,订阅
GameWindow.RenderFrame
没有固有的优势。选择更适合您的代码结构的方法。

我认为
updateFrame
可以更新几何体和矩阵,而
renderFrame
可以实际绘制所有内容,
renderFrame
是主循环,尽可能频繁地处理(如果禁用了vsync)而UpdateName是在使用上下文创建中的参数定义的固定时间间隔(通常为30或60次/秒)触发的。由于人眼的帧速率感知限制,尽可能快地触发渲染是为了提高整体性能(据我们所知)。如果你的更新函数没有在这个限制下减慢进程,你可以在任何你想要的地方触发帧计算。谢谢你深刻的回答。当我第一次使用OpenTk时,Thirs确实帮助了我的理解。
using (var game = new GameWindow())
{
    game.RenderFrame += (sender, e) =>
    {
        GL.Clear(ClearBufferMask.ColorBufferBit);
        game.SwapBuffers();
    };
}