From: Bergmann89 Date: Sun, 10 Nov 2013 16:30:24 +0000 (+0100) Subject: * refactored LoadDDS X-Git-Url: https://git.delphigl.com/?p=LazOpenGLCore.git;a=commitdiff_plain;h=ff9fe5a4282af64bf3d6fad22ce914c3124e49fa * refactored LoadDDS --- diff --git a/glBitmap.pas b/glBitmap.pas index 88724cf..72c81e0 100644 --- a/glBitmap.pas +++ b/glBitmap.pas @@ -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; @@ -3401,6 +3432,84 @@ begin 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; @@ -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);