unit TextureCompression;

interface

uses Windows, SysUtils, GL, GLu, GLext, WGLext, GLtools, Textures, Images;

procedure CompressedFormat(tex: TTexture; fmt: cardinal);
function CompressedImageSize(tex: TTexture): cardinal;
procedure CompressedImage1D(tex: TTexture; img: TCompressedImage); overload;
procedure CompressedImage2D(tex: TTexture; img: TCompressedImage); overload;
procedure CompressedImage3D(tex: TTexture; img: TCompressedImage); overload;
function CompressedImage1D(tex: TTexture): TCompressedImage; overload;
function CompressedImage2D(tex: TTexture): TCompressedImage; overload;
function CompressedImage3D(tex: TTexture): TCompressedImage; overload;

implementation

var
  GL_ARB_texture_compression_loaded: boolean = false;

procedure Load_TC;
begin
  if not GL_ARB_texture_compression_loaded then
  begin
    if not glext_ExtensionSupported('GL_ARB_texture_compression') or
       not Load_GL_ARB_texture_compression then
         raise Exception.Create('GL_ARB_texture_compression required!');
    GL_ARB_texture_compression_loaded := true;
  end;
end;

procedure CompressedFormat;
begin
  Load_TC;
  tex.InternalFormat := fmt;
end;

function CompressedImageSize;
begin
  Load_TC;
  result := tex.Parameteri(GL_TEXTURE_COMPRESSED_IMAGE_SIZE);
end;

procedure CompressedImage1D(tex: TTexture; img: TCompressedImage);
begin
  Load_TC;
  tex.Bind;
  glCompressedTexImage1DARB(tex.Target, 0, tex.InternalFormat,
    img.Width, 0, img.DataSize, img.Data);
end;

procedure CompressedImage2D(tex: TTexture; img: TCompressedImage);
begin
  Load_TC;
  tex.Bind;
  glCompressedTexImage2DARB(tex.Target, 0, tex.InternalFormat,
    img.Width, img.Height, 0, img.DataSize, img.Data);
end;

procedure CompressedImage3D(tex: TTexture; img: TCompressedImage);
begin
  Load_TC;
  tex.Bind;
  glCompressedTexImage3DARB(tex.Target, 0, tex.InternalFormat,
    img.Width, img.Height, img.Depth, 0, img.DataSize, img.Data);
end;

function CompressedImage1D(tex: TTexture): TCompressedImage; overload;
begin
  Load_TC;
  tex.Bind;
  result := TCompressedImage.Create(tex.Width, 1, 1,
              tex.BytesPerPel * 8, CompressedImageSize(tex));
  glGetCompressedTexImageARB(tex.Target, 0, result.Data);
end;

function CompressedImage2D(tex: TTexture): TCompressedImage; overload;
begin
  Load_TC;
  tex.Bind;
  result := TCompressedImage.Create(tex.Width, tex.Height, 1,
              tex.BytesPerPel * 8, CompressedImageSize(tex));
  glGetCompressedTexImageARB(tex.Target, 0, result.Data);
end;

function CompressedImage3D(tex: TTexture): TCompressedImage; overload;
begin
  Load_TC;
  tex.Bind;
  result := TCompressedImage.Create(tex.Width, tex.Height, tex.Depth,
              tex.BytesPerPel * 8, CompressedImageSize(tex));
  glGetCompressedTexImageARB(tex.Target, 0, result.Data);
end;

end.
