Open TK difference onRenderFrame and onUpdateFrame?

对着背影说爱祢 提交于 2019-12-14 01:02:22

问题


I am currently programming a Jump n' Run game in C# using OpenTK Framework and OpenGL.

Open TK provides preset functions like GameWindow.Run(); or GameWindow.onUpdateFrame(); onRenderFrame();

As far as i thought through it, all actions that draw OpenGL elements or primitives should belong into onRenderFrame, whereas game events like player movement should be performed in onUpdateFrame, so these actions can be calculated in advance before rendering a new frame.

Am I right? Would it make a difference to perform all actions in the onRenderFrame method? OpenTK suggests not to override these methods and subscribing to their Events (onRenderFrameEvent) instead.

http://www.opentk.com/files/doc/class_open_t_k_1_1_game_window.html#abc3e3a8c21a36d226c9d899f094152a4]

What is subscribing and how would i subscribe to an event instead of overriding a method?

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();
}

回答1:


It's pretty much as the comments said: update your world in the UpdateFrame event and render it in RenderFrame.

This makes sense when you realize that your game will run on wildly different hardware. Some computers might only be able to render your game at 15fps. Others will achieve a solid 60fps. And players with 120Hz monitors will want your game to run at 120fps in order to enjoy the full potential of their systems.

In all those cases, you want your game logic to run at the same speed and give identical results.

The simplest way to achieve this is by setting a fixed UpdateFrame rate in GameWindow.Run():

using (var game = new GameWindow())
{
     game.VSync = VSyncMode.Adaptive;
     game.Run(60.0, 0.0);
}

This code snippet instructs OpenTK to raise 60 UpdateFrame events per second and as many RenderFrame events as the system can handle, up to the refresh rate of the monitor. When running on a slower system, OpenTK will drop RenderFrame events in order to ensure a solid 60 UpdateFrame events per second. This is typically called a "fixed timestep".

See Fix Your Timestep! for why this is desirable.

See Quake 3 for why you should not perform your world updates inside the RenderFrame event (short version: in Quake 3, numerical inaccuracies on high fps allow players to jump higher and gain a competitive advantage.)

Edit: for the second part of your question, see understanding C# events. For example:

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

There is no inherent advantage to subscribing GameWindow.RenderFrame compared to inheriting from GameWindow and overloading its OnRenderFrame method. Pick whichever approach fits your code structure better.



来源:https://stackoverflow.com/questions/23542591/open-tk-difference-onrenderframe-and-onupdateframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!