How can I disable interpolation on a GPU canvas FMX TImage or set interpolation to “nearest neighbor”

强颜欢笑 提交于 2019-12-02 03:25:31

问题


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?)?


回答1:


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!