Images

Creating new TCastleImageControl in editor
Setting up TCastleImageControl in editor

1. Display images

There are 3 recommended ways to display an image using Castle Game Engine.

1.1. TCastleImageControl (image as user interface component)

When the image is part of a 2D user-interface, use TCastleImageControl. Set the TCastleImageControl.URL to load the image.

You can create such image components using Pascal code or using the CGE visual editor.

Manual chapter Designing user interface describes using images in UI.

1.2. TCastleImageTransform (image component inside a viewport, with powerful game features)

When the image is part of the viewport, use TCastleImageTransform. Set the TCastleImageTransform.Url to load the image.

Such images are part of the viewport. See manual about viewport. The advantages of this approach are:

  • you have a camera (to control what user sees) in a vewport.

  • you can trivially have a working navigation, in 3D or 2D, too.

  • you can combine the image with other TCastleTransform components. In particular you can add TCastleScene with animations (sprite sheets), you can transform images in 3D too, you can display everything freely behind or in front of images.

  • such images can have physics colliders and rigid bodies.

1.3. TDrawableImage (drawing image yourself)

The last method is to load the image to TDrawableImage. This is the low-level approach, where you will need to manually handle drawing the image at the appropriate moment, following manual about custom-drawing UI things in CGE.

The basic code example is:

procedure TMyState.Create(AOwner: TComponent);
begin
  inherited;
  SomeImage := TDrawableImage.Create('castle-data:/image.png');
end;
...
procedure TMyState.Render;
begin
  inherited;
  SomeImage.Draw(XOnScreen, YOnScreen, WidthOnScreen, HeightOnScreen);
end;

2. Which approach to use?

The approaches 1 and 2 can be used when designing the game in the editor and are more advised.

Approach 3 may be easier to use in some cases (if you already think in terms "I want to have code that draws images"). Also TDrawableImage.Draw allows to draw with batching, which allows to reliably achieve great speed when drawing large maps.

Note
TODO: In the future batching should also work across TCastleImageTransform, if you activate boolean DynamicBatching. But right now, dynamic batching will not optimize multiple TCastleImageTransform instances.

3. Supported image formats

All approaches handle all the image formats supported by CGE, like PNG or JPG; see castle-view-image docs for the full list.

4. For 2D maps: Tiled is an alternative

If you want to draw 2D maps, an alternative is to design them in Tiled. You can then:

  1. load ready map in TCastleTiledMapControl. See 2 examples in examples/tiled/. It’s a UI element.

  2. load ready map in TCastleScene.

For now TCastleTiledMapControl supports a few more Tiled options.

5. Internal: Image types in CGE

  • TCastleImageControl is a descendant of TCastleUserInterface and allows to use the image as part of the UI. It refers to TCastleImagePersistent to load image contents using cache. It is a trivial user-interface control to render image on the screen. It can be added and configured in the editor.

  • TCastleImageTransform is a descendant of TCastleTransform and allows to place the image in the TCastleViewport, modify image size, repeat it many times etc. It is also useful from the editor.

  • TEncodedImage is an image loaded to a regular memory (RAM) to operate on it by Pascal code (that is, on CPU).

    Important descendant of TEncodedImage is TCastleImage which is an image that is expressed in memory as directly-accessible array of pixels. It has more descendants for grayscale, RGB, RGBA, float-based images etc. If you want to edit image on CPU, this is what you will use. E.g. create TRGBAlphaImage and iterate over TRGBAlphaImage.Pixels. There are many methods to draw lines, shapes, text to the image.

    Images are usually 2D, but we also support 3D, for 3D (volumetric) textures.

  • TDrawableImage holds an image (loaded from TEncodedImage) on GPU. It can be actually rendered on the screen.

    Also, you can edit this image by drawing to it on GPU, see TDrawableImage.RenderToImageBegin. Example is in examples/images_videos/draw_images_on_gpu.lpr.

  • TCastleImagePersistent is a container around TCastleImage and TDrawableImage. It is using cache to load images. It is visually configurable in the CGE editor.

    It’s like a TPicture in VCL — it doesn’t draw the image, but it has everything else to describe how to load and draw the image. It’s used by TCastleImageControl.Image, TCastleButtom.CustomBackgroundNormal, TCastleButtom.CustomBackgroundPressed etc.

  • There are a few X3D nodes to express images. The most important are

    • TImageTextureNode which is an image loaded from URL (set like MyImageTexture.SetUrl(['castle-data:/my_image.png']))

    • TPixelTextureNode which is an image defined by TCastleImage (set like MyPixelTexture.FdImage.Value := MyImage, remember that MyImage becomes "owned" by TPixelTextureNode).

    These nodes are used underneath when you load image into TCastleScene or TCastleImageTransform. We do not advise using these nodes directly,

TODO: There are too many classes above. In time, we hope to hide this complexity more, some of these classes should become internal (or not necessary at all).

6. Deprecated: load image directly in TCastleScene

You can load the image to TCastleScene, using the TCastleScene.Load method (or by setting TCastleScene.URL). While traditionally TCastleScene is used for "heavier" 3D and 2D assets, it is perfectly suitable to also just use it to render a trivial rectangle with a simple image. See CGE manual about loading and using scenes.

Under the hood, this method creates nodes to define a rectangle, and applies the image as a texture. The "manual" way of achieving the same is presented in the example code here.

This approach is deprecated now, as TCastleImageTransform is better.

6.1. Parameters when loading image to TCastleScene

By default we display an entire image. Alternatively, when loading the image to TCastleScene, you can use a special syntax with URL anchors to specify a subset of the image. That is, instead of

my_image.png

you can load

my_image.png#left:100,bottom:100,width:256,height:256

This will cut the appropriate subset of the image.

These are the parameters:

  • left

    Left coordinate of chosen rectangle (in image pixels)

  • bottom

    Bottom coordinate of chosen rectangle (in image pixels)

  • width

    Width of chosen rectangle (in image pixels)

  • height

    Height of chosen rectangle (in image pixels)

All the parameters are integers (we have not yet found a use-case to make them floats, but please tell us if you have such use-case).

Note that if you specify area that is too large (outside of the actual image area), the excessive pixels will show the clamped image border (the image is simply rendered as a texture with repeat=FALSE).


To improve this documentation just edit the source of this page in AsciiDoctor (simple wiki-like syntax) and create a pull request to Castle Game Engine WWW (cge-www) repository.