Class TCastleControl

Unit

Declaration

type TCastleControl = class(TCustomOpenGLControl)

Description

Control to render everything (3D or 2D) with Castle Game Engine.

See https://castle-engine.io/control_on_form for a documentation how to use this.

You can use this with TUIState, following https://castle-engine.io/control_on_form instructions. In this case, all user interface creation and event handling should be inside some state.

You can also add any user-interface controls to the Controls property. User-interface controls are any TCastleUserInterface descendants, like TCastleImageControl or TCastleButton or TCastleViewport. Use events like OnPress to react to events. Use event OnUpdate to do something continuously.

By default, the control is filled with simple color from Container.BackgroundColor.

This control is an alternative to rendering things using TCastleWindow. Note that you cannot use both TCastleControl and TCastleWindow within the same application.

Hierarchy

Overview

Fields

Public class var MainControl: TCastleControl;

Methods

Protected procedure DestroyHandle; override;
Protected procedure DoExit; override;
Protected procedure Resize; override;
Protected procedure KeyDown(var Key: Word; Shift: TShiftState); override;
Protected procedure UTF8KeyPress(var UTF8Key: TUTF8Char); override;
Protected procedure KeyUp(var Key: Word; Shift: TShiftState); override;
Protected procedure MouseDown(Button: Controls.TMouseButton; Shift:TShiftState; X,Y:Integer); override;
Protected procedure MouseUp(Button: Controls.TMouseButton; Shift:TShiftState; X,Y:Integer); override;
Protected procedure MouseMove(Shift: TShiftState; NewX, NewY: Integer); override;
Protected function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override;
Protected procedure DoUpdate; virtual;
Public constructor Create(AOwner: TComponent); override;
Public destructor Destroy; override;
Public function Controls: TInternalChildrenControls;
Public function MakeCurrent(SaveOldToStack: boolean = false): boolean; override;
Public procedure Invalidate; override;
Public procedure Paint; override;
Public function Pressed: TKeysPressed;
Public function MousePressed: TCastleMouseButtons;
Public procedure ReleaseAllKeysAndMouse;
Public function Fps: TFramesPerSecond;
Public procedure SaveScreen(const URL: string); overload;
Public function SaveScreen: TRGBImage; overload;
Public function SaveScreen(const SaveRect: TRectangle): TRGBImage; overload;
Public function SaveScreenBuffer: TColorBuffer;
Public function Rect: TRectangle;
Public function DesignedComponent(const ComponentName: String): TComponent;

Properties

Protected property GLInitialized: boolean read FGLInitialized;
Public property MousePosition: TVector2 read FMousePosition write SetMousePosition;
Published property Align;
Published property Anchors;
Published property BorderSpacing;
Published property Enabled;
Published property OpenGLMajorVersion;
Published property OpenGLMinorVersion;
Published property MultiSampling;
Published property AlphaBits;
Published property DepthBits;
Published property StencilBits;
Published property AUXBuffers;
Published property Options;
Published property OnChangeBounds;
Published property OnConstrainedResize;
Published property OnDblClick;
Published property OnDragDrop;
Published property OnDragOver;
Published property OnEnter;
Published property OnExit;
Published property OnMouseEnter;
Published property OnMouseLeave;
Published property OnShowHint;
Published property PopupMenu;
Published property ShowHint;
Published property Visible;
Published property TabOrder;
Published property TabStop default true;
Published property AutoFocus: Boolean read FAutoFocus write FAutoFocus default false;
Published property Container: TContainer read FContainer;
Published property OnOpen: TNotifyEvent read FOnOpen write FOnOpen;
Published property OnClose: TNotifyEvent read FOnClose write FOnClose;
Published property OnBeforeRender: TNotifyEvent read FOnBeforeRender write FOnBeforeRender;
Published property OnRender: TNotifyEvent read FOnRender write FOnRender;
Published property OnResize: TNotifyEvent read FOnResize write FOnResize;
Published property OnPress: TControlInputPressReleaseEvent read FOnPress write FOnPress;
Published property OnRelease: TControlInputPressReleaseEvent read FOnRelease write FOnRelease;
Published property OnMotion: TControlInputMotionEvent read FOnMotion write FOnMotion;
Published property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate;
Published property AutoRedisplay: boolean read FAutoRedisplay write SetAutoRedisplay default true;
Published property DesignUrl: String read FDesignUrl write SetDesignUrl;

Description

Fields

Public class var MainControl: TCastleControl;

Central control where user-interface states (TUIState) are added. You do not need to set this if you don't use TUIState.

Methods

Protected procedure DestroyHandle; override;
 
Protected procedure DoExit; override;
 
Protected procedure Resize; override;
 
Protected procedure KeyDown(var Key: Word; Shift: TShiftState); override;
 
Protected procedure UTF8KeyPress(var UTF8Key: TUTF8Char); override;
 
Protected procedure KeyUp(var Key: Word; Shift: TShiftState); override;
 
Protected procedure MouseDown(Button: Controls.TMouseButton; Shift:TShiftState; X,Y:Integer); override;
 
