- Your own mixing is using loop mixing and it takes a little time to mix in the CPU layer, hope to provide suggestions Thank you very much
function BlendBytes(const Dest, Source, Opacity: Byte): Byte; {$ifdef SUPPORTS_INLINE} inline; {$endif}
var
W: Word;
begin
W := byte(Dest) * (255 - Opacity) div 255 + byte(Source) * Opacity div 255;
if W > 255 then W := 255;
Result := W;
end;
function AddBytes(const Dest, Source, Opacity: Byte): Byte; {$ifdef SUPPORTS_INLINE} inline; {$endif}
var
W: Word;
begin
W := Dest + Word(Source) * Opacity div 255;
if W > 255 then W := 255;
Result := W;
end;
function AddBytesPremultiplied(const Dest, Source: Byte): Byte; {$ifdef SUPPORTS_INLINE} inline; {$endif}
var
W: Word;
begin
W := Dest + Source;
if W > 255 then W := 255;
Result := W;
end;
function MultiplyBytes(const Dest, Source: Byte): Byte; {$ifdef SUPPORTS_INLINE} inline; {$endif}
var
W: Word;
begin
W := Dest * Word(Source) div 255;
if W > 255 then W := 255;
Result := W;
end;
Indeed there is a faster and more recommended method.
The idea is to not use CPU-based drawing methods in CastleImages
, like TCastleImage.DrawFrom
and TCastleImage.DrawTo
. As you found, this approach uses a loop in CPU, so it’s never really going to be efficient for large images.
The more recommended approach is to use TDrawableImage
and draw there. Like TDrawableImage.DrawFrom
. Or, more generally, do any drawing you want between TDrawableImage.RenderToImageBegin
and TDrawableImage.RenderToImageEnd
– this way you can draw other images, or any other UI controls, even 3D stuff, inside an image. This approach is:
-
Fully GPU-accelerated (underneath we use OpenGL(ES) FBOs to draw into a texture).
-
More powerful, as you can really draw anything.
-
It also works just differently. You rely on OpenGL(ES) provided blending methods, see TDrawableImage.Alpha
, TDrawableImage.BlendingSourceFactor
, TDrawableImage.BlendingDestinationFactor
.
See examples/images_videos/draw_images_on_gpu/draw_images_on_gpu.dpr
for example.
In the long-term, we plan to either deprecate existing CPU-based drawing methods on TCastleImage
or reimplement them on top of TDrawableImage
.
TODO: I should document it better, so that others don’t fall into this trap. Maybe we should deprecate existing CPU-based drawing methods sooner. We should also have more examples of this.