Class TCastleControlBase

DescriptionHierarchyFieldsMethodsProperties

Unit

Declaration

type TCastleControlBase = class(TOpenGLControl)

Description

OpenGL control, with a couple of extensions for "Castle Game Engine". You will usually prefer to use TCastleControlCustom instead of directly this class, TCastleControlCustom adds some very useful features like TCastleControlCustom.Controls.

Provides OnGLContextOpen and OnGLContextClose events.

Provides comfortable Idle method. And a special AggressiveUpdate hack to be able to continously update (call Idle and Draw) even when the window system clogs us with events (this typically happens when user moves the mouse and we use TWalkCamera.MouseLook).

Also, this automatically calls LoadAllExtensions when GL context is initialized. This will initialize all extensions and set GLVersion variables, describing OpenGL version and available extensions.

Hierarchy

  • TOpenGLControl
  • TCastleControlBase

Overview

Fields

Public internal const DefaultAggressiveUpdateDelay = 1000 div 60;
Public internal const DefaultAggressiveUpdate = false;

Methods

Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public function MakeCurrent(SaveOldToStack: boolean = false): boolean; override;
Public procedure Invalidate; override;
Public procedure Paint; override;
Public procedure Idle; virtual;
Public procedure ReleaseAllKeysAndMouse;
Public procedure SetMousePosition(const NewMouseX, NewMouseY: Integer);
Public function SaveScreen: TRGBImage;

Properties

Public property Pressed: TKeysPressed read FPressed;
Public property MousePressed: CastleKeysMouse.TMouseButtons read FMousePressed;
Public property MouseX: Integer read FMouseX;
Public property MouseY: Integer read FMouseY;
Public property Fps: TFramesPerSecond read FFps;
Published property OnGLContextOpen: TNotifyEvent read FOnGLContextOpen write FOnGLContextOpen;
Published property OnGLContextClose: TNotifyEvent read FOnGLContextClose write FOnGLContextClose;
Published property OnBeforeDraw: TNotifyEvent read FOnBeforeDraw write FOnBeforeDraw;
Published property OnDraw: TNotifyEvent read FOnDraw write FOnDraw;
Published property AggressiveUpdate: boolean read FAggressiveUpdate write FAggressiveUpdate default DefaultAggressiveUpdate;
Published property AggressiveUpdateDelay: TMilisecTime read FAggressiveUpdateDelay write FAggressiveUpdateDelay default DefaultAggressiveUpdateDelay;
Published property TabOrder;
Published property TabStop default true;

Description

Fields

Public internal const DefaultAggressiveUpdateDelay = 1000 div 60;

Default value for TCastleControlBase.AggressiveUpdateDelay. "1000 div 60" means that we strike for 60 frames per second, although this is gross approximation (no guarantees, of course; especially if your Idle / Draw take a long time).

Public internal const DefaultAggressiveUpdate = false;

Default value for TCastleControlBase.AggressiveUpdate

Methods

Public constructor Create(AOwner: TComponent); override;
 
Public destructor Destroy; override;
 
Public function MakeCurrent(SaveOldToStack: boolean = false): boolean; override;
 
Public procedure Invalidate; override;
 
Public procedure Paint; override;
 
Public procedure Idle; virtual;
 
Public procedure ReleaseAllKeysAndMouse;
 
Public procedure SetMousePosition(const NewMouseX, NewMouseY: Integer);

Place mouse cursor at NewMouseX and NewMouseY. Position is specified relative to this window's upper-top corner (more specifically, OpenGL area upper-top corner), just like MouseX and MouseY properties.

Note that the actually set position may be different than requested, for example if part of the window is offscreen then window manager will probably refuse to move mouse cursor offscreen.

This may generate normal OnMouseMove event, just as if the user moved the mouse. But it's also allowed to not do this.

Ignored when window is closed.

Public function SaveScreen: TRGBImage;

Capture the current control contents to an image. These functions take care of flushing any pending redraw operations and capturing the screen contents correctly.

Properties

Public property Pressed: TKeysPressed read FPressed;
 
Public property MousePressed: CastleKeysMouse.TMouseButtons read FMousePressed;
 
Public property MouseX: Integer read FMouseX;
 
Public property MouseY: Integer read FMouseY;
 
Public property Fps: TFramesPerSecond read FFps;
 
Published property OnGLContextOpen: TNotifyEvent read FOnGLContextOpen write FOnGLContextOpen;

This will be called right after GL context will be initialized.

Published property OnGLContextClose: TNotifyEvent read FOnGLContextClose write FOnGLContextClose;

This will be called right before GL context will be destroyed.

Published property OnBeforeDraw: TNotifyEvent read FOnBeforeDraw write FOnBeforeDraw;
 
Published property OnDraw: TNotifyEvent read FOnDraw write FOnDraw;
 
Published property AggressiveUpdate: boolean read FAggressiveUpdate write FAggressiveUpdate default DefaultAggressiveUpdate;

Force Idle and Paint (if invalidated) events to happen continously.

You almost always want this to happen. Without this, when user "clogs" the GTK / WinAPI / Qt etc. event queue, Lazarus (LCL) doesn't continously fire the "Idle" events (used to update various state of our 3D world) and repaint events. This is somewhat tolerable for normal UI programs, that really "do" something only in response to user actions. But typical games / 3D simulations must try to update animations and repaint at a constant rate. Which means that we want "Idle" to be fired continously (not really only when application stays "idle"), and we want redraw to happen when needed (you signal the need to redraw by Invalidate call).

The most visible usage of this is when using TWalkCamera.MouseLook. Walking with mouse look typically produces a continous stream of mouse move events, usually interspersed with key down events (since you usually press forward / back / strafe keys at the same time when looking around with mouse). Without AggressiveUpdate, this really works badly.

So what does it do? We do not have the tools to hack Lazarus event control from the outside — existing Application methods allow us to process a single "batch" of events, but this is too much (for example, may be ˜ 100 GTK messages, see TGtkWidgetSet.AppProcessMessages in lazarus/trunk/lcl/interfaces/gtk/gtkwidgetset.inc). So instead we hack from the inside: from time to time (more precisely, after AggressiveUpdateDelay miliseconds since last Idle + Paint end), when receving key or mouse events (KeyDown, MouseDown, MouseMove etc.), we'll call the Idle, and (if pending Invalidate call) Paint methods.

Do not set too small, like 0, or you'll overload the system (you will see smooth animation and rendering, but there will be latency with respect to handling input, e.g. mouse move will be processed with a small delay).

Published property AggressiveUpdateDelay: TMilisecTime read FAggressiveUpdateDelay write FAggressiveUpdateDelay default DefaultAggressiveUpdateDelay;
 
Published property TabOrder;
 
Published property TabStop default true;
 

Generated by PasDoc 0.12.1 on 2013-02-04 20:26:50