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,
tfDepth24,
tfDepth32
tfDepth32,

tfS3tcDtx1RGBA,
tfS3tcDtx3RGBA,
tfS3tcDtx5RGBA
);

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

fRange: TglBitmapColorRec;
fShift: TShiftRec;
@@ -1071,6 +1077,7 @@ type
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;
@@ -1413,6 +1420,24 @@ type
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
@@ -1526,7 +1551,11 @@ const

TfdDepth16,
TfdDepth24,
TfdDepth32
TfdDepth32,

TfdS3tcDtx1RGBA,
TfdS3tcDtx3RGBA,
TfdS3tcDtx5RGBA
);

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

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

// DDS_header.sCaps.dwCaps1
DDSCAPS_COMPLEX = $00000008;
@@ -6940,84 +7050,70 @@ type
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;

@@ -7025,37 +7121,45 @@ begin
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;
@@ -7141,8 +7245,7 @@ var
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;
@@ -7159,9 +7262,8 @@ begin
end
else SetLength(fLines, 0);
end else begin
(*
SetLength(fLines, 0);
(*
fSetPixelFunc := nil;

case Format of
@@ -7185,19 +7287,16 @@ var
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
@@ -7218,15 +7317,13 @@ var
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);
@@ -7266,12 +7363,10 @@ begin
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);


Loading…
Cancel
Save