I am trying to create a pinch-to-zoom TImage function and want to disable interpolation when resizing a firemonkey TImage control (and it needs to work across multiple devices).
Setting the TImage's "DisableInterpolation" to "True" doesn't work on Windows if "GlobalUseGPUCanvas" is set to "True" or on Android (which I believe always uses a GPU canvas).
This is easily reproducible with Embarcadero's Image Zoom sample by setting "GlobalUseGPUCanvas" to "True" in the project's DPR file and checking "DisableInterpolation" on the form's TImage:
http://docwiki.embarcadero.com/CodeExamples/Tokyo/en/FMX.ImageZoom_Sample
Is there a way to truly disable interpolation with a GPU canvas or somehow set the GPU resampler to use nearest neighbor instead of the default algorithm (bicubic? bilinear?)?
Instead of using a TImage, you can paint directly the image on the canvas using a Texture
When you will create the texture you can assign it with GL_NEAREST instead of GL_LINEAR (IE: Texture.MagFilter)
Below the delphi function that will create the texture (for reference) :
class procedure TCustomContextOpenGL.DoInitializeTexture(const Texture: TTexture);
var
Tex: GLuint;
begin
if Valid then
begin
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, @Tex);
glBindTexture(GL_TEXTURE_2D, Tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
case Texture.MagFilter of
TTextureFilter.Nearest: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
TTextureFilter.Linear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
end;
if TTextureStyle.MipMaps in Texture.Style then
begin
case Texture.MinFilter of
TTextureFilter.Nearest: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
TTextureFilter.Linear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
end;
end
else
begin
case Texture.MinFilter of
TTextureFilter.Nearest: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
TTextureFilter.Linear: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
end;
end;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Texture.Width, Texture.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nil);
glBindTexture(GL_TEXTURE_2D, 0);
ITextureAccess(Texture).Handle := Tex;
if (GLHasAnyErrors()) then
RaiseContextExceptionFmt(@SCannotCreateTexture, [ClassName]);
end;
end;
来源:https://stackoverflow.com/questions/49302477/how-can-i-disable-interpolation-on-a-gpu-canvas-fmx-timage-or-set-interpolation