Browse Source

* refactored LoadDDS

master
Bergmann89 10 years ago
parent
commit
ff9fe5a428
1 changed files with 183 additions and 88 deletions
  1. +183
    -88
      glBitmap.pas

+ 183
- 88
glBitmap.pas View File

@@ -645,7 +645,11 @@ type


tfDepth16, tfDepth16,
tfDepth24, tfDepth24,
tfDepth32
tfDepth32,

tfS3tcDtx1RGBA,
tfS3tcDtx3RGBA,
tfS3tcDtx5RGBA
); );


TglBitmapFileType = ( TglBitmapFileType = (
@@ -1054,7 +1058,9 @@ type
fWithAlpha: TglBitmapFormat; fWithAlpha: TglBitmapFormat;
fWithoutAlpha: TglBitmapFormat; fWithoutAlpha: TglBitmapFormat;
fRGBInverted: TglBitmapFormat; fRGBInverted: TglBitmapFormat;
fUncompressed: TglBitmapFormat;
fPixelSize: Single; fPixelSize: Single;
fIsCompressed: Boolean;


fRange: TglBitmapColorRec; fRange: TglBitmapColorRec;
fShift: TShiftRec; fShift: TShiftRec;
@@ -1071,6 +1077,7 @@ type
property RGBInverted: TglBitmapFormat read fRGBInverted; property RGBInverted: TglBitmapFormat read fRGBInverted;
property Components: Integer read GetComponents; property Components: Integer read GetComponents;
property PixelSize: Single read fPixelSize; property PixelSize: Single read fPixelSize;
property IsCompressed: Boolean read fIsCompressed;


property glFormat: Cardinal read fglFormat; property glFormat: Cardinal read fglFormat;
property glInternalFormat: Cardinal read fglInternalFormat; property glInternalFormat: Cardinal read fglInternalFormat;
@@ -1413,6 +1420,24 @@ type
constructor Create; override; constructor Create; override;
end; 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) TbmpBitfieldFormat = class(TFormatDescriptor)
private private
@@ -1526,7 +1551,11 @@ const


TfdDepth16, TfdDepth16,
TfdDepth24, TfdDepth24,
TfdDepth32
TfdDepth32,

TfdS3tcDtx1RGBA,
TfdS3tcDtx3RGBA,
TfdS3tcDtx5RGBA
); );


var var
@@ -2236,7 +2265,9 @@ begin
fWithAlpha := tfEmpty; fWithAlpha := tfEmpty;
fWithoutAlpha := tfEmpty; fWithoutAlpha := tfEmpty;
fRGBInverted := tfEmpty; fRGBInverted := tfEmpty;
fUncompressed := tfEmpty;
fPixelSize := 0.0; fPixelSize := 0.0;
fIsCompressed := false;


fglFormat := 0; fglFormat := 0;
fglInternalFormat := 0; fglInternalFormat := 0;
@@ -3400,6 +3431,84 @@ begin
fglInternalFormat := GL_DEPTH_COMPONENT32; fglInternalFormat := GL_DEPTH_COMPONENT32;
end; 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/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //TFormatDescriptor///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -6882,6 +6991,7 @@ const
DDPF_FOURCC = $00000004; DDPF_FOURCC = $00000004;
DDPF_INDEXED = $00000020; DDPF_INDEXED = $00000020;
DDPF_RGB = $00000040; DDPF_RGB = $00000040;
DDPF_LUMINANCE = $00020000;


// DDS_header.sCaps.dwCaps1 // DDS_header.sCaps.dwCaps1
DDSCAPS_COMPLEX = $00000008; DDSCAPS_COMPLEX = $00000008;
@@ -6940,84 +7050,70 @@ type
function TglBitmap.LoadDDS(const aStream: TStream): Boolean; function TglBitmap.LoadDDS(const aStream: TStream): Boolean;
var var
Header: TDDSHeader; 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; function GetDDSFormat: TglBitmapFormat;
begin begin
result := tfEmpty;
with Header.PixelFormat do begin with Header.PixelFormat do begin
// Compresses // Compresses
if (dwFlags and DDPF_FOURCC) > 0 then begin
(* TODO
if ((dwFlags and DDPF_FOURCC) > 0) then begin
case Header.PixelFormat.dwFourCC of 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; end;
*)
raise RaiseEx;
end else end else


// RGB // 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 case dwRGBBitCount of
8: begin 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; result := tfLuminance8;
end; end;

16: begin 16: begin
if dwFlags and DDPF_ALPHAPIXELS > 0 then begin
// Alpha
if ((dwFlags and DDPF_ALPHAPIXELS) > 0) then begin
case CountSetBits(dwRBitMask) of case CountSetBits(dwRBitMask) of
5: result := tfRGB5A1; 5: result := tfRGB5A1;
//TODO 4: result := tfRGBA4;
4: result := tfRGBA4;
else else
result := tfLuminance8Alpha8; result := tfLuminance8Alpha8;
end; 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; end;

