CastleWindow Backends

1. Introduction

TCastleWindow class represents a window suitable for Castle Game Engine rendering.

Most CGE applications use this class (although there is an alternative TCastleControl, but we advise TCastleWindow for most cases).

The TCastleWindow has a number of alternative backends, using different libraries underneath to manage the window and OpenGL(ES) context properties. By default, we use a backend that is considered "best" for the current operating system you’re compiling to, but you can override this choice by defining a symbol CASTLE_WINDOW_xxx at the compilation time. You can define this symbol in various places, e.g. in CastleEngineManifest.xml file.

Right now, we always use exactly one "backend", which is determined at the compile-time when you compile your application. In the future, we want to rework the CastleWindow infrastructure to enable you to use multiple backends, each backend in a separate unit, and (optionally) allow you to select the best backend at runtime.

2. Available backends

2.1. WinAPI backend (CASTLE_WINDOW_WINAPI)

The default backend on Windows. Looks native and supports everything.

Uses Windows API (WinAPI). By default it uses wgl to initialize OpenGL context. Can be also used (when symbol OpenGLES is defined) to initialize OpenGLES context using EGL. This way, you can test OpenGLES rendered on desktop Windows systems.

Supported platforms:

  • Windows only.

Advantages:

  • TCastleWindow.MainMenu is implemented as actual Windows menu bar, so it looks good and native.

  • Dialog windows like TCastleWindow.FileDialog are implemented using standard Windows dialog boxes, so again they look nice and native.

  • Supports both OpenGL (by wgl) and OpenGLES (by EGL) contexts.

2.2. GTK backend (CASTLE_WINDOW_GTK_2)

The default backend on most Unix systems, like Linux. Looks native and supports everything (except changing screen resolution, see below). Uses GTK 2. Initializes OpenGL(ES) context using Xlib + glX (for OpenGL) or EGL (for OpenGLES).

At some point, this will be also available under CASTLE_WINDOW_GTK symbol. At some further point, we will add backend CASTLE_WINDOW_GTK_3 and when it’s stable, CASTLE_WINDOW_GTK will be equivalent to CASTLE_WINDOW_GTK_3.

Supported platforms:

  • Works on any OS where GTK + glX / EGL works. Currently tested under Linux, FreeBSD, macOS.

Advantages:

  • TCastleWindow.MainMenu is implemented using GTK menu bar.

  • Dialog windows like TCastleWindow.FileDialog are implemented using GTK dialogs. So they look good and native.

  • Supports both OpenGL (by glX) and OpenGLES (by EGL) contexts.

Known problems:

  • Tab key cannot work as menu item shortcut (it’s always only for switching focus). This is an issue with GTK 2.

  • Application.TryVideoChange (to change screen resolution at runtime) is not finished, i.e. always returns false. See TODOs near CASTLE_WINDOW_USE_XF86VMODE definition.

History: at some point this was using GtkGlExt, and was portable to any system using GTK (even to Windows). This has changed because:

  • This way our dependencies are simpler (not every system has GtkGlExt),

  • there was not practical usage of this backend outside of GTK+Xlib anyway.

2.3. Xlib (X11) backend (CASTLE_WINDOW_XLIB)

A backend useful on most Unix systems, like Linux, that use X11.

Advantages compared to CASTLE_WINDOW_GTK (which supports similar platforms):

  • Doesn’t depend on GTK (one less dependency of your application).

  • Application.TryVideoChange works.

  • Supports both OpenGL (by glX) and OpenGLES (by EGL) contexts. By default it uses glX to initialize OpenGL context. But when symbol OpenGLES is defined, it uses EGL to initialize OpenGLES context. This way, you can test OpenGLES renderer on desktop Unix systems.

Known problems:

  • Doesn’t provide nicely-looking menu bar (TCastleWindow.MainMenu). Menu bar is not visible.

  • Doesn’t provide nicely-looking dialog boxes (TCastleWindow.FileDialog). The dialog boxes are implemented using simple modal boxes in CastleMessages instead, which works OK but doesn’t look pretty.

  • Full-screen (TCastleWindow.FullScreen) is realized using an obsolete method ("override_redirect") that doesn’t allow to switch applications with Alt+Tab from a fullscreen window.

2.4. Form (LCL or FMX) backend (CASTLE_WINDOW_FORM)

Backend that uses TForm and other LCL / FMX components to create a window. It is fully-functional:

To use this define CASTLE_WINDOW_FORM.

It is automatically used right now when you compile with Delphi for non-Windows platforms (Linux, macOS, Android, iOS…​).