Protected procedure MouseUp(Button: Controls.TMouseButton; Shift:TShiftState; X,Y:Integer); override;
 
Protected procedure MouseMove(Shift: TShiftState; NewX, NewY: Integer); override;
 
Protected function DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean; override;
 
Protected procedure DoUpdate; virtual;
 
Public constructor Create(AOwner: TComponent); override;
 
Public destructor Destroy; override;
 
Public function Controls: TInternalChildrenControls;

List of user-interface controls currently active. You can add your TCastleUserInterface instances (like TCastleViewport, TCastleButton and much more) to this list. We will pass events to these controls, draw them etc. See TCastleContainer.Controls for details.

Public function MakeCurrent(SaveOldToStack: boolean = false): boolean; override;
 
Public procedure Invalidate; override;
 
Public procedure Paint; override;
 
Public function Pressed: TKeysPressed;

Keys currently pressed.

Public function MousePressed: TCastleMouseButtons;

Mouse buttons currently pressed. See TCastleContainer.MousePressed for details.

Public procedure ReleaseAllKeysAndMouse;
 
Public function Fps: TFramesPerSecond;

Application speed.

Public procedure SaveScreen(const URL: string); overload;

Capture the current control contents to an image.

Public function SaveScreen: TRGBImage; overload;
 
Public function SaveScreen(const SaveRect: TRectangle): TRGBImage; overload;
 
Public function SaveScreenBuffer: TColorBuffer;

Color buffer where we draw, and from which it makes sense to grab pixels. Use only if you save the screen using low-level SaveScreen_NoFlush function. Usually, you should save the screen using the simpler SaveScreen method, and then the SaveScreenBuffer is not useful.

Public function Rect: TRectangle;

Rectangle representing the inside of this container. Always (Left,Bottom) are zero, and (Width,Height) correspond to container sizes.

Public function DesignedComponent(const ComponentName: String): TComponent;

When the DesignUrl is set you can use this method to find loaded components. Like this:

MyButton := MyCastleControl.DesignedComponent('MyButton') as TCastleButton;

See also
DesignUrl
Load and show the design (.castle-user-interface file).

Properties

Protected property GLInitialized: boolean read FGLInitialized;
 
Public property MousePosition: TVector2 read FMousePosition write SetMousePosition;

Current mouse position. See TTouch.Position for a documentation how this is expressed.

Published property Align;

Be cafeful about comments in the published section. They are picked up and shown automatically by Lazarus Object Inspector, and it has it's own logic, much much dumber than what PasDoc sees. There seems no way to hide comment there.

We publish most, but not all, stuff from inherited TCustomOpenGLControl.

Exceptions: - Don't publish these, as not every widgetset has them: property RedBits; property GreenBits; property BlueBits;

- Don't publish these, as we have our own events for this: property OnResize; property OnClick; property OnKeyDown; property OnKeyPress; property OnKeyUp; property OnMouseDown; property OnMouseMove; property OnMouseUp; property OnMouseWheel; property OnMouseWheelDown; property OnMouseWheelUp; property OnPaint;

- Don't use, engine handles this completely: property OnMakeCurrent; property AutoResizeViewport;

Published property Anchors;
 
Published property BorderSpacing;
 
Published property Enabled;
 
Published property OpenGLMajorVersion;
 
Published property OpenGLMinorVersion;
 
Published property MultiSampling;
 
Published property AlphaBits;
 
Published property DepthBits;
 
Published property StencilBits;
 
Published property AUXBuffers;
 
Published property Options;
 
Published property OnChangeBounds;
 
Published property OnConstrainedResize;
 
Published property OnDblClick;
 
Published property OnDragDrop;
 
Published property OnDragOver;
 
Published property OnEnter;
 
Published property OnExit;
 
Published property OnMouseEnter;
 
Published property OnMouseLeave;
 
Published property OnShowHint;
 
Published property PopupMenu;
 
Published property ShowHint;
 
Published property Visible;
 
Published property TabOrder;
 
Published property TabStop default true;
 
Published property AutoFocus: Boolean read FAutoFocus write FAutoFocus default false;

Automatically make this control focused (receiving key input) when user clicks on it.

