AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Anzeigen von DDS Dateien

Offene Frage von "himitsu"
Ein Thema von creehawk · begonnen am 28. Nov 2017 · letzter Beitrag vom 13. Sep 2020
Antwort Antwort
Seite 1 von 2  1 2   
creehawk

Registriert seit: 1. Jul 2013
Ort: Hamburg
120 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#1

Anzeigen von DDS Dateien

  Alt 28. Nov 2017, 17:34
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
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
2.498 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#2

AW: Anzeigen von DDS Dateien

  Alt 28. Nov 2017, 17:48
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;
            }
         }
      }
  Mit Zitat antworten Zitat
creehawk

Registriert seit: 1. Jul 2013
Ort: Hamburg
120 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#3

AW: Anzeigen von DDS Dateien

  Alt 28. Nov 2017, 18:12
Selber basteln......

Hab' ich schon geahnt. Schaun' mer ma.

Vielen Dank für die Antwort.

Creehawk
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
604 Beiträge
 
#4

AW: Anzeigen von DDS Dateien

  Alt 28. Nov 2017, 18:14
Hast Du wirklich die "aktuelle" Datei von glBitmap?
http://git.delphigl.com/?p=glBitmap..../master;sf=tgz
Forum https://delphigl.com/forum/viewtopic.php?p=62127#p62127

Was geht denn da nicht?

Vielleicht auch mal Herrn Bergmann fragen, der verwaltet das gerade.
http://www.delphigl.com/forum/viewtopic.php?t=7457
https://bergmann89.de/de/
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
604 Beiträge
 
#5

AW: Anzeigen von DDS Dateien

  Alt 28. Nov 2017, 18:19
in der "glBitmapConf.default.inc" müssen Kompilerdirektiven für Delphi eingestellt werden!
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
creehawk

Registriert seit: 1. Jul 2013
Ort: Hamburg
120 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#6

AW: Anzeigen von DDS Dateien

  Alt 29. Nov 2017, 08:30
Moin Moin.

glBitmap habe ich samt Zubehör installiert. Mangels Dokumentation habe ich folgendes ausprobiert:


Delphi-Quellcode:
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
Letzteres - die Formatdefinition - steht auch nicht in der Liste der unterstützten Formate. Geht also wohl nicht, es sei denn ich mache etwas falsch.

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
  Mit Zitat antworten Zitat
Redeemer
Online

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
704 Beiträge
 
Delphi 2009 Professional
 
#7

AW: Anzeigen von DDS Dateien

  Alt 29. Nov 2017, 08:57
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.
Angehängte Dateien
Dateityp: zip RedeemerGfx.zip (4,7 KB, 12x aufgerufen)
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
2.498 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#8

AW: Anzeigen von DDS Dateien

  Alt 29. Nov 2017, 09:51
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.
Funktioniert gut für die drei Formatvarianten (nachdem ich den Filestream-Parameter angepasst habe)!
Mit der Vorlage sollte der TE ggf. auch die anderen Formate implementieren können, wenn er sie denn braucht.
  Mit Zitat antworten Zitat
Jens01

Registriert seit: 14. Apr 2009
604 Beiträge
 
#9

AW: Anzeigen von DDS Dateien

  Alt 29. Nov 2017, 12:41
@creehawk
Dann würde ich sagen, glBitmap macht Dein Format nicht ....
Achtung: Bin kein Informatiker sondern komme vom Bau.
  Mit Zitat antworten Zitat
TiGü

Registriert seit: 6. Apr 2011
Ort: Berlin
2.498 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#10

AW: Anzeigen von DDS Dateien

  Alt 29. Nov 2017, 14:20
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;

Geändert von TiGü (29. Nov 2017 um 15:01 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2020 by Daniel R. Wolf