![]() |
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; |
AW: Anzeigen von DDS Dateien
@redeemer
Herunterladen : 5 Sekunden - Einbauen : 120 Sekunden - Ausprobieren : 360 Sekunden - Erfolg: 100% ! Perfekt.
Delphi-Quellcode:
Das ist alles. LoadDXT1 ist alles was ich brauche, die DDS Dateien stammen aus den PC Spielen CaesarIV, Anno1404 und Age of Empires 3.
procedure TForm1.FormCreate(Sender: TObject);
Var PNGTyp:TPngImage; begin PNGTyp:= TPNGIMAGE.Create; PNGTyp := LoadDXT1('aaaaa'); Image1.Picture.Assign(PngTyp); end; @an alle die geantwortet haben Ich bin nicht der Experte für PC Grafik. Vieles davon muss und musste ich mir empirisch zusammenbasteln, "basteln" wörtlich genommen. Und die o.g. LoadDXT1 ist mir in ihrer Ausführung auch ziemlich schleierhaft. Wir hier bauen für einige ältere Spiele - siehe oben - Karten, Missionen und Hilfstools. Das spielt sich eher in dem Bereich Datenbank oder auch schlichter Textbearbeitung ab. Ich bedanke mich bei allen für die Antworten und Hilfestellungen! :thumb: creehawk |
AW: Anzeigen von DDS Dateien
Delphi-Quellcode:
Sonst hast du Speicherlecks!
procedure TForm1.FormCreate(Sender: TObject);
Var PNGTyp:TPngImage; begin PNGTyp := LoadDXT1('aaaaa'); Image1.Picture.Assign(PngTyp); PNGTyp.Free; end; |
AW: Anzeigen von DDS Dateien
Ups, alles klar, danke!
|
AW: Anzeigen von DDS Dateien
Moin...:P
Ich will ja nicht meckern...aber TRY FINALLY ist ein indisches Gewürz oder? :roll:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var PNGTyp:TPngImage; begin PNGTyp := LoadDXT1('aaaaa'); try Image1.Picture.Assign(PngTyp); finally PNGTyp.Free; end; end; |
AW: Anzeigen von DDS Dateien
Hi, apologies for using English but I am desperate for some help.
I need to load a DDS file and display it in a TImage32 (or TImage/TBitmap) component, but I have been unable to do so. Could I please ask you for an example on how to do this (if possible?) Thank you! |
AW: Anzeigen von DDS Dateien
Hello,
download the attachment attached to this post from 2017 in this thread: Zitat:
That should work. Best regards TurboMagic |
AW: Anzeigen von DDS Dateien
Zitat:
Einmal die Instanz vom Create, dann nochmal aus LoadDXT1, und am Ende wird Keine davon wieder freigegeben. Zitat:
|
AW: Anzeigen von DDS Dateien
Wieso? Der Code im Post direkt vor seinem = "preceding" gibt doch das png image frei! Oder was hab' ich übersehen?
|
AW: Anzeigen von DDS Dateien
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:16 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