unit DTextureHandle;

{$DEFINE DENG_USE_DRAW_OPENGL}

{$MODE FPC}
{$MODESWITCH ADVANCEDRECORDS}
{$MODESWITCH DEFAULTPARAMETERS}
{$MODESWITCH OUT}
{$MODESWITCH RESULT}

interface

uses
  {$IFDEF DENG_USE_DRAW_OPENGL}{$IFDEF ANDROID}GLES{$ELSE}GL, GLU{$ENDIF}{$ENDIF},
  dvector2i;

type
TTexture2DHandle = packed record
  {$IFDEF DENG_USE_DRAW_OPENGL}Id: GLuint;{$ENDIF}
public
  procedure Init; inline;
  procedure Done; inline;
  procedure UploadRGBATexture(Width, Height: PtrUInt;
                              Data: Pointer);
  procedure Bind; inline;
  procedure Unbind; inline;
end;

implementation

const
  MipMap: Boolean = True;

procedure TTexture2DHandle.Init;
begin
  glGenTextures(1, @Id);
  glBindTexture(GL_TEXTURE_2D, Id);

  //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // set 1-byte alignment

  // set texture to repeat mode
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

  if MipMap then begin
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    {$IFDEF ANDROID}
    //glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
    {$ENDIF}
  end else begin
    // TODO support switching off filtering
    // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  end;
  //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 2.0);
  glDisable(GL_LIGHTING);
  glDisable(GL_DEPTH_TEST);
  glDisable(GL_DITHER);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

  glBindTexture(GL_TEXTURE_2D, 0);
end;

procedure TTexture2DHandle.Done;
begin
end;

procedure TTexture2DHandle.UploadRGBATexture(Width, Height: PtrUInt;
                            Data: Pointer);
begin
  glBindTexture(GL_TEXTURE_2D, Id);
  {$IFNDEF ANDROID}
  if MipMap then begin
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA,
                      Width, Height, GL_RGBA,
                      GL_UNSIGNED_BYTE, Data);
  end else
  {$ENDIF}
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                 Width, Height, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, Data);
  glBindTexture(GL_TEXTURE_2D, 0);
end;

procedure TTexture2DHandle.Bind;
begin
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, Id);
end;

procedure TTexture2DHandle.Unbind;
begin
  glDisable(GL_TEXTURE_2D);
end;

end.
