Unit CastleWindow

DescriptionUsesClasses, Interfaces, Objects and RecordsFunctions and ProceduresTypesConstantsVariables

Description

Window with OpenGL context suitable for 2D and 3D rendering of "Castle Game Engine". The base TCastleWindowBase provides a simple window with OpenGL context, and is suitable for any OpenGL program. More advanced TCastleWindow extends it to comfortably render 2D controls and 3D objects defined by our engine.

Application object (instance of class TGLApplication) is a central manager of all open TCastleWindowBase windows.

Using this unit:

  1. Declare and create TCastleWindowBase instance. (Or a descendant like TCastleWindow.)

  2. Assign Glw properties and callbacks like OnDraw, OnResize, Width, Height, Caption.

  3. Call Window.Open, this will actually show the window and it's associated OpenGL context. It also calls EventOpen (OnOpen callback) and EventResize (OnResize callback).

  4. Call Application.Run. This will enter message loop that will call appropriate windows' callbacks at appropriate times (OnDraw, OnPress, OnRelease, OnResize, OnIdle and many more). There are also some Application callbacks, like Application.OnIdle.

    For more advanced needs you can use something like

      while Application.ProcessMessage do <something>;

    instead of Application.Run.

    You can also call Window.OpenAndRun, this is just a shortcut for Window.Open + Application.Run.

  5. Application.Run ends when you call Application.Quit or when you close last visible window using Close(true).

    User is also allowed to close a window using WindowManager facilities (clicking on "X" button in the frame corner, pressing Alt+F4 or something like that). By default, such user action will make window close (but you can freely customize what your program does when user tries to close the window using callback OnCloseQuery).

So the simplest example of using this unit can look like this:

  uses CastleWindow;

  var
    Window: TCastleWindowCustom;

  procedure Draw(Window: TCastleWindowBase);
  begin  ...  end;

  procedure Resize(Window: TCastleWindowBase);
  begin  ...  end;

  begin
    Window := TCastleWindowCustom.Create(Application);
    Window.OnResize := @Resize;
    Window.OnDraw := @Draw;
    Window.Caption := 'Simplest CastleWindow example';
    Window.OpenAndRun;
  end.

More object-oriented approach: Instead of assigning callbacks (OnDraw, OnResize etc.) you can also derive a new class from TCastleWindowBase and override some of virtual methods, like EventDraw, EventResize etc. Every callback OnXxx has a corresponding EventXxx method. In TCastleWindowBase class, all EventXxx methods simply call appropriate OnXxx callbacks (this way you can use whatever approach you like – OOP or not-OOP).

This is a second version of the "simplest example" program above, this time using OOP approach:

  uses CastleWindow;

  type
    TMyWindow = class(TCastleWindowCustom)
      procedure EventDraw; override;
      procedure EventResize; override;
    end;

  procedure TMyWindow.EventDraw;
  begin  ...  end;

  procedure TMyWindow.EventResize;
  begin  ...  end;

  var
    Window: TMyWindow;
  begin
    Window := TMyWindow.Create(Application);
    Window.Caption := 'Simplest CastleWindow example using more OOP';
    Window.OpenAndRun;
  end.

The non-OOP approach has one advantage: you can easily switch all callbacks to some other set of callbacks. This allows you to implement modal behaviors, where a function suspends normal callbacks to display some dialog. See CastleWindowModes unit and, build on top of it, dialog boxes in CastleMessages and progress bar in CastleWindowProgress. These units give you some typical GUI capabilities, and they are in pure OpenGL.

Using OOP approach (overriding EventXxx methods instead of registering OnXxx callbacks) you can not do such things so easily – in general, you have to define something to turn off special EventXxx functionality (like SetDemoOptions in TCastleWindowDemo and UseControls in TCastleWindowCustom) and you have to turn them off/on when using CastleWindowModes (mentioned TCastleWindowDemo and TCastleWindowCustom are already handled in CastleWindowModes). TODO: I shall do some virtual methods in TCastleWindowBase to make this easy.

Random features list:

Uses

Overview

Classes, Interfaces, Objects and Records

Name Description
Class TMenuEntry A basic class representing basic menu building block.
Class TMenuEntryWithCaption  
Class TMenu TMenuEntry that contains a list of menu entries.
Class TMenuItem TMenuEntry that is a simple, clickable menu item.
Class TMenuSeparator TMenuEntry that acts as a visual separator (horizontal line or something like that) between menu items.
Class TMenuItemChecked TMenuItem that should visualize Checked state somehow to the user.
Class TMenuItemRadio Menu radio item.
Class TMenuItemRadioGroup A group of radio buttons.
Class EGLContextNotPossible  
Class TCastleWindowBase Window with an OpenGL context.
Class TCastleWindowDemo Window with OpenGL context and some functionality typically useful for simple demo programs.
Class TCastleWindowCustom OpenGL window keeping a Controls list.
Class TCastleWindow Window with an OpenGL context, most comfortable to render 3D worlds with 2D controls above.
Class TWindowList  
Class TGLApplication Application, managing all open TCastleWindowBase (OpenGL windows).

Functions and Procedures

procedure Resize2D(Window: TCastleWindowBase);
function MenuItemFromSmallId(SearchSmallId: Integer): TMenuItem;
function SRemoveMnemonics(const S: string): string;
function SQuoteMenuEntryCaption(const S: string): string;

Types