If this is True, consider showing it in some way, e.g. draw something special in OnRender when this control is focused. You can check "Focused" property ( https://lazarus-ccr.sourceforge.io/docs/lcl/controls/twincontrol.focused.html ) or FormXxx.ActiveControl or register OnEnter / OnExit LCL events.

Published property Container: TContainer read FContainer;
 
Published property OnOpen: TNotifyEvent read FOnOpen write FOnOpen;

Event called when the OpenGL context is created.

You can initialize things that require OpenGL context now. Often you do not need to use this callback (engine components will automatically create/release OpenGL resource when necessary). You usually will also want to implement OnClose callback that should release stuff you create here.

Often, instead of using this callback, it's cleaner to derive new classes from TCastleUserInterface class or it's descendants, and override their GLContextOpen / GLContextClose methods to react to context being open/closed. Using such TCastleUserInterface classes is usually easier, as you add/remove them from controls whenever you want (e.g. you add them in ApplicationInitialize), and underneath they create/release/create again the OpenGL resources when necessary.

Note that we automatically initialize necessary Castle Game Engine resources when context is created (GLVersion, GLFeatures and more).

Published property OnClose: TNotifyEvent read FOnClose write FOnClose;

Event called when the context is closed, right before the OpenGL context is destroyed. This is your last chance to release OpenGL resources, like textures, shaders, display lists etc. This is a counterpart to OnOpen event.

Published property OnBeforeRender: TNotifyEvent read FOnBeforeRender write FOnBeforeRender;

Event always called right before OnRender. These two events, OnBeforeRender and OnRender, will be always called sequentially as a pair.

The only difference between these two events is that time spent in OnBeforeRender is NOT counted as "frame time" by Fps.OnlyRenderFps. This is useful when you have something that needs to be done from time to time right before OnRender and that is very time-consuming. It such cases it is not desirable to put such time-consuming task inside OnRender because this would cause a sudden big change in Fps.OnlyRenderFps value. So you can avoid this by putting this in OnBeforeRender.

Published property OnRender: TNotifyEvent read FOnRender write FOnRender;

Render window contents here.

Called when window contents must be redrawn, e.g. after creating a window, after resizing a window, after uncovering the window etc. You can also request yourself a redraw of the window by the Invalidate method, which will cause this event to be called at nearest good time.

Note that calling Invalidate while in EventRender (OnRender) is not ignored. It instructs to call EventRender (OnRender) again, as soon as possible.

When you have some controls on the Controls list, the OnRender event is done last. So here you can draw on top of the existing UI controls. To draw something underneath the existing controls, create a new TCastleUserInterface and override it's TCastleUserInterface.Render and insert it to the controls using Controls.InsertBack(MyBackgroundControl);.

Published property OnResize: TNotifyEvent read FOnResize write FOnResize;

Called when the control size (Width, Height) changes. It's also guaranteed to be called right after the OnOpen event.

Published property OnPress: TControlInputPressReleaseEvent read FOnPress write FOnPress;

Called when user presses a key or mouse button or moves mouse wheel.

Published property OnRelease: TControlInputPressReleaseEvent read FOnRelease write FOnRelease;

Called when user releases a pressed key or mouse button.

It's called right after Pressed[Key] changed from true to false.

The TInputPressRelease structure, passed as a parameter to this event, contains the exact information what was released.

Note that reporting characters for "key release" messages is not perfect, as various key combinations (sometimes more than one?) may lead to generating given character. We have some intelligent algorithm for this, used to make Characters table and to detect this C for OnRelease callback. The idea is that a character is released when the key that initially caused the press of this character is also released.

This solves in a determined way problems like "what happens if I press Shift, then X, then release Shift, then release X". (will "X" be correctly released as pressed and then released? yes. will small "x" be reported as released at the end? no, as it was never pressed.)

Published property OnMotion: TControlInputMotionEvent read FOnMotion write FOnMotion;

Mouse or a finger on touch device moved.

For a mouse, remember you always have the currently pressed mouse buttons in MousePressed. When this is called, the MousePosition property records the previous mouse position, while callback parameter NewMousePosition gives the new mouse position.

Published property OnUpdate: TNotifyEvent read FOnUpdate write FOnUpdate;

Continuously occuring event. This event is called roughly as regularly as redraw, and you should use this to update your game state.

Note that this is different than LCL "idle" event, as it's guaranteed to be run continuously, even when your application is clogged with events (like when using TCastleWalkNavigation.MouseLook).

Note: As we need to continuously call the "update" event (to update animations and more), we listen on the Lazarus Application "idle" event, and tell it that we're never "done" with our work. We do this only when at least one instance of TCastleControl is created, and never at design-time. This means that your own "idle" events (registered through LCL TApplicationProperties.OnIdle or Application.AddOnIdleHandler) may be never executed, because really the application is never idle.

If you want to reliably do some continuous work, use Castle Game Engine features to do it. There are various alternative ways:

Published property AutoRedisplay: boolean read FAutoRedisplay write SetAutoRedisplay default true;

Should we automatically redraw the window all the time, without the need for an Invalidate call. If True (the default), OnRender will called constantly.

If your game may have a still screen (nothing animates), then this approach is a little unoptimal, as we use CPU and GPU for drawing, when it's not needed. In such case, you can set this property to False, and make sure that you call Invalidate always when you need to redraw the screen. Note that the engine components always call Invalidate when necessary, so usually you should only call it yourself if you provide a custom OnRender implementation.

Published property DesignUrl: String read FDesignUrl write SetDesignUrl;

Load and show the design (.castle-user-interface file). You can reference the loaded components by name using DesignedComponent.

If you have more complicated control flow, we recommend to leave this property empty, and split your management into a number of states (TUIState) instead. In this case, load design using TUIState.DesignUrl. This property makes it however easy to use .castle-user-interface in simple cases, when TCastleControl just shows one UI.

The design loaded here is visible also at design-time, when editing the form in Lazarus/Delphi. Though we have to way to edit it now in Lazarus/Delphi (you have to use CGE editor to edit the design), so it is just a preview in this case.


Generated by PasDoc 0.16.0.