| @@ -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); | |||