TWindowParseOption = (...);
TWindowParseOptions = set of TWindowParseOption;
PWindowParseOptions = ˆTWindowParseOptions;
TAntiAliasing = (...);
TMenuEntryList = specialize TFPGObjectList<TMenuEntry>;
TWindowMessageType = (...);
TIdleFunc = procedure;
TWindowFunc = procedure (Window: TCastleWindowBase);
TDrawFunc = TWindowFunc;
TMouseMoveFunc = procedure (Window: TCastleWindowBase; NewX, NewY: Integer);
TInputPressReleaseFunc = procedure (Window: TCastleWindowBase; const Event: TInputPressRelease);
TMenuCommandFunc = procedure (Window: TCastleWindowBase; Item: TMenuItem);
TGLContextRetryOpenFunc = function (Window: TCastleWindowBase): boolean;
TResizeAllowed = (...);
PGtkGLArea = PGtkWidget;

Constants

WindowPositionCenter = -1000000;
WindowDefaultSize = -1000000;
StandardParseOptions = [poGeometry, poScreenGeometry, poDisplay];
DefaultDepthBits = 16;
DefaultFpsCaptionUpdateInterval = 5000;
DefaultTooltipDelay = 1000;
DefaultTooltipDistance = 10;
DefaultLimitFPS = 100.0;
DefaultAntiAliasing = aaNone;
AntiAliasingNames: array [TAntiAliasing] of string = ( 'None', '2 samples (faster)', '2 samples (nicer)', '4 samples (faster)', '4 samples (nicer)' );

Variables

Application: TGLApplication;

Description

Functions and Procedures

procedure Resize2D(Window: TCastleWindowBase);

A simple TCastleWindowBase.OnResize callback implementation, that sets 2D projection. You can use it like Window.OnResize := Resize2D; or just by calling it directly from your OnResize callback.

It does

  glViewport(0, 0, Window.Width, Window.Height);
  OrthoProjection(0, Window.Width, 0, Window.Height);

function MenuItemFromSmallId(SearchSmallId: Integer): TMenuItem;

Search for menu item with given SmallId. SearchSmallId must be a SmallId of some existing (i.e. created and not destroyed yet) TMenuItem. This function returns this TMenuItem.

function SRemoveMnemonics(const S: string): string;

Returns S with each '__' replaced with single '_', any other '_' removed.

In other words: with mnemonics (as defined by TMenuEntryWithCaption.Caption removed.

function SQuoteMenuEntryCaption(const S: string): string;

Returns S with each underscore '_' replaced by two underscores, '__'.

In other words: S will not contain any mnemonics. If you will assign S to TMenuEntryWithCaption.Caption, then this menu entry caption will display exactly S, without any mnemonics. Single '_' in S will be displayed exactly as single '_'.

Types

TWindowParseOption = (...);
 
Values
  • poGeometry:  
  • poScreenGeometry:  
  • poDisplay:  
TWindowParseOptions = set of TWindowParseOption;
 
PWindowParseOptions = ˆTWindowParseOptions;
 
TAntiAliasing = (...);

Anti-aliasing values for TCastleWindowBase.AntiAliasing.

Values
  • aaNone:  
  • aa2SamplesFaster: 2 samples, "don't care" hint.
  • aa2SamplesNicer: 2 samples, "nicest" hint (quincunx (5 taps) for NVidia).
  • aa4SamplesFaster: 4 samples, "don't care" hint.
  • aa4SamplesNicer: 4 samples, "nicest" hint (9 taps for NVidia).
TMenuEntryList = specialize TFPGObjectList<TMenuEntry>;
 
TWindowMessageType = (...);

Type of message box, for TCastleWindowBase.MessageOK and TCastleWindowBase.MessageYesNo.

Values
  • mtInfo:  
  • mtWarning:  
  • mtQuestion:  
  • mtError:  
  • mtOther:  
TIdleFunc = procedure;
 
TWindowFunc = procedure (Window: TCastleWindowBase);
 
TDrawFunc = TWindowFunc;
 
TMouseMoveFunc = procedure (Window: TCastleWindowBase; NewX, NewY: Integer);
 
TInputPressReleaseFunc = procedure (Window: TCastleWindowBase; const Event: TInputPressRelease);
 
TMenuCommandFunc = procedure (Window: TCastleWindowBase; Item: TMenuItem);
 
TGLContextRetryOpenFunc = function (Window: TCastleWindowBase): boolean;
 
TResizeAllowed = (...);
 
Values
  • raNotAllowed:  
  • raOnlyAtOpen:  
  • raAllowed:  
PGtkGLArea = PGtkWidget;

For now I use GtkDrawingArea when CASTLE_WINDOW_GTK_2. But, really, GLAreaGtk could be any gtk widget with CASTLE_WINDOW_GTK_2.

Constants

WindowPositionCenter = -1000000;
 
WindowDefaultSize = -1000000;
 
StandardParseOptions = [poGeometry, poScreenGeometry, poDisplay];

All "normal" command-line options, that most programs using CastleWindow should be able to handle without any problems.

In other words, most programs calling TCastleWindowBase.ParseParameters method can safely pass as the 1st parameter this constant, StandardParseOptions. Or they can simply call overloaded version of TCastleWindowBase.ParseParameters that doesn't take any parameters, it is always equivalent to calling TCastleWindowBase.ParseParameters(StandardParseOptions).

DefaultDepthBits = 16;
 
DefaultFpsCaptionUpdateInterval = 5000;
 
DefaultTooltipDelay = 1000;
 
DefaultTooltipDistance = 10;
 
DefaultLimitFPS = 100.0;
 
DefaultAntiAliasing = aaNone;
 
AntiAliasingNames: array [TAntiAliasing] of string = ( 'None', '2 samples (faster)', '2 samples (nicer)', '4 samples (faster)', '4 samples (nicer)' );
 

Variables

Application: TGLApplication;

One global instance of TGLApplication.

Don't change value of this variable, don't Free this object. This will be handled in initialization / finalization of this module. Many things in this unit, also in TCastleWindowBase class implementation, depend on having this variable present all the time.


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