Castle Game EngineIntroduction Units Class Hierarchy Classes, Interfaces, Objects and Records Types Variables Constants Functions and Procedures Identifiers |
Class TCastleControlBase
Unit
CastleControl
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
Methods
Properties
Description
Fields
 |
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).
|
Methods
 |
constructor Create(AOwner: TComponent); override; |
|
 |
destructor Destroy; override; |
|
 |
function MakeCurrent(SaveOldToStack: boolean = false): boolean; override; |
|
 |
procedure Invalidate; override; |
|
 |
procedure Paint; override; |
|
 |
procedure Idle; virtual; |
|
 |
procedure ReleaseAllKeysAndMouse; |
|
 |
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.
|
 |
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
 |
property MouseX: Integer read FMouseX; |
|
 |
property MouseY: Integer read FMouseY; |
|
 |
property OnGLContextOpen: TNotifyEvent
read FOnGLContextOpen write FOnGLContextOpen; |
This will be called right after GL context will be initialized.
|
 |
property OnGLContextClose: TNotifyEvent
read FOnGLContextClose write FOnGLContextClose; |
This will be called right before GL context will be destroyed.
|
 |
property OnBeforeDraw: TNotifyEvent read FOnBeforeDraw write FOnBeforeDraw; |
|
 |
property OnDraw: TNotifyEvent read FOnDraw write FOnDraw; |
|
 |
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).
|
 |
property TabOrder; |
|
 |
property TabStop default true; |
|
Generated by PasDoc 0.12.1 on 2013-02-04 20:26:50
|