8

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();
}
ratchet freak
  • 47,288
  • 5
  • 68
  • 106
user3605638
  • 207
  • 1
  • 5
  • 11
  • 2
    I think that `updateFrame` is so you can update your geometry & matrices, while `renderFrame` is to actually draw everything, – ratchet freak May 08 '14 at 13:17
  • `renderFrame` is the main loop, processed as often as possible (if vsync disabled) while updateFrame is triggered at fixed interval defined with a parameter in your context creation (usualy 30 or 60 times/second). – j-p May 08 '14 at 14:32
  • Triggering rendering as fast as possible is for overall performance appreciation (as far as we know) because of human eyes frame rate perception limit. if your update function doesn't slow the process under that limit, you may trigger frame computations wherever you want. – j-p May 08 '14 at 14:43

1 Answers1

10

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.

Community
  • 1
  • 1
The Fiddler
  • 2,726
  • 22
  • 28
  • Thank you for your profound answer. Thirs really helped my understanding as I work with OpenTk for the first time. – user3605638 May 09 '14 at 01:31