Bare Game Example: Cube

Some people on the Lazarus forums where discussing frames and time with regards to game development. I decided to create a real quick video demonstrating what I consider the proper way to deal with time in games.
That is, don't use a TTimer, instead use a high performance time function, wrap it in a class, and for the purposes of game dev, you should have separate logic and render thread which are all apart from the message queue (user interface) thread.

Demo

Here is the quick demonstration video (based on SDL 2) I wrote on Ubuntu. It should compile and run the same on any platform (Windows, Macintosh, Raspbian Pi).

Getting Setup

If you're interested in playing around with these type of approach you'll to need to install Lazarus and SDL 2. Next get BareGame from github. After than start Lazarus and...
  1. Open package source/barerun.lpk and compilel
  2. Open package tools/design/baredsgn.lpk and install
Now can then select "Project | New Project ... | Game Project" from within Lazarus to start a new Game Project

Program listing

Below is a listing of the cube example program. You can research the help reference documentation about the Bare Game library on its official website. Comments are provided in the source code to help new users understand the structure.
program Game1;

{$mode delphi}

uses
  Bare.Game,
  Bare.System,
  Bare.Interop.OpenGL,
  Bare.Graphics,
  Bare.Example;

{ TWindow1 }

type
  TWindow1 = class(TWorldWindow)
  protected
    procedure Logic(Stopwatch: TStopwatch); override;
    procedure Render(Stopwatch: TStopwatch); override;
  end;

procedure TWindow1.Logic(Stopwatch: TStopwatch);
begin
  MessageQueue.Remove;
  if MessageQueue.KeyDown(VK_SPACE) then
    Stopwatch.Paused := not Stopwatch.Paused;
end;

procedure TWindow1.Render(Stopwatch: TStopwatch);
var
  S: string;
begin
  glClearColor(0, 0, 1, 1);
  World.Update;
  glLoadIdentity;
  glTranslatef(0.0, 0.0, -6.0);
  glRotatef(Stopwatch.Time * 20, 0.19, 1, 0.62);
  glDisable(GL_TEXTURE_2D);
  glBegin(GL_QUADS);
  glColor3f(0, 1, 0);
  glVertex3f( 1, 1, -1);
  glVertex3f(-1, 1, -1);
  glVertex3f(-1, 1, 1);
  glVertex3f( 1, 1, 1);
  glColor3f(1, 0.5, 0);
  glVertex3f( 1, -1, 1);
  glVertex3f(-1, -1, 1);
  glVertex3f(-1, -1, -1);
  glVertex3f( 1, -1, -1);
  glColor3f(1, 0, 0);
  glVertex3f( 1, 1, 1);
  glVertex3f(-1, 1, 1);
  glVertex3f(-1, -1, 1);
  glVertex3f( 1, -1, 1);
  glColor3f(1, 1, 0);
  glVertex3f( 1, -1, -1);
  glVertex3f(-1, -1, -1);
  glVertex3f(-1, 1, -1);
  glVertex3f( 1, 1, -1);
  glColor3f(0, 0.5, 1);
  glVertex3f(-1, 1, 1);
  glVertex3f(-1, 1, -1);
  glVertex3f(-1, -1, -1);
  glVertex3f(-1, -1, 1);
  glColor3f(1, 0, 1);
  glVertex3f( 1, 1, -1);
  glVertex3f( 1, 1, 1);
  glVertex3f( 1, -1, 1);
  glVertex3f( 1, -1, -1);
  glEnd;
  glLoadIdentity;
  S := Format('Game time: %.2f'#13#10'Framerate: %d', [Stopwatch.Time, Stopwatch.Framerate]);
  Font.Write(S, 1, 1, 0);
end;

begin
  Application.Run(TWindow1);
end.