![]() |
Anzeigen von DDS Dateien
Moin Moin.
Ich möchte (muss) für ein Programm Grafik(Textur) Dateien vom Typ DDS anzeigen. Mit D7 kein Problem. Mit Delphi 10.2 schon, weil alle angebotenen Hilfsmittel wie Devil, Vampyre, Andorra, glBitmap und weiß ich was in Delphi 10.2 nicht laufen, zumeist gibt es massig Typprobleme. Liegt wohl daran das die aktuellsten Ausgaben der genannten so um das Jahr 2009 datieren - aber auch Modelle aus 2015 gehen nicht. Gibt es irgendwas Neueres, eine andere Möglichkeit? creehawk |
AW: Anzeigen von DDS Dateien
Da wirst du um das Laden per Stream und dann händisch auseinander basteln wohl nicht drum rum kommen.
Außer natürlich, jemand hat noch irgendwo eine fertige Unit parat. Bist du mit dem Programm ILSpy und Paint.Net vertraut? Mit dem Ersten kannst du im Zweiten nachschauen, wie im Namespace PaintDotNet.Data.Dds -> DdsFile diese Texturen geladen werden. Beispiel:
Code:
public void Load(Stream input)
{ uint ddsTag = (uint)input.ReadUInt32(); if (ddsTag != 542327876u) { throw new FormatException("File does not appear to be a DDS image"); } this.m_header.Read(input); if (this.m_header.m_pixelFormat.m_flags == 0u || (this.m_header.m_pixelFormat.m_flags & 4u) != 0u) { uint fourCC = this.m_header.m_pixelFormat.m_fourCC; int squishFlags; if (fourCC != 827611204u) { if (fourCC != 861165636u) { if (fourCC != 894720068u) { throw new FormatException("File is not a supported DDS format"); } squishFlags = 4; } else { squishFlags = 2; } } else { squishFlags = 1; } int blockCount = (this.GetWidth() + 3) / 4 * ((this.GetHeight() + 3) / 4); int blockSize = ((squishFlags & 1) != 0) ? 8 : 16; byte[] compressedBlocks = new byte[blockCount * blockSize]; input.Read(compressedBlocks, 0, compressedBlocks.GetLength(0)); this.m_pixelData = DdsSquish.DecompressImage(compressedBlocks, this.GetWidth(), this.GetHeight(), squishFlags); return; } DdsFileFormat fileFormat; if (this.m_header.m_pixelFormat.m_flags == 65u && this.m_header.m_pixelFormat.m_rgbBitCount == 32u && this.m_header.m_pixelFormat.m_rBitMask == 16711680u && this.m_header.m_pixelFormat.m_gBitMask == 65280u && this.m_header.m_pixelFormat.m_bBitMask == 255u && this.m_header.m_pixelFormat.m_aBitMask == 4278190080u) { fileFormat = DdsFileFormat.DDS_FORMAT_A8R8G8B8; } else if (this.m_header.m_pixelFormat.m_flags == 64u && this.m_header.m_pixelFormat.m_rgbBitCount == 32u && this.m_header.m_pixelFormat.m_rBitMask == 16711680u && this.m_header.m_pixelFormat.m_gBitMask == 65280u && this.m_header.m_pixelFormat.m_bBitMask == 255u && this.m_header.m_pixelFormat.m_aBitMask == 0u) { fileFormat = DdsFileFormat.DDS_FORMAT_X8R8G8B8; } else if (this.m_header.m_pixelFormat.m_flags == 65u && this.m_header.m_pixelFormat.m_rgbBitCount == 32u && this.m_header.m_pixelFormat.m_rBitMask == 255u && this.m_header.m_pixelFormat.m_gBitMask == 65280u && this.m_header.m_pixelFormat.m_bBitMask == 16711680u && this.m_header.m_pixelFormat.m_aBitMask == 4278190080u) { fileFormat = DdsFileFormat.DDS_FORMAT_A8B8G8R8; } else if (this.m_header.m_pixelFormat.m_flags == 64u && this.m_header.m_pixelFormat.m_rgbBitCount == 32u && this.m_header.m_pixelFormat.m_rBitMask == 255u && this.m_header.m_pixelFormat.m_gBitMask == 65280u && this.m_header.m_pixelFormat.m_bBitMask == 16711680u && this.m_header.m_pixelFormat.m_aBitMask == 0u) { fileFormat = DdsFileFormat.DDS_FORMAT_X8B8G8R8; } else if (this.m_header.m_pixelFormat.m_flags == 65u && this.m_header.m_pixelFormat.m_rgbBitCount == 16u && this.m_header.m_pixelFormat.m_rBitMask == 31744u && this.m_header.m_pixelFormat.m_gBitMask == 992u && this.m_header.m_pixelFormat.m_bBitMask == 31u && this.m_header.m_pixelFormat.m_aBitMask == 32768u) { fileFormat = DdsFileFormat.DDS_FORMAT_A1R5G5B5; } else if (this.m_header.m_pixelFormat.m_flags == 65u && this.m_header.m_pixelFormat.m_rgbBitCount == 16u && this.m_header.m_pixelFormat.m_rBitMask == 3840u && this.m_header.m_pixelFormat.m_gBitMask == 240u && this.m_header.m_pixelFormat.m_bBitMask == 15u && this.m_header.m_pixelFormat.m_aBitMask == 61440u) { fileFormat = DdsFileFormat.DDS_FORMAT_A4R4G4B4; } else if (this.m_header.m_pixelFormat.m_flags == 64u && this.m_header.m_pixelFormat.m_rgbBitCount == 24u && this.m_header.m_pixelFormat.m_rBitMask == 16711680u && this.m_header.m_pixelFormat.m_gBitMask == 65280u && this.m_header.m_pixelFormat.m_bBitMask == 255u && this.m_header.m_pixelFormat.m_aBitMask == 0u) { fileFormat = DdsFileFormat.DDS_FORMAT_R8G8B8; } else { if (this.m_header.m_pixelFormat.m_flags != 64u || this.m_header.m_pixelFormat.m_rgbBitCount != 16u || this.m_header.m_pixelFormat.m_rBitMask != 63488u || this.m_header.m_pixelFormat.m_gBitMask != 2016u || this.m_header.m_pixelFormat.m_bBitMask != 31u || this.m_header.m_pixelFormat.m_aBitMask != 0u) { throw new FormatException("File is not a supported DDS format"); } fileFormat = DdsFileFormat.DDS_FORMAT_R5G6B5; } int srcPixelSize = (int)(this.m_header.m_pixelFormat.m_rgbBitCount / 8u); int rowPitch; if ((this.m_header.m_headerFlags & 8u) != 0u) { rowPitch = (int)this.m_header.m_pitchOrLinearSize; } else if ((this.m_header.m_headerFlags & 524288u) != 0u) { rowPitch = (int)(this.m_header.m_pitchOrLinearSize / this.m_header.m_height); } else { rowPitch = (int)(this.m_header.m_width * (uint)srcPixelSize); } byte[] readPixelData = new byte[(long)rowPitch * (long)((ulong)this.m_header.m_height)]; input.Read(readPixelData, 0, readPixelData.GetLength(0)); this.m_pixelData = new byte[this.m_header.m_width * this.m_header.m_height * 4u]; for (int destY = 0; destY < (int)this.m_header.m_height; destY++) { for (int destX = 0; destX < (int)this.m_header.m_width; destX++) { int srcPixelOffset = destY * rowPitch + destX * srcPixelSize; uint pixelColour = 0u; uint pixelRed = 0u; uint pixelGreen = 0u; uint pixelBlue = 0u; uint pixelAlpha = 0u; for (int loop = 0; loop < srcPixelSize; loop++) { pixelColour |= (uint)((uint)readPixelData[srcPixelOffset + loop] << 8 * loop); } if (fileFormat == DdsFileFormat.DDS_FORMAT_A8R8G8B8) { pixelAlpha = (pixelColour >> 24 & 255u); pixelRed = (pixelColour >> 16 & 255u); pixelGreen = (pixelColour >> 8 & 255u); pixelBlue = (pixelColour & 255u); } else if (fileFormat == DdsFileFormat.DDS_FORMAT_X8R8G8B8) { pixelAlpha = 255u; pixelRed = (pixelColour >> 16 & 255u); pixelGreen = (pixelColour >> 8 & 255u); pixelBlue = (pixelColour & 255u); } else if (fileFormat == DdsFileFormat.DDS_FORMAT_A8B8G8R8) { pixelAlpha = (pixelColour >> 24 & 255u); pixelRed = (pixelColour & 255u); pixelGreen = (pixelColour >> 8 & 255u); pixelBlue = (pixelColour >> 16 & 255u); } else if (fileFormat == DdsFileFormat.DDS_FORMAT_X8B8G8R8) { pixelAlpha = 255u; pixelRed = (pixelColour & 255u); pixelGreen = (pixelColour >> 8 & 255u); pixelBlue = (pixelColour >> 16 & 255u); } else if (fileFormat == DdsFileFormat.DDS_FORMAT_A1R5G5B5) { pixelAlpha = (pixelColour >> 15) * 255u; pixelRed = (pixelColour >> 10 & 31u); pixelGreen = (pixelColour >> 5 & 31u); pixelBlue = (pixelColour & 31u); pixelRed = (pixelRed << 3 | pixelRed >> 2); pixelGreen = (pixelGreen << 3 | pixelGreen >> 2); pixelBlue = (pixelBlue << 3 | pixelBlue >> 2); } else if (fileFormat == DdsFileFormat.DDS_FORMAT_A4R4G4B4) { pixelAlpha = (pixelColour >> 12 & 255u); pixelRed = (pixelColour >> 8 & 15u); pixelGreen = (pixelColour >> 4 & 15u); pixelBlue = (pixelColour & 15u); pixelAlpha = (pixelAlpha << 4 | pixelAlpha); pixelRed = (pixelRed << 4 | pixelRed); pixelGreen = (pixelGreen << 4 | pixelGreen); pixelBlue = (pixelBlue << 4 | pixelBlue); } else if (fileFormat == DdsFileFormat.DDS_FORMAT_R8G8B8) { pixelAlpha = 255u; pixelRed = (pixelColour >> 16 & 255u); pixelGreen = (pixelColour >> 8 & 255u); pixelBlue = (pixelColour & 255u); } else if (fileFormat == DdsFileFormat.DDS_FORMAT_R5G6B5) { pixelAlpha = 255u; pixelRed = (pixelColour >> 11 & 31u); pixelGreen = (pixelColour >> 5 & 63u); pixelBlue = (pixelColour & 31u); pixelRed = (pixelRed << 3 | pixelRed >> 2); pixelGreen = (pixelGreen << 2 | pixelGreen >> 4); pixelBlue = (pixelBlue << 3 | pixelBlue >> 2); } int destPixelOffset = destY * (int)this.m_header.m_width * 4 + destX * 4; this.m_pixelData[destPixelOffset] = (byte)pixelRed; this.m_pixelData[destPixelOffset + 1] = (byte)pixelGreen; this.m_pixelData[destPixelOffset + 2] = (byte)pixelBlue; this.m_pixelData[destPixelOffset + 3] = (byte)pixelAlpha; } } } |
AW: Anzeigen von DDS Dateien
Selber basteln......
Hab' ich schon geahnt. Schaun' mer ma. Vielen Dank für die Antwort. Creehawk |
AW: Anzeigen von DDS Dateien
Hast Du wirklich die "aktuelle" Datei von glBitmap?
![]() Forum ![]() Was geht denn da nicht? Vielleicht auch mal Herrn Bergmann fragen, der verwaltet das gerade. ![]() ![]() |
AW: Anzeigen von DDS Dateien
in der "glBitmapConf.default.inc" müssen Kompilerdirektiven für Delphi eingestellt werden!
|
AW: Anzeigen von DDS Dateien
Moin Moin.
glBitmap habe ich samt Zubehör installiert. Mangels Dokumentation habe ich folgendes ausprobiert:
Delphi-Quellcode:
Letzteres - die Formatdefinition - steht auch nicht in der Liste der unterstützten Formate. Geht also wohl nicht, es sei denn ich mache etwas falsch.
procedure TForm1.Button1Click(Sender: TObject);
var TGLBMPTyp:Tglbitmapdata; BMPTyp:TBitmap; begin BMPTyp := TBitmap.Create; TGLBMPTyp := Tglbitmapdata.Create; TGLBMPTyp.LoadFromFile('E:\Games\maps\Attuwe_Color.dds'); // TGLBMPTyp.AssignToBitmap(BitmapTyp); TGLBMPTyp.AssignToBitmap(Form1.Image1.Picture.Bitmap); end; // Fehlermeldung aus UNIT GLBitmap : "Fehlerhafters Pixelformat" procedure TForm1.Button2Click(Sender: TObject); var TGLBMPTyp:Tglbitmapdata; begin TGLBMPTyp := tglbitmapdata.Create; TGLBMPTyp.LoadFromFile('E:\Games\maps\Attuwe_Color.dds'); TGLBMPTyp.SaveToFile('E:\Games\maps\Attuwe_Color.bmp',ftbmp); end; // Fehlermeldung aus UNIT GLBitmap : Unsupported Format : tf23tcDtx1rgba Blöderweise ist das Programm das ich da erarbeite eigentlich eine Übertragung von Delphi7 nach Delphi 10.2. Die Delphi 7 Variante arbeitet problemlos. In Delphi7 wird die DevIL Variante verwendet (2005), die, kompiliert mit Delphi 10.2, auch problemlos arbeitet, aber nichts anzeigt. Die DevIL Variante in neuerer Version wurde überarbeitet, aber ohne Dokumentation - jedenfalls habe ich keine gefunden - veröffentlicht. Die Befehle der Version 2005 funktionieren nicht mehr. Wat mach' ich nu? creehawk |
AW: Anzeigen von DDS Dateien
Liste der Anhänge anzeigen (Anzahl: 1)
Lag hier rum, ist von 2012 aber sollte immer noch laufen. Methoden sind LoadDXT1, LoadDXT3 und LoadDXT5, such dir eins aus oder schreib eine Methode, das das erkennt. Index, Heights und Widths sind wegen des Programms, das sie verwendet hat, da, weil es die als vertikale ImageStrips benutzt hat und so ein wahlfreier Zugriff möglich ist. Daten werden in einen MemoryStream kopiert, weil das byteweise Lesen von FileStreams sehr langsam ist.
|
AW: Anzeigen von DDS Dateien
Zitat:
Mit der Vorlage sollte der TE ggf. auch die anderen Formate implementieren können, wenn er sie denn braucht. |
AW: Anzeigen von DDS Dateien
@creehawk
Dann würde ich sagen, glBitmap macht Dein Format nicht .... |
AW: Anzeigen von DDS Dateien
Mir ist noch was eingefallen. Du könntest es auch per DirectX an sich laden.
Mit folgenden Codeschnipsel hast du zumindest die geladene DDS-Datei als IDirect3DTexture9 und IDirect3DSurface9 vorliegen. Es würde noch die Möglichkeit geben das in eine IDirectDrawSurface7 umzukopieren und die dann wiederum zu verwenden, um ein Winapi.GDIOBJ.TGPBitmap zu erzeugen. Vom TGPBitmap aus kann man ja weitermachen... Sag Bescheid, wenn du das dann brauchst.
Delphi-Quellcode:
uses
Winapi.GDIPOBJ, Winapi.Windows, Winapi.Direct3D9, // Winapi.DirectDraw, Winapi.D3DX9; procedure LoadPerDirectX(const Filename: string); var HR: HRESULT; Direct3D: IDirect3D9Ex; Device: IDirect3DDevice9; Texture: IDirect3DTexture9; Params: TD3DPresentParameters; DisplayMode: TD3DDisplayMode; D3DSurface: IDirect3DSurface9; // DDSurface: IDirectDrawSurface7; begin HR := Direct3DCreate9Ex(D3D_SDK_VERSION, Direct3D); if Failed(HR) then Exit; HR := Direct3D.GetAdapterDisplayMode(D3DADAPTER_DEFAULT, DisplayMode); if Failed(HR) then Exit; FillChar(Params, SizeOf(Params), 0); Params.SwapEffect := D3DSWAPEFFECT_DISCARD; Params.BackBufferCount := 1; Params.BackBufferWidth := DisplayMode.Width; Params.BackBufferHeight := DisplayMode.Height; Params.BackBufferFormat := DisplayMode.Format; HR := Direct3D.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 0, D3DCREATE_SOFTWARE_VERTEXPROCESSING, @Params, Device); if Failed(HR) then Exit; HR := Winapi.D3DX9.D3DXCreateTextureFromFile(Device, PWideChar(Filename), Texture); if Failed(HR) then Exit; HR := Texture.GetSurfaceLevel(0, D3DSurface); if Failed(HR) then Exit; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz