Fun With 3D: Apply A Texture To A GPU Shader With Delphi FireMonkey
February 28, 2021 By Muminjon
We have been exploring shader programming in Delphi FireMonkey. In the Для просмотра ссылки Войдиили Зарегистрируйся, we have learned the fundamentals of computer graphics and prepared the development environment. And created a simple demo application that just renders every pixel using a blue color.
So, Для просмотра ссылки Войдиили Зарегистрируйся, we have applied a custom color to the GPU shader. And made several additions to the main TCustomMaterialClass.
Now, it is time to apply a texture to the 3D object instead of using a single color. What is a texture? A texture is a bitmap that lives on the GPU.

To make it happen, we need to do some additional modifications to the Vertex and Pixel shaders. Moreover, on the Delphi side, the material is updated to reflect the new shaders
The material source controls the image bitmap. This bitmap is of type TTextureBitmap, which is a special kind of bitmap that is backed by a texture on the GPU. We connect an OnChange event handler to it so we can update the underlying material when the bitmap changes.
And the result is here:

February 28, 2021 By Muminjon
We have been exploring shader programming in Delphi FireMonkey. In the Для просмотра ссылки Войди
So, Для просмотра ссылки Войди
Now, it is time to apply a texture to the 3D object instead of using a single color. What is a texture? A texture is a bitmap that lives on the GPU.

To make it happen, we need to do some additional modifications to the Vertex and Pixel shaders. Moreover, on the Delphi side, the material is updated to reflect the new shaders
Код:
{$R *.fmx}
{$R '..TexturesTextures.res'}
procedure TFormMain.Form3DCreate(Sender: TObject);
begin
LabelBackend.Text := 'Backend: ' + Context.ClassName;
FMaterialSource := TImageMaterialSource.Create(Self);
var Image := LoadImage('LENA');
try
FMaterialSource.Image := Image;
finally
Image.Free;
end;
Plane.MaterialSource := FMaterialSource;
end;
procedure TFormMain.Form3DRender(Sender: TObject; Context: TContext3D);
begin
{$IF Defined(MACOS) and not Defined(IOS)}
{ Workaround for https://quality.embarcadero.com/browse/RSP-32121 }
if (GlobalUseMetal) then
Context.FillRect(Point3D(-Width, -Height, 100), Point3D(Width, Height, 100), 1, Color);
{$ENDIF}
end;
class function TFormMain.LoadImage(const AResource: String): TBitmap;
begin
Result := TBitmap.Create;
var Stream := TResourceStream.Create(HInstance, AResource, RT_RCDATA);
try
Result.LoadFromStream(Stream);
finally
Stream.Free;
end;
end;
And the result is here:
