Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi DirectX 8 - Transparente Farbe (https://www.delphipraxis.net/137821-directx-8-transparente-farbe.html)

XoRiC 29. Jul 2009 00:36


DirectX 8 - Transparente Farbe
 
Hallo,

nachdem ich nun eine Menge Tutorials durchgearbeitet und die entlegensten Seiten im Internet aufgesucht habe bin ich doch hier gelandet. Ich hoffe niemand nimmt mir den Post böse, aber tatsächlich hat keine der von mir besuchten Seiten mein Problem gelöst.
Ich versuche gerade den Einstieg in DirectX Programmierung zu schaffen. Ich benutze Delphi 6 und DirectX 8. DirectX 9 habe ich mir angeschaut, möchte aber bei DirectX 8 bleiben.

Ich hab schon eine Menge Effekte ausprobiert und alle funktionieren wunderbar.
Nur an einer (vermutlich einfachen) Sache bin ich bisher keinen Schritt vorangekommen:

Es soll eine Farbe festgelegt werden, die komplett durchsichtig erscheint.

Nichts was ich bisher probiert habe hat funktioniert. Anfangs lag der Verdacht bei den verwendeten Bitmaps (BMP), da diese vielleicht keinen Alphachannel unterstützen. Durch den Umstieg auf Targas (TGA) hat sich jedoch nichts geändert.

Für den DirectX-Device habe ich einige Einstellungen durchprobiert:
Delphi-Quellcode:
SetRenderState( D3DRS_ALPHABLENDENABLE, 1);
SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
doch auch das alles hat nichts geholfen.

Meine Frage also: Wie kann ich z.B. den schwarzen Hintergrund einer Textur komplett transparent bekommen, sodass der Hintergrund durchscheint?

Vielen Dank für Tipps und Links,
Gruß Xoric

ich2 29. Jul 2009 07:23

Re: DirectX 8 - Transparente Farbe
 
Hallo Xoric...

es ist zwar schon ein wenig her, aber ich habe mal wieder die source-codes meiner 3D-Engine herausgekramt:
und da drinnen heißt es so für den Transparent-Teil:

Delphi-Quellcode:

 if Model.transparent then begin
   //transparent
   D3DDev8.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
//   D3DDev8.SetRenderState(D3DRS_SRCBLEND, Integer(D3DBLEND_INVSRCCOLOR));
//   D3DDev8.SetRenderState(D3DRS_DESTBLEND, Integer({D3DBLEND_ONE}D3DBLEND_SRCALPHA));
   D3DDev8.SetRenderState(D3DRS_SRCBLEND, Integer(D3DBLEND_srcalpha));
   D3DDev8.SetRenderState(D3DRS_DESTBLEND, Integer(D3DBLEND_invsrccolor));
   D3DDev8.SetRenderState(D3DRS_CULLMODE, Ord(D3DCULL_none));

   D3DDev8.SetRenderState(D3DRS_ZWRITEENABLE, Ord(false));
 end else begin
   //nicht transparent
   D3DDev8.SetRenderState(D3DRS_ALPHABLENDENABLE, 0);

   D3DDev8.SetRenderState(D3DRS_CULLMODE, Ord(D3DCULL_CW));
  if not mirrortest then
   D3DDev8.SetRenderState(D3DRS_CULLMODE, Ord(D3DCULL_CCW)); //CW alle normalen gewendet
  if RenderCubeMap then
   D3DDev8.SetRenderState(D3DRS_CULLMODE, Ord(D3DCULL_none));

   D3DDev8.SetRenderState(D3DRS_ZWRITEENABLE, Ord(true));
 end;
...dann gibt es da noch die Möglichkeit Color-Keying zu betreiben, also bestimmte Farben einer Textur auszublenden:

Delphi-Quellcode:
//ColorKey -> freie Stellen in der Texture
 if Model.colorkey_enable then begin
  // Enable Aplha Test (colorkeying)
  D3DDev8.SetRenderState(D3DRS_ALPHAREF, model.alpharef );
  D3DDev8.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
  D3DDev8.SetRenderState(D3DRS_ALPHATESTENABLE, 1);

  // Set texture stages (colorkeying)
  D3DDev8.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  D3DDev8.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

  D3DDev8.SetRenderState(D3DRS_CULLMODE, Ord(D3DCULL_NONE));
 end;
..vielleicht hilft es dir weiter...

mfg

XoRiC 29. Jul 2009 09:20

Re: DirectX 8 - Transparente Farbe
 
Hallo ich2,

erst mal vielen Dank für deine Antwort. Dein Code sah wirklich vielversprechend aus, es will bei mir jedoch einfach nicht funktionieren. Ich zeige besser mal meine Initialisierung:

Delphi-Quellcode:
 
  with Params do begin            // Params : TD3DPRESENTPARAMETERS
    BackBufferWidth := 640;
    BackBufferHeight := 480;
    BackBufferCount := 1;
    BackBufferFormat := D3DFMT_A8R8G8B8;
    SwapEffect := D3DSWAPEFFECT_DISCARD;
    hDeviceWindow := 0;
    Windowed := true;
  end;

  // DirectX Instanz erstellen
  DirectX := Direct3DCreate8(D3D_SDK_VERSION);
  DirectX.CreateDevice( D3DADAPTER_DEFAULT,    // Default Grafikkarte
                        D3DDEVTYPE_HAL,        
                        Form1.Handle,          // Handle, auf das gezeichnet werden soll
                        D3DCREATE_HARDWARE_VERTEXPROCESSING, // Hardwarebeschleunigung für Vertex
                        Params,                // Oben gesetzte Parameter verwenden
                        Device);               // Device : IDirect3DDevice8 

  // Sprite erstellen
  D3DXCreateSprite(Device, Sprite);      // Sprite : ID3DXSprite

                                   
  // Enable Alpha Test (colorkeying)
  Device.SetRenderState(D3DRS_ALPHAREF, $000000FF );
  Device.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
  Device.SetRenderState(D3DRS_ALPHATESTENABLE, 1);

  // Set texture stages (colorkeying)
  Device.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
  Device.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

  Device.SetRenderState(D3DRS_CULLMODE, Ord(D3DCULL_NONE));

Die letzten 8 Codezeilen habe ich aus ich2s Post übernommen :)
(Habe für model.alpharef die Werte 0 und $000000FF getestet)

Ich lade dann eine Textur Test.bmp aus meinem Programmordner:

http://img266.imageshack.us/img266/1386/testrzb.png

Delphi-Quellcode:
3DXCreateTextureFromFile(Device, PChar('Test.bmp'), Texture);    // Texture : IDirect3DTexture8

Zuletzt zeichne ich sie dann in doppelter Ausführung auf den Background Buffer (verschoben):

Delphi-Quellcode:
  Device.Clear(0, nil, D3DCLEAR_TARGET, $FF000000, 0, 0);
  Device.BeginScene;

     Sprite._Begin;

     Target.x := 0;            // Target : TD3DXVector2
     Target.y := 0;

     RotCenter.x := 0;         // RotCenter : TD3DXVector2
     RotCenter.y := 0;
   
     Sprite.Draw(Texture,
                 nil,          // Gesamte Textur
                 nil,          // @scaleVect, bei nil wird nicht skaliert
                 @RotCenter,   // @rotationCenter,
                 0,            // Rotation
                 @Target,      // @TranslationVector
                 Color);

     Target.x := 80;
     Target.y := 35;

     Sprite.Draw(Texture,
                 nil,          // Gesamte Textur
                 nil,          // @scaleVect, bei nil wird nicht skaliert
                 @RotCenter,   // @rotationCenter,
                 0,            // Rotation
                 @Target,      // @TranslationVector
                 Color);

    Sprite._End;

  Device.EndScene;
  Device.Present(nil, nil, 0, nil);

Das Ergebnis ist immer das gleiche: von Transparenz keine Spur:

http://img266.imageshack.us/img266/8974/test3k.jpg


Habe ich irgendwas falsch gemacht? Falls ja, wo liegt mein Fehler?
Vielen Dank schonmal im Voraus für jede Form von Hilfe,
ich verzweifle noch daran.

Lieben Gruß,
Xoric

XoRiC 29. Jul 2009 10:08

Re: DirectX 8 - Transparente Farbe
 
Habe das Problem in den Griff bekommen. Falls es jemanden interessieren sollte:
Beim Laden der Textur fehlte in meinem Code die Angabe eines Colorkeys.
Diese als Colorkey spezifizierte Farbe wird transparent gesetzt.

Indem ich die Zeile

Delphi-Quellcode:
3DXCreateTextureFromFile(Device, PChar('Test.bmp'), Texture);    // Texture : IDirect3DTexture8
durch den Befehl

Delphi-Quellcode:
D3DXCreateTextureFromFileEx(Device, PChar('Test.bmp'), D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN,
  D3DPOOL_MANAGED, D3DX_FILTER_TRIANGLE, D3DX_FILTER_BOX, D3DCOLOR_XRGB(0,0,0), 0, 0, Texture);
ersetzt habe, wurde der Fehler behoben und die Farbe schwarz ist nun transparent.


http://img204.imageshack.us/img204/9145/test4l.jpg

Gruß an alle,
Xoric


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:46 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz