Unit CastleImages
Description
Loading, saving, and processing of images (TEncodedImage, TCastleImage and other classes). This unit deals with images, stored in normal memory (not on GPU). Images can be loaded and saved from/to various formats and processed in a lot of ways. For example you can resize images, you can draw one image on another, convert to grayscale and so on.
The "image" as understood by this unit may have some interesting features useful with modern GPUs: image data may be compressed for GPU (TGPUCompressedImage), image data may be 3D (every image has Depth
, in addition to Width
and Height
).
The most important class here is TCastleImage. It represents an image as a simple uncompressed array of pixels. Descendants of TCastleImage define what exactly is a "pixel". We have 8-bit color images (TRGBAlphaImage, TRGBImage, TGrayscaleAlphaImage and TGrayscaleImage). We also have an image with floating-point precision and range: TRGBFloatImage.
There is also a more abstract image class TEncodedImage, representing either uncompressed image (TCastleImage) or an image with data compressed for GPU (TGPUCompressedImage).
When reading and writing image files, we understand various image formats. See castle-view-image documentation ( https://castle-engine.io/castle-view-image.php ) for a current list of supported image formats.
The basic loading and saving procedures are LoadImage and SaveImage. Example usage:
var Image: TCastleImage; begin Image := LoadImage('image.png'); { scale the image to be 2x smaller } Image.Resize(Image.Width div 2, Image.Height div 2); SaveImage(Image, 'newimage.png'); end;
This unit is not dependent on OpenGL or any other rendering library. See CastleGLImages for OpenGL image operations (for textures and others).
Uses
- SysUtils
- Classes
- Math
- Generics.Collections
- FPImage
- FPReadPCX
- FPReadGIF
- FPReadPSD
- FPReadTGA
- FPReadTiff
- FPReadXPM
- FPReadBMP
- FPWriteBMP
- FPReadJPEG
- FPWriteJPEG
- FPReadPNM
- FPWritePNM
- FPReadPNG
- FPWritePNG
- CastleInternalPng
- CastleUtils
- CastleVectors
- CastleRectangles
- CastleFileFilters
- CastleClassUtils
- CastleColors
Overview
Classes, Interfaces, Objects and Records
Name | Description |
---|---|
Class EImagePosOutOfRange |
Raised by TCastleImage.MakeExtracted when coordinates on image are wrong. |
Class EImageLerpError |
|
Class EImageLerpInvalidClasses |
|
Class EImageLerpDifferentSizes |
|
Class EImageAssignmentError |
|
Class EImageCannotConvertFpImage |
|
Class EImageDrawError |
|
Class TEncodedImage |
Abstract class for an image with unspecified, possibly compressed, memory format. |
Class TCastleImage |
An abstract class representing image as a simple array of pixels. |
Class TGPUCompressedImage |
Image compressed using one of the GPU texture compression algorithms. |
Class ECannotDecompressTexture |
|
Class TRGBImage |
Image with pixel represented as a TVector3Byte (red, green, blue). |
Class TRGBAlphaImage |
|
Class TRGBFloatImage |
Image with high-precision RGB colors encoded as 3 floats. |
Class TGrayscaleImage |
Grayscale image. |
Class TGrayscaleAlphaImage |
Grayscale image with an alpha channel. |
Class EImageLoadError |
|
Class EInvalidImageFormat |
|
Class EUnableToLoadImage |
|
Class EImageFormatNotSupported |
|
Class EImageSaveError |
Raised by SaveImage when it's not possible to save image. |
Object TTextureCompressionInfo |
Functions and Procedures
function EqualRGB(const Color1, Color2: TVector3Byte; Tolerance: Byte): boolean; |
function InImageClasses(ImageClass: TEncodedImageClass; const ImageClasses: array of TEncodedImageClass): boolean; overload; |
function InImageClasses(Image: TEncodedImage; const ImageClasses: array of TEncodedImageClass): boolean; overload; |
function ImageClassesEqual(const Ar1, Ar2: array of TEncodedImageClass): boolean; |
function Vector3ToRGBE(const v: TVector3): TVector4Byte; deprecated 'RGBE compression should be internal in CGE or Vampyre'; |
function VectorRGBETo3Single(const v: TVector4Byte): TVector3; deprecated 'RGBE compression should be internal in CGE or Vampyre'; |
function IsImageMimeType(const MimeType: string; const OnlyLoadable, OnlySaveable: boolean): boolean; |
function ListImageExtsLong(OnlyLoadable, OnlySaveable: boolean; const LinePrefix: string): string; |
function ListImageExtsShort(OnlyLoadable, OnlySaveable: boolean): string; |
function ImageExtToMimeType(Ext: string): string; deprecated 'use URIMimeType'; |
function LoadImage(Stream: TStream; const MimeType: string; const AllowedImageClasses: array of TEncodedImageClass) :TCastleImage; overload; |
function LoadImage(const URL: string): TCastleImage; overload; |
function LoadImage(const URL: string; const AllowedImageClasses: array of TEncodedImageClass) :TCastleImage; overload; |
function LoadImage(const URL: string; const AllowedImageClasses: array of TEncodedImageClass; const ResizeWidth, ResizeHeight: Cardinal; const Interpolation: TResizeInterpolation = riBilinear; const Options: TLoadImageOptions = []): TCastleImage; overload; |
function LoadEncodedImage(Stream: TStream; const MimeType: string; const AllowedImageClasses: array of TEncodedImageClass; const Options: TLoadImageOptions = []) :TEncodedImage; overload; |
function LoadEncodedImage(const URL: string; const Options: TLoadImageOptions = []): TEncodedImage; overload; |
function LoadEncodedImage(URL: string; const AllowedImageClasses: array of TEncodedImageClass; const Options: TLoadImageOptions = []) :TEncodedImage; overload; |
procedure SaveImage(const Img: TEncodedImage; const MimeType: string; Stream: TStream); overload; |
procedure SaveImage(const Img: TEncodedImage; const URL: string); overload; |
function ImageClassBestForSavingToFormat(const URL: string): TCastleImageClass; deprecated 'implement this logic yourself; the fact that this may return TRGBImage, disregarging possible alpha, is misleading'; |
procedure AlphaMaxVar(var A: TAlphaChannel; const B: TAlphaChannel); |
function StringToAlpha(S: string; var WarningDone: boolean): TAutoAlphaChannel; |
function TextureCompressionToString(const TextureCompression: TTextureCompression): string; |
function StringToTextureCompression(const S: string): TTextureCompression; |
procedure AddLoadImageListener(const Event: TLoadImageEvent); |
procedure RemoveLoadImageListener(const Event: TLoadImageEvent); |
function ProcessImageUrl(const URL: string): string; |
Types
TAutoAlphaChannel = (...); |
TAlphaChannel = acNone .. acBlending; |
TResizeInterpolation = (...); |
TResizeInterpolationInternal = Low(TResizeInterpolation) .. riBilinear; |
TResizeInterpolationFpImage = Succ(riBilinear) .. High(TResizeInterpolation); |
TDrawMode = (...); |
TCastleImageList = specialize TObjectList<TCastleImage>; |
TEncodedImageList = specialize TObjectList<TEncodedImage>; |
TTextureCompression = (...); |
TTextureCompressions = set of TTextureCompression; |
TS3TCImage = TGPUCompressedImage deprecated; |
TDecompressTextureFunction = function (Image: TGPUCompressedImage): TCastleImage; |
TCastleImageClass = class of TCastleImage; |
TEncodedImageClass = class of TEncodedImage; |
TLoadImageOption = (...); |
TLoadImageOptions = set of TLoadImageOption; |
TLoadImageEvent = procedure (var ImageUrl: string) of object; |
Constants
acSimpleYesNo = acBlending deprecated 'use acTest'; |
acFullRange = acBlending deprecated 'use acBlending'; |
DefaultAlphaTolerance = 5; |
AlphaToString: array [TAutoAlphaChannel] of string =
('AUTO', 'NONE', 'TEST', 'BLENDING'); |
TextureCompressionInfo: array [TTextureCompression] of TTextureCompressionInfo =
( (Name: 'DXT1_RGB' ; RequiresPowerOf2: false; AlphaChannel: acNone ; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'DXT1_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acTest ; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'DXT3' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'DXT5' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'PVRTC1_4bpp_RGB' ; RequiresPowerOf2: true ; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC1_2bpp_RGB' ; RequiresPowerOf2: true ; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC1_4bpp_RGBA' ; RequiresPowerOf2: true ; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC1_2bpp_RGBA' ; RequiresPowerOf2: true ; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC2_4bpp' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC2_2bpp' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ATITC_RGB' ; RequiresPowerOf2: false; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ATITC_RGBA_ExplicitAlpha' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ATITC_RGBA_InterpolatedAlpha'; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ETC1' ; RequiresPowerOf2: true ; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.ktx'),
(Name: 'ASTC_4x4_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x4_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x6_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x6_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x8_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x6_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x8_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x10_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x10_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x12_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_4x4_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x4_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x6_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x6_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x8_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x6_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x8_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x10_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x10_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x12_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' )
); |
Variables
Description
Functions and Procedures
function EqualRGB(const Color1, Color2: TVector3Byte; Tolerance: Byte): boolean; |
Check if the two RGB colors are equal, ignoring small differences. All three color components may differ by at most Tolerance. When Tolerance is 0, this is a normal (exact) comparison. |
function InImageClasses(ImageClass: TEncodedImageClass; const ImageClasses: array of TEncodedImageClass): boolean; overload; |
Check is ImageClass one of the items in the ImageClasses array, or a descendant of one of them. |
function InImageClasses(Image: TEncodedImage; const ImageClasses: array of TEncodedImageClass): boolean; overload; |
Check is Image class one of the items in the ImageClasses array, or a descendant of one of them. This is a shortcut for |
function ImageClassesEqual(const Ar1, Ar2: array of TEncodedImageClass): boolean; |
Check if both arrays contain exactly the same classes in the same order. May be extended in the future to do better checks and return true also if both array contain the same classes but in different order, and one array may contain the same classes duplicated any times. So the intention is that you should treat both arrays as sets (i.e. order of elements is ignored). The problem is that this function should be lighting fast. As the main purpose of it is to use it in constructions like setting property values, e.g. if ImageClassesArraysEqual(Value, SomeProperty) then begin SomeProperty := Value; { ... do some lengthy operations to update new value of SomeProperty ... } end;
Doing smarter checks may cost us a little time. So for now this function returns
|
function Vector3ToRGBE(const v: TVector3): TVector4Byte; deprecated 'RGBE compression should be internal in CGE or Vampyre'; |
Warning: this symbol is deprecated: RGBE compression should be internal in CGE or Vampyre Encode RGB color as Red + Green + Blue + Exponent format. This allows you to encode high-precision colors in 4 bytes, see ifRGBE image format for pointers why this is useful. Each component of V (red, green, blue) must be from range [0, +infinity), not merely from [0, 1]. That is, V must have only nonnegative values. |
function VectorRGBETo3Single(const v: TVector4Byte): TVector3; deprecated 'RGBE compression should be internal in CGE or Vampyre'; |
Warning: this symbol is deprecated: RGBE compression should be internal in CGE or Vampyre Decode Red + Green + Blue + Exponent back into RGB (3 floats). |
function IsImageMimeType(const MimeType: string; const OnlyLoadable, OnlySaveable: boolean): boolean; |
Does this MIME type correspond to image. |
function ListImageExtsLong(OnlyLoadable, OnlySaveable: boolean; const LinePrefix: string): string; |
List available image file formats. This is basically for debug/info purposes, you can show this to user to let him know which formats are supported (and by which extensions they are recognized). Although almost always a better way to show this to user is just to use SaveImage_FileFilters with a save dialog like TCastleWindow.FileDialog, this shows file types in the open/save dialog, so it's most natural and convenient to user.
ListImageExtsShort writes all recognized extensions separated by comma (', '). |
function ListImageExtsShort(OnlyLoadable, OnlySaveable: boolean): string; |
function ImageExtToMimeType(Ext: string): string; deprecated 'use URIMimeType'; |
Warning: this symbol is deprecated: use URIMimeType Guess MIME type from image extension. Empty string if cannot guess. |
function LoadImage(Stream: TStream; const MimeType: string; const AllowedImageClasses: array of TEncodedImageClass) :TCastleImage; overload; |
The ultimate procedure to load an image from a file or URL. URL is downloaded using CastleDownload unit. As always, if you all you care about is loading normal files, then just pass a normal filename (absolute or relative to the current directory) as the URL parameter. Simple examples: { When you don't care what TCastleImage descendant you get: } Image := LoadImage('image.png'); { When you insist on getting TRGBImage, that is 8-bit color image without an alpha channel. } ImageRGB := LoadImage('image.png', [TRGBImage]) as TRGBImage;
Image file format may be given explicitly (overloaded version with Format parameter), or guessed based on URL extension (which can be given explicitly by TypeExt, or automatically calculated from full URL). For now, we cannot guess the file format based on file contents or MIME type (the latter case would be sensible for http URLs). AllowedImageClasses says what image classes are allowed. As a special case, AllowedImageClasses = [] is equivalent to AllowedImageClasses = [TCastleImage] which says that all TCastleImage descendants are allowed. Then this function will do everything it can to load any image into the best subclass of TCastleImage, losing as little image information it can. Example: consider you're loading a PNG file. Let's suppose you're loading it with AllowedImageClasses = []. Then you can get TGrayscaleImage, TGrayscaleAlphaImage, TRGBImage, TRGBAlphaImage, depending on whether PNG file is grayscale or not and has alpha or not. Now let's suppose you specified AllowedImageClasses = [TRGBImage]. If PNG file will not be grayscale and not have alpha channel, LoadImage will return TRGBImage descendant, as before. But if PNG fill *will* have alpha channel then LoadImage will simply ignore (strip) alpha channel and return you TRGBImage. Similar thing for grayscale: if image file was grayscale but you requested only TRGBImage, then grayscale may be "expanded" into full three-channel RGB. There can also happen reverse situation: you e.g. insist that AllowedImageClasses = [TRGBAlphaImage] but given PNG image does not have alpha channel. In this case LoadImage may add "dummy" alpha channel (everywhere equal to 1.0 or High(Byte)). Similar thing when you e.g. gave AllowedImageClasses = [TRGBFloatImage] but you're loading from PNG image. In this case you want float precision, but image file cannot offer it. So LoadImage can simply convert discreet values to appropriating floating point values. If at any point LoadImage will find that it's unable to satisfy AllowedImageClasses, it will raise EUnableToLoadImage.
Exceptions raised
See also |
function LoadImage(const URL: string): TCastleImage; overload; |
function LoadImage(const URL: string; const AllowedImageClasses: array of TEncodedImageClass) :TCastleImage; overload; |
function LoadImage(const URL: string; const AllowedImageClasses: array of TEncodedImageClass; const ResizeWidth, ResizeHeight: Cardinal; const Interpolation: TResizeInterpolation = riBilinear; const Options: TLoadImageOptions = []): TCastleImage; overload; |
function LoadEncodedImage(Stream: TStream; const MimeType: string; const AllowedImageClasses: array of TEncodedImageClass; const Options: TLoadImageOptions = []) :TEncodedImage; overload; |
Load image to TEncodedImage format. This allows loading image compressed with GPU, which is good for optimally loading it to GPU. However, the operations on GPU-compressed image are very limited, we generally cannot do much with GPU-compressed data except rendering it.
See also |
function LoadEncodedImage(const URL: string; const Options: TLoadImageOptions = []): TEncodedImage; overload; |
function LoadEncodedImage(URL: string; const AllowedImageClasses: array of TEncodedImageClass; const Options: TLoadImageOptions = []) :TEncodedImage; overload; |
procedure SaveImage(const Img: TEncodedImage; const MimeType: string; Stream: TStream); overload; |
Save image to a file. Takes URL as parameter, you can give File format is determined by looking at URL (guessing MIME type using URIMimeType), or given explicitly as MimeType, or just given explicitly as Format parameter. Image class does not affect the created image file format, on the assumption that the "memory format" of the image (what TCastleImage descendant is used) can be orthogonal to the actual "file format" used to save this file. Tries to write the image preserving it as closely as possible in this image format. When it's not possible, according conversions may be done: floating point precision of TRGBFloatImage may be lost (if saving to any file format besides RGBE file, although saving to OpenEXR may also preserve it once implemented), alpha channel may be lost, grayscale may be expanded and such. Although not absolutely all conversions are implemented for now. You can be sure that all image formats (that allow any saving at all) can be saved from TRGBImage. Also TRGBFloatImage can be saved to RGBE file. Also PNG format supports full collection (grayscale/rgb, alpha/no alpha are all perfectly possible in PNG file; and TRGBFloatImage will be just converted to 8-bit RGB before saving to PNG).
Exceptions raised
|
procedure SaveImage(const Img: TEncodedImage; const URL: string); overload; |
function ImageClassBestForSavingToFormat(const URL: string): TCastleImageClass; deprecated 'implement this logic yourself; the fact that this may return TRGBImage, disregarging possible alpha, is misleading'; |
Warning: this symbol is deprecated: implement this logic yourself; the fact that this may return TRGBImage, disregarging possible alpha, is misleading Choose TCastleImage descendant best matching for this image file format. The only purpose of this for now is to pick TRGBFloatImage for RGBE files, chooses TRGBImage for anything else. For the overloaded version with URL, file format is determined by guessing based on file extension. |
procedure AlphaMaxVar(var A: TAlphaChannel; const B: TAlphaChannel); |
Maximum alpha channel type. Chooses "full range" if anything is "full range", otherwise choose "simple yes/no" if anything is "simple yes/no", otherwise returns "no alpha channel". |
function StringToAlpha(S: string; var WarningDone: boolean): TAutoAlphaChannel; |
function TextureCompressionToString(const TextureCompression: TTextureCompression): string; |
Convert TTextureCompression enum to string. |
function StringToTextureCompression(const S: string): TTextureCompression; |
Convert string to TTextureCompression enum. Possible values correspond to names listed in TextureCompressionInfo array, they are also equal to enum Pascal names without leading "tc". Compares given strig ignoring the case. Exceptions raised
|
procedure AddLoadImageListener(const Event: TLoadImageEvent); |
All image URLs are processed by this event before loading. This allows to globally modify / observe your images paths, e.g. to use GPU compressed alternative versions. The URL processing is automatically used by all image loaders. This includes LoadImage, LoadEncodedImage and (internal) The URL processing is automatically registered by MaterialProperties to automatically use GPU compressed textures. See https://castle-engine.io/creating_data_material_properties.php . You can also use it yourself, instead or in addition to MaterialProperties processing. An example: To work on any GPU, you want to have various versions of your textures (uncompressed, and also compressed with various GPU algorithms) in your data. Use this procedure to redirect all image loading to use your compressed versions, when they are supported by the GPU. By doing it like this we capture all kinds of image loading — from TDrawableImage, from TCastleScene and so on. uses ..., CastleURIUtils, CastleGLUtils, CastleLog, CastleStringUtils, CastleFilesUtils; procedure TTextureUtils.GPUTextureAlternative(var ImageUrl: string); begin if IsPrefix('castle-data:/animation/dragon/', ImageUrl) then begin if GLFeatures = nil then WritelnWarning('TextureCompression', 'Cannot determine whether to use GPU compressed version for ' + ImageUrl + ' because the image is loaded before GPU capabilities are known') else if tcPvrtc1_4bpp_RGBA in GLFeatures.TextureCompression then begin ImageUrl := ExtractURIPath(ImageUrl) + 'compressed/pvrtc1_4bpp_rgba/' + ExtractURIName(ImageUrl) + '.dds'; WritelnLog('TextureCompression', 'Using compressed alternative ' + ImageUrl); end; end; end; initialization AddLoadImageListener(@TTextureUtils(nil).GPUTextureAlternative); finalization RemoveLoadImageListener(@GPUTextureAlternative); end. |
procedure RemoveLoadImageListener(const Event: TLoadImageEvent); |
Remove listener added by AddLoadImageListener. |
function ProcessImageUrl(const URL: string): string; |
Process URL through events registered by AddLoadImageListener. This is used internally by the engine. |
Types
TAutoAlphaChannel = (...); |
How is the alpha channel of an image treated. Values
|
TAlphaChannel = acNone .. acBlending; |
See TCastleImage.AlphaChannel. |
TResizeInterpolation = (...); |
Resize interpolation modes, see TCastleImage.Resize and TCastleImage.MakeResized. Values
|
TResizeInterpolationInternal = Low(TResizeInterpolation) .. riBilinear; |
TResizeInterpolationFpImage = Succ(riBilinear) .. High(TResizeInterpolation); |
TDrawMode = (...); |
Drawing mode used by image-on-image drawing methods (TCastleImage.DrawFrom and TCastleImage.DrawTo). Values
|
TCastleImageList = specialize TObjectList<TCastleImage>; |
TEncodedImageList = specialize TObjectList<TEncodedImage>; |
TTextureCompression = (...); |
Possible compression of textures for GPU. The compressed texture formats may be automatically created for you by CGE, see https://castle-engine.io/creating_data_auto_generated_textures.php . Values
|
TTextureCompressions = set of TTextureCompression; |
TS3TCImage = TGPUCompressedImage deprecated; |
Warning: this symbol is deprecated. Deprecated alias for TGPUCompressedImage |
TDecompressTextureFunction = function (Image: TGPUCompressedImage): TCastleImage; |
TCastleImageClass = class of TCastleImage; |
TEncodedImageClass = class of TEncodedImage; |
TLoadImageOption = (...); |
Values
|
TLoadImageOptions = set of TLoadImageOption; |
TLoadImageEvent = procedure (var ImageUrl: string) of object; |
Listener type for AddLoadImageListener. |
Constants
acSimpleYesNo = acBlending deprecated 'use acTest'; |
Warning: this symbol is deprecated: use acTest |
acFullRange = acBlending deprecated 'use acBlending'; |
Warning: this symbol is deprecated: use acBlending |
DefaultAlphaTolerance = 5; |
Default parameters for TEncodedImage.AlphaChannel, decide how to detect textures alpha channel. |
AlphaToString: array [TAutoAlphaChannel] of string =
('AUTO', 'NONE', 'TEST', 'BLENDING'); |
TextureCompressionInfo: array [TTextureCompression] of TTextureCompressionInfo =
( (Name: 'DXT1_RGB' ; RequiresPowerOf2: false; AlphaChannel: acNone ; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'DXT1_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acTest ; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'DXT3' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'DXT5' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: false; FileExtension: '.dds'),
(Name: 'PVRTC1_4bpp_RGB' ; RequiresPowerOf2: true ; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC1_2bpp_RGB' ; RequiresPowerOf2: true ; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC1_4bpp_RGBA' ; RequiresPowerOf2: true ; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC1_2bpp_RGBA' ; RequiresPowerOf2: true ; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC2_4bpp' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'PVRTC2_2bpp' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ATITC_RGB' ; RequiresPowerOf2: false; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ATITC_RGBA_ExplicitAlpha' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ATITC_RGBA_InterpolatedAlpha'; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.dds'),
(Name: 'ETC1' ; RequiresPowerOf2: true ; AlphaChannel: acNone ; DDSFlipped: true; FileExtension: '.ktx'),
(Name: 'ASTC_4x4_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x4_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x6_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x6_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x8_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x5_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x6_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x8_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x10_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x10_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x12_RGBA' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_4x4_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x4_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_5x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_6x6_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x6_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_8x8_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x5_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x6_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x8_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_10x10_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x10_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' ),
(Name: 'ASTC_12x12_SRGB8_ALPHA8' ; RequiresPowerOf2: false; AlphaChannel: acBlending; DDSFlipped: true; FileExtension: '.ktx' )
); |
Variables
DecompressTexture: TDecompressTextureFunction; |
Assign here texture decompression function that is available. This way the "decompressor" is pluggable, which means that you can even use OpenGL to decompress textures, if you're going to load images while some OpenGL context is active. |
LoadImage_FileFilters: TFileFilterList; |
File filters if you want to choose a file that can be loaded/saved by appropriate functions from Images unit. These objects should be treated as read-only outside this unit. Initialization / finalization of this unit automatically take care of them. |
SaveImage_FileFilters: TFileFilterList; |
SupportedTextureCompressionKnown: boolean; |
Is the value of SupportedTextureCompression determined by the renderer (like OpenGL context) parameters. |
SupportedTextureCompression: TTextureCompressions; |
Which texture compression values are supported by the renderer (like OpenGL context). |
Generated by PasDoc 0.16.0.