Integration with Vampyre Imaging Library, new example image_display to test image loading speed and format support

Castle Game Engine example - image_display
examples/images_videos/image_display speed test

We now can use Vampyre Imaging Library to load and save images in various formats. After some testing, I’m very impressed with how easy it is to use Vampyre, and we are already:

  • Using it with Delphi by default (no need to do anything).

  • Vampyre source code is bundled with CGE, so you don’t need to set up / download anything extra. Vampyre is just automatically used under the hood by CGE to load/save some image formats. It is in src/vampyre_imaginglib of CGE, and CGE build tool automatically passes paths to it when building CGE applications.

For FPC:

I have also tested using Vampyre with FPC, and our build tool already contains the necessary paths. Every FPC user of CGE can just define USE_VAMPYRE_IMAGING symbol to use it. There are a number of ways to define it, the advised is to define it in CastleEngineManifest.xml, like here.

In the near future we will likely just use Vampyre with FPC by default, so the need to define USE_VAMPYRE_IMAGING is just a temporary thing. We just need more testing, with various FPC versions and platforms (see lower for examples).

In the more distant future, we may also remove the code to use FpImage with FPC, even as a fallback, since Vampyre seems just better than FpImage in every way.

Advantages of using Vampyre:

  • Vampyre Imaging Library is cross-platform.

  • Works with both FPC and Delphi. Unlike FPC-specific FpImage or Delphi-specific PngImage (and other stuff in Delphi Vcl.Imaging).

  • Supports many image formats, both reading and writing. It even supports a bit more than FpImage, e.g. we added now loading TIFF, JPEG 2000, XPM without any extra tools.

  • It has really good and simple API. Almost entire CGE + Vampyre integration code is in this include file.

  • It is well documented on https://imaginglib.sourceforge.io/ , with manual and reference.

  • It is efficient. Unlike e.g. FpImage from FPC — which turned out to be very inefficient when it comes e.g. to PNG image reading (despite our efforts to make it fast, using TFPCompactImgRGBA8Bit, using format detection in InternalDetectClassPNG).

  • It doesn’t require any external libraries. Unlike LibPng approach in CGE.

Help us test!

I’m eager to hear about your tests of Vampyre on various platforms, with various compilers, with your images.

You can use e.g. our castle-view-image (image viewer) for easy testing. It compiles now with both FPC and Delphi.

You can also use a new cross-platform example: examples/images_videos/image_display . This loads the image in a number of formats (making sure we support them all), and can perform speed testing – to compare loading times of various libraries, so you can verify the speed of Vampyre vs FpImage vs LibPng yourself.

What about LibPng, DDS, KTX?

Vampyre is still a bit slower for reading PNGs than LibPng (about 2x slower on Linux/x86_64, which is anyway better than FpImage that was 4x slower), so we will keep relying on LibPng for PNG. Still, Vampyre is a much better fallback than FpImage when LibPng will be missing.

We may rely on Vampyre for some formats that are currently built-in in CGE code, too. This includes BMP, RGBE, PPM.

We will likely keep our own CGE code for loading DDS and KTX though. (Vampyre can handle DDS. But we want DDS and KTX to go though a similar code path in CGE, and we want to efficiently use all their features — cubemaps, texture compression, 3d textures, mipmaps.)

1 Like

While i “traditionally” used GraphicEx for formats and Graphics32 for transparent 2D, i heard Vampyre was a strong competitor.

That said

E.g. it is necessary for JPG support in Delphi.

???

XE2 Delphi support JPEG and PNG out of the box, actually VLC.jpeg i think was already there in Delphi 5 in 1999


I wonder how having local copy would work long term… In my experience separating yourself from upstream changes history makes it harder long-term, if you would need to co-develop that library, at least to find and fix bugs in it. One time convenience, sure… But maybe you could just add dependency from GCE’s packages to Vampyre’s package.

I didn’t mean that JPEG or PNG support without Vampyre is impossible for Delphi. I meant that, in CGE, using Vampyre is now the only implemented way to support JPEG.

As for Vcl.Imaging.Jpeg from Delphi Vcl.Imaging - RAD Studio API Documentation : While it is indeed coming with Delphi out-of-the-box and allows to use JPG with TGraphic and rest of VCL, it isn’t useful in CGE. There’s no way to extract image data efficiently, without going through TGraphic drawing routines.

This is unlike Vcl.Imaging.PngImage, which does allow to extract raw image contents, and we implement support for it in CGE for now, as a fallback if you deactivate Vampyre. (I said “right now”, because we may remove this fallback at some point – as Vampyre works great, we may just rely on it even more in the future.)

People get CGE code in various ways, for Lazarus, for Delphi, using zip, using GIT from GitHub, using OPM… And more ways will come. Like Delphi GetIt and Delphinus. So bundling Vampyre inside CGE is just the most reliable way that doesn’t introduce headaches / additional steps for some workflows.

As for synchronizing with Vampyre upstream: that’s true, this is a concern. Let’s just see how active the upstream of Vampyre will be and how much effort will the synchronization cost. The synchronization right now can be done with a script, and if needed we can just tell Jenkins in the future to do it (and test it) automatically and regularly.