Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Alphatransparent von Bildern bei Direct3D (https://www.delphipraxis.net/98278-alphatransparent-von-bildern-bei-direct3d.html)

SirThornberry 24. Aug 2007 11:19


Alphatransparent von Bildern bei Direct3D
 
Hallo,

ich bastel gerade etwas mit direkt3D herum und versuche ein 32bit-Bitmap unter berücksichtigung des Alphakanals im Raum darzustellen:

auf folgende Art und Weise klappt die Ausgabe jedoch ohne Transparanz (sondern so wie es in Paint dargestellt wird)
Delphi-Quellcode:
f3DDevice.SetTexture(0, fTexture);

f3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
f3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);

f3DDevice.SetStreamSource(0,f3DObj.Buffer3D,sizeof(TVertex));
f3DDevice.DrawPrimitive(D3DPT_TRIANGLELIST, 0, f3DObj.Count);
auf folgende Art und Weise sehe ich nur noch schwarze Flächen ohne Bild.
Delphi-Quellcode:
f3DDevice.SetTexture(0, fTexture);

f3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT);
f3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TEXTURE);

f3DDevice.SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);

f3DDevice.SetStreamSource(0,f3DObj.Buffer3D,sizeof(TVertex));
f3DDevice.DrawPrimitive(D3DPT_TRIANGLELIST, 0, f3DObj.Count);
Ich hätte es gern so das ich an bestimmten Stellen (bestimmt durch den Alphakanal) durch die Wand durchschauen kann und das sehe was hinter dieser Wand ist.

TGLDX 24. Aug 2007 12:27

Re: Alphatransparent von Bildern bei Direct3D
 
Für Alphatransparenz musst du die Textur mit D3DXCreateTextureFromFileEx erstellen und dabei einen Colorkey angeben, der dann transparent wird.
Danach musst du Alphatesting aktivieren, z.B. so:
Delphi-Quellcode:
 D3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,1);
 D3DDevice.SetRenderState(D3DRS_ALPHAREF,$1);
 D3DDevice.SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);

SirThornberry 24. Aug 2007 12:33

Re: Alphatransparent von Bildern bei Direct3D
 
was bestimmt der ColorKey? Vom Namen her würde ich sagen das er bestimmt welche Farbe transparent wird aber das wäre ja dann nicht alphatransparenz. Ich werd mal im msdn schauen und mich nochma melden falls ich fest hänge.

Neutral General 24. Aug 2007 12:47

Re: Alphatransparent von Bildern bei Direct3D
 
Zitat:

Zitat von SirThornberry
was bestimmt der ColorKey? Vom Namen her würde ich sagen das er bestimmt welche Farbe transparent wird aber das wäre ja dann nicht alphatransparenz. Ich werd mal im msdn schauen und mich nochma melden falls ich fest hänge.

Ich hab von dem ganzen keine Ahnung aber wie wärs mit

Delphi-Quellcode:
f3DDevice.SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_BLENDTEXTUREALPHA);
+

Delphi-Quellcode:
D3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,1);
D3DDevice.SetRenderState(D3DRS_ALPHAREF,$1);
D3DDevice.SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL);
und ohne den Colorkey? Is aber nur geraten. Das is das was mein Gehirn mir in der Situation sagen würde :mrgreen:

Gruß
Neutral General

SirThornberry 24. Aug 2007 12:50

Re: Alphatransparent von Bildern bei Direct3D
 
@Michael: So gehts nicht, da ist bei mir das ganze Bild transparent so als ob es gar nicht da wäre.

mein aktueller Stand (nachdem ich das von Michael probiert hab):
Delphi-Quellcode:
D3DXCreateTextureFromFileEx(f3DDevice, 'c:\temp\test01.bmp', D3DX_DEFAULT, D3DX_DEFAULT,
  D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8{ D3DFMT_UNKNOWN}, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR,
  D3DX_FILTER_LINEAR, 0, nil, nil, fTexture);
Delphi-Quellcode:
f3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,1);
f3DDevice.SetRenderState(D3DRS_ALPHAREF,1);
f3DDevice.SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);

f3DDevice.SetTexture(0, fTexture);

//Kamera etc. setzen

f3DDevice.SetStreamSource(0,f3DObj.Buffer3D,sizeof(TVertex));
f3DDevice.DrawPrimitive(D3DPT_TRIANGLELIST, 0, f3DObj.Count);

f3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE,0);

SirThornberry 25. Aug 2007 06:57

Re: Alphatransparent von Bildern bei Direct3D
 
also ich hab mir jetzt mal D3DRS_ALPHATESTENABLE angeschaut und es scheint so als ob man damit nur bestimmen kann ob gezeichnet wird oder nicht. Aber eine halbdurchsichtigkeit scheine ich damit nicht erreichen zu können. :cry:

mit folgendem Quelltext bekomme ich eine Alphatransparenz in Abhängigkeit von der Texturefarbe. Das muss doch auch irgendwie klappen in Abhängigkeit von dem Alphakanal.
Delphi-Quellcode:
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
ich hab auch schon mit den Konstanten D3DBLEND_SRCALPHA etc. herum gespielt aber ich bekomme nie das gewünschte Ergebnis (Alphatransparenz nur vom TextureAlphakanal abhängig)

