Geneartion of cycled background texture with TDrawableImage

Good day!
I use TDrawableImage for procedural generation of tiled textures. You showed me this method in my previous topic:

For now I want to make cycled texture for imitation of 360-degree observe in 2D Viewport. And, when background texture is generated, I want slice it at two parts for make two cycled scenes.
As I understand, DrawFrom of TCastleImage have properties ti do it. But I don’t see possibility to do it with DrawFrom of TDrawableImage
My algorithm is:

...
Canv := TDrawableImage.Create(Tiles.TileW * Ints.Count, 1024, TRGBAlphaImage, True);

// tile texture generation...

DrawblImg := TDrawableImage.Create(Trunc(Canv.Width/2), 1024, TRGBAlphaImage, True);
DrawblImg.DrawFrom(Canv,
             FloatRectangle(0, 0, Canv.Width, Canv.Height),
             Canv.FloatRect);
FinalImage := DrawblImg.GetContents(TRGBAlphaImage);
Result.NorthWest.LoadFromImage(FinalImage, True);

// Result is class for cycled 2D terrain, 
// NorthWest and SouthEast fields - modified TCastleImageTransform's

In this code I load left part (“north” and “west” of the my landscape) to result image.
But I can’t do same thing for right part with “south” and “east”.
So… How to slice TDrawableImage at two part for drawing in different scenes?

P.S. for now my generation algorithm became more complex and generation of NorthWest and SouthEast parts separately seems little difficult, because they depend on each other…

I understand you wanted to ask “possibility to do it with DrawFrom of TDrawableImage” ? I’ll answer assuming that “yes”.

The TDrawableImage.DrawFrom allows to specify any subset of the source image using the SourceRect,

procedure TDrawableImage.DrawFrom(const SourceImage: TDrawableImage;
  const DestinationRect, SourceRect: TFloatRectangle);

The SourceRect specifies which portion of the source to take – any origin, any size.

For example, this would render 4x the part of TestImage that starts at (100,100) and has size (150,150):

  function CreateDrawableImage: TDrawableImage;
  var
    TestImage: TDrawableImage;
    I: Integer;
  begin
    Result := TDrawableImage.Create(1024, 1024, TRGBImage, true);
    Result.RenderToImageBegin;
    RenderContext.Clear([cbColor], Yellow);
    Result.RenderToImageEnd;
    TestImage := TDrawableImage.Create('castle-data:/test_texture.png');
    try
      for I := 0 to 3 do
        Result.DrawFrom(TestImage,
          // destination rectangle (origin and size in target, i.e. in Result)
          FloatRectangle(100, 100 + I * 200, 200, 200),
          // source rectangle (origin and size in source, i.e. in TestImage)
          FloatRectangle(100, 100, 150, 150));
    finally FreeAndNil(TestImage); end;
  end;

You can test above by using it in image_generate_and_use example in gameviewmain.pas instead of the current CreateDrawableImage.

BTW: I just noticed that the feature TCastleImageTransform.LoadFromImage was temporarily broken (I broke it when implementing another TCastleImageTransform feature requested in this thread, https://forum.castle-engine.io/t/solved-bug-with-shadows-on-tcastleimagetransform/ ). Now it’s all fixed, naturally, with both features working :slight_smile: If you want to upgrade CGE, be sure to either take sources from GitHub or wait until commit titled “Fix TCastleImageTransform.LoadFromImage…” is no longer visible on this page, it means that it is part of downloads.

1 Like

Yes, it was mistake, what I saw too late :face_without_mouth:

I was wrong here, with FloatRectangle in DrawFrom. As result, I got empty or stretched textures… Now I see, thanks!

1 Like