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();
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With