Muss eventuell ein bestimmter CULL-Mode gesetzt sein damit es annähernd funktioniert?


ich hatte auch mal folgendes probiert:
Delphi-Quellcode:
D3DDevice.SetRenderState(D3DRS_ALPHATESTENABLE, 1);
D3DDevice.SetRenderState(D3DRS_ALPHAREF, 0);
D3DDevice.SetRenderState(D3DRS_ALPHAFUNC,D3DCMP_GREATER);
das müsste ja eigentlich bewirken das pixel mit einem Alphawert größer 0gezeichnet werden. Allerdings ist das Ergebnis das nichts gezeichnet wird. Oder verstehe ich da irgendwas falsch? (habs auch schon mit den geposteten Werten probiert was allerdings auch keinen Erfolg brachte)


Oder muss ich eventuell noch irgendwo einen Puffer auf 32bit setzen (außer den des Bildes) damit während der Ausgabe die 32bit erhalten bleiben und somit beachtet werden können?

ich hab eben noch folgendes probiert:
Delphi-Quellcode:
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
und
Delphi-Quellcode:
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_INVSRCALPHA);
D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCALPHA);
Und obwohl der Alphakanal des Bildes auf 127 steht (A8R8G8B8) ist entweder gar nichts zu sehen oder mit voller Deckkraft. Es scheint das mein Alphakanal irgendwie ignoriert wird.

turboPASCAL 25. Aug 2007 10:35

Re: Alphatransparent von Bildern bei Direct3D
 
Liegt es ggf. an deinem 32Bit-Bitmap ? Hat es denn einen Alphakanal und wie hast du es erstellt ?
Oder möchtest du ein "normales" Bitmap halb-transparent darstellen ?


-> http://www.two-kings.de/tutorials/dx...raphics10.html

(..hoffe mal den richtegen Link erwischt zu haben)

OregonGhost 25. Aug 2007 11:08

Re: Alphatransparent von Bildern bei Direct3D
 
Seufz, Browser abgestürzt vor dem Senden. Also nochmal die Kurzfassung.
Punkt 1: Die Blend-Operation, die du erreichen willst, lautet: dest.color = src.color * src.alpha + dest.color * (1 - src.alpha). Also:
Code:
D3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
D3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
D3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DDevice.SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
Punkt 2: Alphatesting hat mit Alphablending nichts zu tun.

Punkt 3: Das Ergebnis des Texture Stage soll bei dir den Alphakanal beinhalten. Das sind alles Default-Werte und sie sollten daher nicht eingestellt werden müssen, aber für alle Fälle:
Code:
D3DDevice.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
D3DDevice.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
D3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
Das hat zur Konsequenz, dass die modulierte Farbe (!) aus Textur und Diffuse als Farbe herauskommt, und der Alphakanal der Textur als Alphakanal. Erst danach findet das Blending mit dem RenderTarget statt.
Damit sollte eigentlich alles funktionieren. Wenn nicht, probiere folgendes:
Setze den Alphakanal im Diffuse deiner Vertices auf z.B. 0.5, und verwende als ALPHAARG1 D3DTA_DIFFUSE. Dann sollte eigentlich ein Per-Vertex-Alphablending funktionieren und es liegt zumindest nicht generell an einer Fehlkonfiguration. Du solltest deine Textur in dem Fall nochmal genauer untersuchen.

Edit: Turbopascals Link geht zwar minimal am Thema vorbei, aber ein Tutorial auf derselben Seite weiter ist eventuell für dich auch zielführend: http://www.two-kings.de/tutorials/dx...raphics11.html. Allerdings gehen die da nicht wirklich auf Hintergrundinformationen ein.

SirThornberry 25. Aug 2007 13:09

Re: Alphatransparent von Bildern bei Direct3D
 
Ich hab das ganze Projekt jetzt nochmal neu aufgesetzt und es funktioniert :shock:

folgende Zeilen haben mich in meinem neuen Projekt zum Ergebnis geführt
Delphi-Quellcode:
//Alphaeinstellungen
f3DDevice.SetRenderState(D3DRS_ALPHABLENDENABLE, Cardinal(True));   //alpha blending enabled ( NEW )
f3DDevice.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);         //source alpha ( NEW )
f3DDevice.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
//Alpha aus Farbe beziehen
f3DDevice.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
Seltsamer Weise bewirken diese im alten Projekt rein gar nichts. Da ich aber schon einen Tag lang probiert hab fehlt mir jetzt der Elan zu Suchen woran es lag.

OregonGhost 25. Aug 2007 13:38

Re: Alphatransparent von Bildern bei Direct3D
 
In meiner Firma sprechen wir in diesem Zusammenhang im Allgemeinen von Sonnenflecken oder Bitflimmern.

Aber ernsthaft, in vielen Fällen liegt es daran, dass man davon ausgeht, dass alle Werte auf Default stehen, obwohl sie irgendwo anders im Projekt verändert wurden. Deshalb schadet es im Zweifel nicht, alle Werte, die das Ergebnis beeinflussen könnten, passend zu setzen. Dann wird man vor allem bei unsauberen Treibern etwas glücklicher werden.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:33 Uhr.
Seite 1 von 2  1 2      

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