[D3D] Alpha-Kanal in der Textur wird scheinbar nicht berücksichtigt



  • Ich will das Blätterdach eines Baums als Kuppel mit einer Textur überziehen, die an manchen Stellen durchsichtig ist. Ich lade die Textur ordentlich im Format A8R8G8B8 und schalte in den Renderstates Alphablending an:

    device.RenderState.AlphaBlendEnable = true;
    device.RenderState.AlphaSourceBlend = Blend.SourceAlpha;
    device.RenderState.AlphaDestinationBlend = Blend.InvSourceAlpha;  // Das lese ich so oft, leuchtet mir aber noch nicht ein
    

    Die Textur ist ein PNG-Bild mit Alpha-Kanal. Gerendert wird dann alles so, als gäbe es den Alpha-Kanal nicht. Ich hab spaßeshalber den transparenten Bereich auf 0x00FF00FF gesetzt und tatsächlich wird das Blätterdach einfach in Magenta gerendert. Wo könnte ich was vergessen haben?



  • In den Texture Stage States?

    Bye, TGGC



  • Meinst du dieses AlphaOperation und die AlphaArguments? Sieht im Moment so aus:

    device.TextureState[0].ColorOperation = TextureOperation.Modulate;
    device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
    device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
    device.TextureState[0].AlphaOperation = TextureOperation.Modulate;
    device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
    device.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse;
    

    Wenn ich beim Alpha etwas ändere, scheint das keine Auswirkungen zu haben. Muss das Material bestimmte Voraussetzungen erfüllen, damit das funktioniert oder ist das unwesentlich? Ich setze das Diffuse und Ambient davon auf Transparent.



  • Setzt du die Sachen eigentlich auch?

    Bye, TGGC



  • Sicher, so wie es da steht:

    setupLights();
    		setupMatrices();
    
    		for( int i = 0;  i < meshMaterials.Length;  ++i )
    		{
    			// Set the material and texture for this subset.
    			Material material = meshMaterials[i];
    			material.Diffuse = Color.Transparent;
    			material.Ambient = Color.Transparent;
    			device.Material = material;
    
    			device.SetTexture(0, meshTextures[i]);
    			device.TextureState[0].ColorOperation = TextureOperation.Modulate;
    			device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
    			device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
    			device.TextureState[0].AlphaOperation = TextureOperation.Modulate;
    			device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
    			device.TextureState[0].AlphaArgument2 = TextureArgument.Diffuse;
    
    			// Draw the mesh subset.
    			mesh.DrawSubset(i);
    		}
    

    plus BeginScene und der Kram. Die Textur wird auch korrekt geladen, wenn ich sie nämlich mit dem Sprite-Zeugs rendere:

    Sprite sprite = new Sprite(device);
    		sprite.Begin(SpriteFlags.AlphaBlend);
    		sprite.Draw(meshTextures[1], Rectangle.Empty, Vector3.Empty, Vector3.Empty, Color.White);
    		sprite.End();
    		sprite.Dispose();
    

    Wird sie brav mit nem transparenten Bereich gerendert.



  • Kenne mich mit der C# Syntax nicht aus. Keine Ahnung ob diese Zuweisungen äquivalent zu SetTextureStageState(blubb) sind.

    Bye, TGGC



  • Ich auch nicht, nachdem die Dokumentation sich überall auf 3 Zeilen beschränkt. Die Funktion gibt's nämlich auch. Würdest du es so machen?

    device.SetTextureStageState(0,
    										TextureStageStates.ColorOperation |
    										TextureStageStates.ColorArgument1 |
    										TextureStageStates.ColorArgument2 |
    										TextureStageStates.AlphaOperation |
    										TextureStageStates.AlphaArgument1 |
    										TextureStageStates.AlphaArgument2,
    										true );
    

    Den letzten Parameter check ich nicht nicht, der ist drei mal überladen und in der C++-Version einfach ein DWORD. Dazu steht dann nur

    State value to set. The meaning of this value is determined by the Type parameter.

    Du kannst mir gerne auch sagen, wie es in C++ gemacht wird, das Übersetzen krieg ich schon hin.



  • Eher so
    device.SetTextureStageState(0, TextureStageStates.ColorOperation, TextureOperation.Modulate );

    So gehts zumindest in C/C++.

    Bye, TGGC



  • Das haut mit den Datentypen nicht hin. Nur mal rein angenommen, die Zuweisungen oben alle machen das, was könnte dann noch schief gelaufen sein?



  • Ok, ich hab die Funktion jetzt gecheckt und es funktioniert auch. Danke dir!

    device.SetRenderState(RenderStates.SourceBlend, (int)Blend.SourceAlpha);
    			device.SetRenderState(RenderStates.DestinationBlend, (int)Blend.InvSourceAlpha);
    
    			//This enables Alpha Blending
    			device.SetRenderState(RenderStates.AlphaBlendEnable, true);
    

    Der letzte Parameter ist u.a. mit int überladen und man muss dann von den verschiedenen enums nach int casten, in C++ ist das halt einfach ein DWORD. Wäre vielleicht schöner gewesen, mit den verschiedenen enums zu überladen, aber wahrscheinlich kann man das eben auch mit den Zuweisungen weiter oben schön einstellen. Das werde ich jetzt noch genauer anschaun.



  • Optimizer schrieb:

    Der letzte Parameter ist u.a. mit int überladen und man muss dann von den verschiedenen enums nach int casten, in C++ ist das halt einfach ein DWORD.

    Nein, da sind es auch enums. Aber C++ macht enum nach int implizit.

    Bye, TGGC


Anmelden zum Antworten