Moreover, to use this from Lazarus (LCL):

  • Add castle_components package to the requirements of the castle_window Lazarus package.

    It will also automatically add LazOpenGLContext package as dependency, which is good. We need castle_components package for LCL helpers (like converting mouse/keys between LCL and CastleKeysMouse), and we need LazOpenGLContext package for TOpenGLControl.

  • Or you can use alternative_castle_window_based_on_lcl.lpk instead of castle_window.lpk in the project. This should take care of above 2 things.

  • Usually you should compile programs using Lazarus then (IDE or lazbuild), to automatically have correct LCL paths used. If you use our build tool or CGE editor, set build_using_lazbuild="true" in CastleEngineManifest.xml.

Supported platforms: everywhere where LCL or FMX runs.

Advantages:

  • Can use any LCL or FMX backend, so in principle allows to use TCastleWindow everywhere where they work.

  • Even some optional (not available in all backends) features are implemented: TCastleWindow.MainMenu or TCastleWindow.FileDialog or TCastleWindow.FullScreen.

Known problems:

  • LCL: Various small things don’t work perfectly using this backend, due to small problems/unfinished features in LCL. In practice we don’t advise this backend anymore with FPC or Lazarus — for all supported platform, we have a better specialized backend when you come from FPC, that also doesn’t depend on LCL.

  • Screen resizing (Application.TryVideoChange) is not implemented. LCL doesn’t implement it.

  • LCL: Message loop may stutter in case of a lot of mouse movement (may be visible in case of "mouse look" navigation).

  • LCL: Doesn’t support OpenGLES, as underlying TOpenGLControl doesn’t support it.

2.5. Android backend (CASTLE_WINDOW_ANDROID)

Backend using Android NDK cooperating with Castle Game Engine Android activity code. Used when you compile for Android, which you should always do using our build tool.

2.6. Library backend (CASTLE_WINDOW_LIBRARY)

Use existing OpenGL(ES) context. This is useful when the engine is used as a library, and an external code initializes OpenGL(ES) context, merely informing CGE about it. Useful for various cases, e.g. to "drive" Castle Game Engine rendering from another programming language. See examples/library/ for an example of wrapping CGE in a library.

Also, this is the only possible backend to use CGE on iOS or Nintendo Switch and it is automatically used there.

Supported platforms: All platforms. But note that using this backend requires additional "outside" code to manage our library. In case of iOS and Nintendo Switch, this is automatically provided when building using our build tool.

2.7. Cocoa backend (CASTLE_WINDOW_COCOA)

Backend using Cocoa with AppKit library, coded using Objective-Pascal. This is the technology to create native applications on macOS.

This backend is only available for macOS, and also is the advised backend there. It gives a native look for macOS applications, and covers all standard TCastleWindow features:

Known problems:

  • TODO: Fullscreen is not correct. The menu bar and macOS dock remain visible, covering parts of the fullscreen window. We have a code in place to deal with it…​ unsuccessfully, so far.

  • TODO: Hiding mouse cursor doesn’t work. Again we have a code to hide/unhide cursor, but it doesn’t work properly for unknown (yet!) reason.

  • When building, a few messages like warning: section "__datacoal_nt" is deprecated: .section __DATA, __datacoal_nt, coalesced are displayed. Compiling LCL app on macOS shows these warnings too. There is no solution for now, but the warnings can be safely ignored.

2.8. Template (CASTLE_WINDOW_TEMPLATE)

A dummy backend that does nothing, but compiles. Can be used as a starting point when developing new CastleWindow backends.

Supported platforms: All platforms.

3. Making new backend

  • Invent a symbol CASTLE_WINDOW_FOO for a new backend, document it in the "available backends list" above.

  • Create a file castlewindow_foo.inc with contents from castlewindow_backend_template.inc and conditionally include it from castlewindow_backend.inc.

  • Adjust defining CASTLE_WINDOW_HAS_VIDEO_CHANGE and CASTLE_WINDOW_USE_PRIVATE_MODIFIERS_DOWN for your backend.

  • Implement all methods in castlewindow_foo.inc.

  • Call TCastleWindow.DoXxx functions at appropriate places from your backend. You can call all DoUpdate all Application.OpenWindows using Application.FOpenWindows.DoUpdate.

  • Call ApplicationProperties._Update when appropriate. Remember that you can always assume that the ONLY existing instance of TCastleApplication is Application.

  • Remember that probably you will have to call ReleaseAllKeysAndMouse when user switches to another window or activates MainMenu.


To improve this documentation just edit this page and create a pull request to cge-www repository.