24: begin 24: begin
if dwRBitMask > dwBBitMask then
result := tfBGR8
else
result := tfRGB8;
result := tfRGB8;
end; 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 else
result := tfRGBA8; result := tfRGBA8;
end; end;
else
raise RaiseEx;
end; end;
end else
raise RaiseEx;

if (dwRBitMask <> 0) and (dwBBitMask <> 0) and (dwRBitMask > dwBBitMask) then
result := TFormatDescriptor.Get(result).RGBInverted;
end;
end; end;
end; end;


var
StreamPos: Int64;
Y, LineSize: Cardinal;
RowSize: Cardinal;
NewImage, TmpData: PByte;
ddsFormat: TglBitmapFormat;
FormatDesc: TFormatDescriptor;

begin begin
result := false; result := false;


@@ -7025,37 +7121,45 @@ begin
StreamPos := aStream.Position; StreamPos := aStream.Position;
aStream.Read(Header, sizeof(Header)); 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; aStream.Position := StreamPos;
exit; exit;
end; end;


if ((Header.Caps.dwCaps1 and DDSCAPS2_CUBEMAP) > 0) then
raise EglBitmapException.Create('LoadDDS - CubeMaps are not supported');

ddsFormat := GetDDSFormat; 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); GetMem(NewImage, Header.dwHeight * LineSize);
try try
pData := NewImage;
TmpData := NewImage;


// Compressed // 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; 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;
end else 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;
end else end else
raise RaiseEx;
raise EglBitmapException.Create('LoadDDS - unsupported Pixelformat found.');


SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight); SetDataPointer(NewImage, ddsFormat, Header.dwWidth, Header.dwHeight);
result := true; result := true;
@@ -7141,8 +7245,7 @@ var
begin begin
inherited SetDataPointer(aData, aFormat, aWidth, aHeight); inherited SetDataPointer(aData, aFormat, aWidth, aHeight);


//TODO compression
if {FormatIsUncompressed(Format)} true then begin
if not TFormatDescriptor.Get(aFormat).IsCompressed then begin
(* TODO PixelFuncs (* TODO PixelFuncs
fGetPixelFunc := GetPixel2DUnmap; fGetPixelFunc := GetPixel2DUnmap;
fSetPixelFunc := SetPixel2DUnmap; fSetPixelFunc := SetPixel2DUnmap;
@@ -7159,9 +7262,8 @@ begin
end end
else SetLength(fLines, 0); else SetLength(fLines, 0);
end else begin end else begin
(*
SetLength(fLines, 0); SetLength(fLines, 0);
(*
fSetPixelFunc := nil; fSetPixelFunc := nil;


case Format of case Format of
@@ -7185,19 +7287,16 @@ var
begin begin
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 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); 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, gluBuild2DMipmaps(aTarget, FormatDesc.Components, Width, Height,
FormatDesc.glFormat, FormatDesc.glDataFormat, Data) FormatDesc.glFormat, FormatDesc.glDataFormat, Data)
else
end else begin
glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0, glTexImage2D(aTarget, 0, FormatDesc.glInternalFormat, Width, Height, 0,
FormatDesc.glFormat, FormatDesc.glDataFormat, Data); FormatDesc.glFormat, FormatDesc.glDataFormat, Data);
end;


// Freigeben // Freigeben
if (FreeDataAfterGenTexture) then if (FreeDataAfterGenTexture) then
@@ -7218,15 +7317,13 @@ var
Size, w, h: Integer; Size, w, h: Integer;
FormatDesc: TFormatDescriptor; FormatDesc: TFormatDescriptor;
begin begin
(* TODO compression
if not FormatIsUncompressed(Format) then
FormatDesc := TFormatDescriptor.Get(Format);
if FormatDesc.IsCompressed then
raise EglBitmapUnsupportedFormatFormat.Create('TglBitmap2D.GrabScreen - ' + UNSUPPORTED_FORMAT); 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); GetMem(Temp, Size);
try try
glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_PACK_ALIGNMENT, 1);
@@ -7266,12 +7363,10 @@ begin
FormatDesc := TFormatDescriptor.Get(IntFormat); FormatDesc := TFormatDescriptor.Get(IntFormat);
GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight)); GetMem(Temp, FormatDesc.GetSize(TempWidth, TempHeight));
try 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) glGetCompressedTexImage(Target, 0, Temp)
else else
*)
glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
glGetTexImage(Target, 0, FormatDesc.glInternalFormat, FormatDesc.glDataFormat, Temp);
SetDataPointer(Temp, IntFormat, TempWidth, TempHeight); SetDataPointer(Temp, IntFormat, TempWidth, TempHeight);
except except
FreeMem(Temp); FreeMem(Temp);


Loading…
Cancel
Save