Seite 1 von 1

DrawImage mit AlphaChannel

Verfasst: 07.08.2020 16:11
von diceman
Hallo ihr Lieben,
Ich brech mir hier grad seit rund einer Stunde einen ab und komme auf keinen grünen Zweig. Ich arbeite hauptsächlich mit Sprites, damit habe ich keine Probleme ...
Jetzt möchte ich allerdings mittels

Code: Alles auswählen

If StartDrawing(SpriteOutput(mySprite))
...
zwei Bilder übereinander in das Sprite hineinzeichnen. Das erste Bild ist quasi der Background, das zweite Bild soll mit der Farbe schwarz als Alpha-Channel transparent darüber gezeichnet werden. Ein Sprite in einanderes hineinzuzeichnen funktioniert nicht, also ist DrawImage, bzw. DrawAlphaImage mein Mittel der Wahl, oder? Aber was, wie und mit welchen DrawingMode() Parametern? Transparent? ALphaBlend? AlphaChannel? Brauche ich den BackColor-Befehl()? RGB? RGBA? Habe mittlerweile, glaube ich, alle Kombinationen durch, und bin so schlau wie zuvor.

Code: Alles auswählen

DrawImage(ImageID(backgroundIMG),0,0)
DrawingMode(#PB_2DDrawing_AlphaChannel)
BackColor(RGB(0,0,0))
DrawImage(ImageID(overlayIMG),0,0)
funktioniert z.B. nicht. Da ist dann nur der Background zu sehen. :(
Und

Code: Alles auswählen

DrawImage(ImageID(backgroundIMG),0,0)
DrawingMode(#PB_2DDrawing_Transparent)
DrawImage(ImageID(overlayIMG),0,0)
funktioniert mit DrawText() problemlos, allerdings nicht mit Bildern (da ist dann nur das overlay-Bild zu sein).
Vielen Dank!

Re: DrawImage mit AlphaChannel

Verfasst: 08.08.2020 05:42
von STARGÅTE
Dein Freund ist #PB_2DDrawing_CustomFilter.
Dort kannst du definieren, wie zwei images übereinander geblendet werden sollen:

Code: Alles auswählen

Procedure MyCustomFilter(X, Y, Source, Destination)
	If Source & $FFFFFF <> $000000
		ProcedureReturn Source      ; benutze neue Farbe
	Else
		ProcedureReturn Destination ; benutze alte Farbe
	EndIf
EndProcedure
Beispiel:

Code: Alles auswählen

Enumeration
	#Window
	#Gadget
	#Image1
	#Image2
EndEnumeration





OpenWindow(#Window, 0, 0, 128, 128, "Vector Canvas Gadget", #PB_Window_MaximizeGadget|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget|#PB_Window_ScreenCentered)
CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window), #PB_Canvas_Keyboard)

CreateImage(#Image1, 128, 128)
If StartDrawing(ImageOutput(#Image1))
	Box(0, 0, 64, 64, $FF0000)
	Box(64, 0, 64, 64, $00FF00)
	Box(0, 64, 64, 64, $0000FF)
	Box(64, 64, 64, 64, $00FFFF)
	StopDrawing()
EndIf

CreateImage(#Image2, 128, 128)
If StartDrawing(ImageOutput(#Image2))
	Box(0, 0, 128, 128, $FFFFFF)
	Circle(64, 64, 64, $000000)
	StopDrawing()
EndIf


Procedure MyCustomFilter(X, Y, Source, Destination)
	If Source & $FFFFFF <> $000000
		ProcedureReturn Source      ; benutze neue Farbe
	Else
		ProcedureReturn Destination ; benutze alte Farbe
	EndIf
EndProcedure

If StartDrawing(CanvasOutput(#Gadget))
	DrawingMode(#PB_2DDrawing_Default)
	DrawImage(ImageID(#Image1), 0, 0)
	DrawingMode(#PB_2DDrawing_CustomFilter)
	CustomFilterCallback(@MyCustomFilter())
	DrawImage(ImageID(#Image2), 0, 0)
	StopDrawing()
EndIf


Repeat
	
	Select WaitWindowEvent()
		
		Case #PB_Event_CloseWindow
			Break
		
	EndSelect
	
ForEver

End

Re: DrawImage mit AlphaChannel

Verfasst: 08.08.2020 13:30
von diceman
Ich danke dir! :)

Ist doch etwas aufwendiger; fast schon Overkill für das simple Resultat. Also die Algorithmen dahinter - wenn ich das richtig verstehe, ersetze ich jedes einzelne Pixel der transparenten Farbe durch das Pixel darunter?
Scheint, als würde #PB_2DDrawing_Transparent nur für DrawText() so straightforward zu funktionieren, wie man das erwartet ...
Muß dazu sagen, daß ich mich nie in die Callback-Funktionen eingearbeitet habe, und ich mir zum Paradigma gemacht habe, niemals Code zu verwenden, den ich nicht selbst zu 100% verstehe.
Daher sei mir nicht böse, daß ich das vorerst nicht so übernehme - sollte ich in Zukunft mal mehr von der Materie verstehen, dann weiß ich jetzt, wo ich nachschauen kann ...

Man wird ja auch kreativ mit der Zeit ... habe mir mittlerweile mit einem kleinen "Hack" geholfen: Ich zeichne 2 Sprites via DisplayTransparentSprite() übereinander in die obere linke Bildschirmposition, und grabbe mir dann mit GrabSprite() das neue Sprite. Das funktioniert ohne FlipBuffers(), der Spieler bekommt also nichts davon mit.

Trotzdem nochmal vielen lieben Dank für deine Mühe. :)

Re: DrawImage mit AlphaChannel

Verfasst: 08.08.2020 18:59
von GlassJoe
diceman hat geschrieben:Ich danke dir! :)

Ist doch etwas aufwendiger; fast schon Overkill für das simple Resultat. Also die Algorithmen dahinter - wenn ich das richtig verstehe, ersetze ich jedes einzelne Pixel der transparenten Farbe durch das Pixel darunter?
Scheint, als würde #PB_2DDrawing_Transparent nur für DrawText() so straightforward zu funktionieren, wie man das erwartet ...
Muß dazu sagen, daß ich mich nie in die Callback-Funktionen eingearbeitet habe, und ich mir zum Paradigma gemacht habe, niemals Code zu verwenden, den ich nicht selbst zu 100% verstehe.
Daher sei mir nicht böse, daß ich das vorerst nicht so übernehme - sollte ich in Zukunft mal mehr von der Materie verstehen, dann weiß ich jetzt, wo ich nachschauen kann ...

Man wird ja auch kreativ mit der Zeit ... habe mir mittlerweile mit einem kleinen "Hack" geholfen: Ich zeichne 2 Sprites via DisplayTransparentSprite() übereinander in die obere linke Bildschirmposition, und grabbe mir dann mit GrabSprite() das neue Sprite. Das funktioniert ohne FlipBuffers(), der Spieler bekommt also nichts davon mit.

Trotzdem nochmal vielen lieben Dank für deine Mühe. :)
Mann muss nicht immer jede Funktion versehen bevor mann sie übernimmt :) ich raff bis heute nicht alles aus dem Callback Zeugs (und einiges anderes, ich glaub ich hab in 15 Jahren nicht einmal with benutzt) aber so lange der Code nicht zu ausuffernt ist (Stargates Code ist doch relativ straff und übersichtlich) und mann den Haupteil davon versteht, passt es doch.

Jedenfalls haben wir es noch gut, wir haben eigentlich keine Grenzen und das meiste ist relativ straight forward, du müsstest mal gucken wie die sich früher mit reinem Assembler auf den alten Konsolen abplagen mussten :lol:

Paar Sprite per Line, 4 Farben pro Sprite, 64 Ingesammt usw usw und das dann noch irgendwie auf ein 2-4MB Modul verpacken :freak:

Ich glaub selbst ohne Assembler kann mann viel von dem Typ (der Haupt Programmierer von Sonic 3D, Toystory, und von Highlander auf'm Amiga) lernen, die Denkweise und Wege die er benutzt hat, sind sehr interessant.
https://www.youtube.com/watch?v=ilolCcB8Om8

https://www.youtube.com/watch?v=c-aQvP7CUAI (Sonic 3D's Impossibly Compressed Logo FMV - How's it done?)
https://www.youtube.com/watch?v=C9A6K5RQ2JQ (How we coded the World's First 3D chase level)
https://www.youtube.com/watch?v=i9bkKw32dGw (Why does PUNCHING Sonic 3D trigger a Secret Level Select?)

Für alle die den wohl übelsten Code der Welt (auf'm Sega Saturn) sehen wollen :mrgreen:
https://www.youtube.com/watch?v=CPaNNiB2H-s