Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open TK difference onRenderFrame and onUpdateFrame?

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();
}
like image 347
user3605638 Avatar asked May 08 '14 13:05

user3605638


1 Answers

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.

like image 99
The Fiddler Avatar answered Nov 15 '22 07:11

The Fiddler