This is an old revision of the document!


Viewport

The 2D/3D Firemonkey components (TButton, TLabel, …) are still compatible with Gorilla3D. But instead of using a TViewport3D or TForm3D, we need to drag at first the TGorillaViewport onto our form.

Creating a Gorilla3D Viewport at design-time

You can find the viewport at designtime in the toolbar under:

Gorilla3D > TGorillaViewport.

Simply drag it onto your form or create it at runtime by the following method.

CAUTION: Gorilla3D is not compatible with TForm3D and TViewport3D!

Creating a viewport at runtime

If you need to create the Gorilla3D viewport at runtime, you can do it the following way:

Form1.pas
uses
  FMX.UITypes,
  Gorilla.Viewport;
 
// in our form (TForm1) we added a field named "FGorilla"
procedure TForm1.FormCreate(Sender: TObject);
begin
  FGorilla := TGorillaViewport.Create(Self);
  FGorilla.Parent := Form1;
  FGorilla.Color  := TAlphaColorRec.Black;
end;

Frame-Rate

Requesting FrameRate (FPS)

Currently it is not possible to retrieve an actual framerate, but the TGorillaViewport provides an estimated framerate value.

Simply setup a timer and request those value every 100 milliseconds.

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Self.Caption := Format('Gorilla 3D - %n FPS', [FGorilla.FPS]);
end;

Notice

The estimated framerate measures the time a complete render cycle needs, including all objects, render passes and the main pass itself. Based on this value we compute the possible frames per second for the last interval. So Gorilla3D FPS value is only an orientation for you and the possible performance of your application.

Animation-Framerate (TAnimation): Because skin- and skeleton animation extends basic Firemonkey TAnimation. Therefore animations are limited to 30 FPS for rendering.

UseFixedFrameRate

FrustumCulling

HighRes

Fog

Optimization

In Firemonkey every time you change a visual property of a component, for example the position of a TCube, FMX will throw an event to update the viewport.

Cube1.Position.X := Cube1.Position.X + 0.1;
Cube1.Position.Y := Cube1.Position.Y + 0.2;
Cube1.Position.Z := Cube1.Position.Z + 0.3;

As you can imagine this is very slow, especially when you did not expected an update on changing the x, y and z value of a position.

Therefor the TGorillaViewport provides an optimization mechanism. Encapsulate those operations into BeginUpdate and EndUpdate to perform only one update command on the viewport renderer.

  FGorilla.BeginUpdate();
  try
    Cube1.Position.X := Cube1.Position.X + 0.1;
    Cube1.Position.Y := Cube1.Position.Y + 0.2;
    Cube1.Position.Z := Cube1.Position.Z + 0.3;  
  finally
    FGorilla.EndUpdate();
  end;

In case you need explicit render instructions, you can suppress updates completely, by calling EndUpdateWithoutInvalidate instead of EndUpdate.

  FGorilla.BeginUpdate();
  try
    Cube1.Position.X := Cube1.Position.X + 0.1;
    Cube1.Position.Y := Cube1.Position.Y + 0.2;
    Cube1.Position.Z := Cube1.Position.Z + 0.3;  
  finally
    FGorilla.EndUpdateWithoutInvalidate();
  end;

But you have to update viewport yourself by calling:

  FGorilla.Invalidate();

Shaders

Since v0.8.0 rendering pipeline was optimized due to unnecessary render instructions. An update limitation was implemented, that not every property change leads to a new rendering. Besides that you may use a shader / material which updates itself by time. The TGorillaWaterMaterialSource is an example. Waves are generated by a timevalue, but it will only update on re-rendering.

Here we need an explicit render instruction. Like you may already know from other Delphi components the TGorillaViewport supports the “Invalidate” method to tell Gorilla3D to re-render. Call this method constantly in a TTimer or by synchronized thread to update water material.

Next step: Loading models