tfDepth16,
tfDepth24,
- tfDepth32
+ tfDepth32,
+
+ tfS3tcDtx1RGBA,
+ tfS3tcDtx3RGBA,
+ tfS3tcDtx5RGBA
);
TglBitmapFileType = (
fWithAlpha: TglBitmapFormat;
fWithoutAlpha: TglBitmapFormat;
fRGBInverted: TglBitmapFormat;
+ fUncompressed: TglBitmapFormat;
fPixelSize: Single;
+ fIsCompressed: Boolean;
fRange: TglBitmapColorRec;
fShift: TShiftRec;
property RGBInverted: TglBitmapFormat read fRGBInverted;
property Components: Integer read GetComponents;
property PixelSize: Single read fPixelSize;
+ property IsCompressed: Boolean read fIsCompressed;
property glFormat: Cardinal read fglFormat;
property glInternalFormat: Cardinal read fglInternalFormat;
constructor Create; override;
end;
+ TfdS3tcDtx1RGBA = class(TFormatDescriptor)
+ procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+ procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+ constructor Create; override;
+ end;
+
+ TfdS3tcDtx3RGBA = class(TFormatDescriptor)
+ procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+ procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+ constructor Create; override;
+ end;
+
+ TfdS3tcDtx5RGBA = class(TFormatDescriptor)
+ procedure Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer); override;
+ procedure Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer); override;
+ constructor Create; override;
+ end;
+
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TbmpBitfieldFormat = class(TFormatDescriptor)
private
TfdDepth16,
TfdDepth24,
- TfdDepth32
+ TfdDepth32,
+
+ TfdS3tcDtx1RGBA,
+ TfdS3tcDtx3RGBA,
+ TfdS3tcDtx5RGBA
);
var
fWithAlpha := tfEmpty;
fWithoutAlpha := tfEmpty;
fRGBInverted := tfEmpty;
+ fUncompressed := tfEmpty;
fPixelSize := 0.0;
+ fIsCompressed := false;
fglFormat := 0;
fglInternalFormat := 0;
end;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdS3tcDtx1RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdS3tcDtx1RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+ raise EglBitmapException.Create('mapping for compressed formats is not supported');
+end;
+
+procedure TfdS3tcDtx1RGBA.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+ raise EglBitmapException.Create('mapping for compressed formats is not supported');
+end;
+
+constructor TfdS3tcDtx1RGBA.Create;
+begin
+ inherited Create;
+ fFormat := tfS3tcDtx1RGBA;
+ fWithAlpha := tfS3tcDtx1RGBA;
+ fUncompressed := tfRGB5A1;
+ fPixelSize := 0.5;
+ fIsCompressed := true;
+ fglFormat := GL_COMPRESSED_RGBA;
+ fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ fglDataFormat := GL_UNSIGNED_BYTE;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdS3tcDtx3RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdS3tcDtx3RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+ raise EglBitmapException.Create('mapping for compressed formats is not supported');
+end;
+
+procedure TfdS3tcDtx3RGBA.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+ raise EglBitmapException.Create('mapping for compressed formats is not supported');
+end;
+
+constructor TfdS3tcDtx3RGBA.Create;
+begin
+ inherited Create;
+ fFormat := tfS3tcDtx3RGBA;
+ fWithAlpha := tfS3tcDtx3RGBA;
+ fUncompressed := tfRGBA8;
+ fPixelSize := 1.0;
+ fIsCompressed := true;
+ fglFormat := GL_COMPRESSED_RGBA;
+ fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
+ fglDataFormat := GL_UNSIGNED_BYTE;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TfdS3tcDtx5RGBA/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TfdS3tcDtx5RGBA.Map(const aPixel: TglBitmapPixelData; var aData: PByte; var aMapData: Pointer);
+begin
+ raise EglBitmapException.Create('mapping for compressed formats is not supported');
+end;
+
+procedure TfdS3tcDtx5RGBA.Unmap(var aData: PByte; var aPixel: TglBitmapPixelData; var aMapData: Pointer);
+begin
+ raise EglBitmapException.Create('mapping for compressed formats is not supported');
+end;
+
+constructor TfdS3tcDtx5RGBA.Create;
+begin
+ inherited Create;
+ fFormat := tfS3tcDtx3RGBA;
+ fWithAlpha := tfS3tcDtx3RGBA;
+ fUncompressed := tfRGBA8;
+ fPixelSize := 1.0;
+ fIsCompressed := true;
+ fglFormat := GL_COMPRESSED_RGBA;
+ fglInternalFormat := GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
+ fglDataFormat := GL_UNSIGNED_BYTE;
+end;
+
+//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class procedure TFormatDescriptor.Init;
DDPF_FOURCC = $00000004;
DDPF_INDEXED = $00000020;
DDPF_RGB = $00000040;
+ DDPF_LUMINANCE = $00020000;
// DDS_header.sCaps.dwCaps1
DDSCAPS_COMPLEX = $00000008;
function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
var
Header: TDDSHeader;
- StreamPos: Int64;
- Y, LineSize: Cardinal;
- RowSize: Cardinal;
- NewImage, pData: pByte;
- ddsFormat: TglBitmapFormat;
-
- function RaiseEx : Exception;
- begin
- result := EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
- end;
function GetDDSFormat: TglBitmapFormat;
begin
+ result := tfEmpty;
with Header.PixelFormat do begin
// Compresses
- if (dwFlags and DDPF_FOURCC) > 0 then begin
- (* TODO
+ if ((dwFlags and DDPF_FOURCC) > 0) then begin
case Header.PixelFormat.dwFourCC of
- D3DFMT_DXT1: result := ifDXT1;
- D3DFMT_DXT3: result := ifDXT3;
- D3DFMT_DXT5: result := ifDXT5;
- else
- raise RaiseEx;
+ D3DFMT_DXT1: result := tfS3tcDtx1RGBA;
+ D3DFMT_DXT3: result := tfS3tcDtx3RGBA;
+ D3DFMT_DXT5: result := tfS3tcDtx5RGBA;
end;
- *)
- raise RaiseEx;
end else
// RGB
- if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
+ if (dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
case dwRGBBitCount of
8: begin
- (* TODO if dwFlags and DDPF_ALPHAPIXELS > 0 then
- result := tfAlpha
- else
- *)
+ if ((dwFlags and DDPF_ALPHAPIXELS) > 0) then
+ result := tfAlpha8
+ else if ((dwFlags and DDPF_LUMINANCE) > 0) then
result := tfLuminance8;
end;
+
16: begin
- if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
- // Alpha
+ if ((dwFlags and DDPF_ALPHAPIXELS) > 0) then begin
case CountSetBits(dwRBitMask) of
5: result := tfRGB5A1;
- //TODO 4: result := tfRGBA4;
+ 4: result := tfRGBA4;
else
result := tfLuminance8Alpha8;
end;
- end else begin
- // no Alpha
- //TODO result := ifR5G6B5;
- raise RaiseEx;
- end;
+ end else if (CountSetBits(dwGBitMask) = 6) then
+ result := tfR5G6B5
+ else
+ result := tfRGB5;
end;
+
24: begin
- if dwRBitMask > dwBBitMask then
- result := tfBGR8
- else
- result := tfRGB8;
+ result := tfRGB8;
end;
- 32: begin
- if CountSetBits(dwRBitMask) = 10 then
- //TODO result := tfRGB10A2
- raise RaiseEx
- else
- if dwRBitMask > dwBBitMask then
- result := tfBGRA8
+ 32: begin
+ if CountSetBits(dwRBitMask) = 10 then
+ result := tfRGB10A2
else
result := tfRGBA8;
end;
- else
- raise RaiseEx;
end;
- end else
- raise RaiseEx;
+
+ if (dwRBitMask <> 0) and (dwBBitMask <> 0) and (dwRBitMask > dwBBitMask) then
+ result := TFormatDescriptor.Get(result).RGBInverted;
+ end;
end;
end;
+var
+ StreamPos: Int64;
+ Y, LineSize: Cardinal;
+ RowSize: Cardinal;
+ NewImage, TmpData: PByte;
+ ddsFormat: TglBitmapFormat;
+ FormatDesc: TFormatDescriptor;
+
begin
result := false;
StreamPos := aStream.Position;
aStream.Read(Header, sizeof(Header));
- if ((Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
- ((Header.dwFlags and DDSD_PIXELFORMAT) = 0) or ((Header.dwFlags and DDSD_CAPS) = 0)) then begin
+ if (Header.dwMagic <> DDS_MAGIC) or (Header.dwSize <> 124) or
+ ((Header.dwFlags and (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) <>
+ (DDSD_PIXELFORMAT or DDSD_CAPS or DDSD_WIDTH or DDSD_HEIGHT)) then
+ begin
aStream.Position := StreamPos;
exit;
end;
+ if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
+ raise EglBitmapException.Create('LoadDDS - CubeMaps are not supported');
+
ddsFormat := GetDDSFormat;
- LineSize := Trunc(Header.dwWidth * TFormatDescriptor.Get(ddsFormat).PixelSize);
+ if (ddsFormat = tfEmpty) then
+ raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
+
+ FormatDesc := TFormatDescriptor.Get(ddsFormat);
+ LineSize := Trunc(Header.dwWidth * FormatDesc.PixelSize);
GetMem(NewImage, Header.dwHeight * LineSize);
try
- pData := NewImage;
+ TmpData := NewImage;
// Compressed
- if (Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0 then begin
+ if ((Header.PixelFormat.dwFlags and DDPF_FOURCC) > 0) then begin
RowSize := Header.dwPitchOrLinearSize div Header.dwWidth;
- for Y := 0 to Header.dwHeight -1 do begin
- aStream.Read(pData^, RowSize);
- Inc(pData, LineSize);
+ for Y := 0 to Header.dwHeight-1 do begin
+ aStream.Read(TmpData^, RowSize);
+ Inc(TmpData, LineSize);
end;
end else
- // RGB(A)
- if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS)) > 0 then begin
- RowSize := Header.dwPitchOrLinearSize;
-
- for Y := 0 to Header.dwHeight -1 do begin
- aStream.Read(pData^, RowSize);
- Inc(pData, LineSize);
+ // Uncompressed
+ if (Header.PixelFormat.dwFlags and (DDPF_RGB or DDPF_ALPHAPIXELS or DDPF_LUMINANCE)) > 0 then begin
+ RowSize := (Header.PixelFormat.dwRGBBitCount * Header.dwWidth) shr 3;
+ for Y := 0 to Header.dwHeight-1 do begin
+ aStream.Read(TmpData^, RowSize);
+ Inc(TmpData, LineSize);
end;
end else
- raise RaiseEx;
+ raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');
SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
result := true;
begin
inherited SetDataPointer(aData, aFormat, aWidth, aHeight);
- //TODO compression
- if {FormatIsUncompressed(Format)} true then begin
+ if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
(* TODO PixelFuncs
fGetPixelFunc := GetPixel2DUnmap;
fSetPixelFunc := SetPixel2DUnmap;
end
else SetLength(fLines, 0);
end else begin
- (*
SetLength(fLines, 0);
-
+ (*
fSetPixelFunc := nil;
case Format of
begin
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- (* TODO compression
- if Self.InternalFormat in [ifDXT1, ifDXT3, ifDXT5] then
- glCompressedTexImage2D(Target, 0, InternalFormat, Width, Height, 0, Trunc(Width * Height * FormatGetSize(Self.InternalFormat)), Data)
- else
- *)
-
FormatDesc := TFormatDescriptor.Get(Format);
- if aBuildWithGlu then
+ if FormatDesc.IsCompressed then begin
+ glCompressedTexImage2D(Target, 0, FormatDesc.glInternalFormat, Width, Height, 0, FormatDesc.GetSize(fDimension), Data)
+ end else if aBuildWithGlu then begin
gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
- else
+ end else begin
glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
+ end;
// Freigeben
if (FreeDataAfterGenTexture) then
Size, w, h: Integer;
FormatDesc: TFormatDescriptor;
begin
- (* TODO compression
- if not FormatIsUncompressed(Format) then
+ FormatDesc := TFormatDescriptor.Get(Format);
+ if FormatDesc.IsCompressed then
raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT);
- *)
- w := aRight - aLeft;
- h := aBottom - aTop;
- FormatDesc := TFormatDescriptor.Get(Format);
- Size := FormatDesc.GetSize(w, h);
+ w := aRight - aLeft;
+ h := aBottom - aTop;
+ Size := FormatDesc.GetSize(w, h);
GetMem(Temp, Size);
try
glPixelStorei(GL_PACK_ALIGNMENT, 1);
FormatDesc := TFormatDescriptor.Get(IntFormat);
GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
try
- (* TODO Compression
- if FormatIsCompressed(IntFormat) and (GL_VERSION_1_3 or GL_ARB_texture_compression) then
+ if FormatDesc.IsCompressed then
glGetCompressedTexImage(Target, 0, Temp)
else
- *)
- glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
+ glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
except
FreeMem(Temp);