Seite 1 von 2
Antialiased Drawing
Verfasst: 20.03.2012 17:07
von Lambda
Kennt jemand einen Filter dafür? Gerade RoundedBox macht sehr unschöne Ränder. Muss nicht gerade eine Lösung für Spiele sein. (CanvasGadget)
lg

Re: Antialiased Drawing
Verfasst: 20.03.2012 17:40
von NicTheQuick
Re: Antialiased Drawing
Verfasst: 20.03.2012 17:56
von Lambda
Ein Filter wäre mir etwas lieber als der GDI extra Kram ^^
Re: Antialiased Drawing
Verfasst: 20.03.2012 19:46
von STARGÅTE
Dafür kannst du den Filter von hier nutzen:
RoundImageFilterCallback
Den Filter kannst du aber nur auf eine Box anwenden.
Für Lines und Ellipsen wäre ein solcher Filter einfach zu langsam.
Dann lieber GDI+
Re: Antialiased Drawing
Verfasst: 20.03.2012 21:12
von Lambda
Und er funktioniert auch bei Verwendung von Gradianten? Die Box ist nämlich nichtmehr sichtbar wenn ich es verwende.
Re: Antialiased Drawing
Verfasst: 20.03.2012 23:50
von STARGÅTE
Klar geht das.
Der CustomFilterCallback macht nix anderes, als die Farbe die theoretisch gezeichnet wird und die Farbe die der Untergrund hat, an den Callback zu geben. Dort kannst du dann das "verhalten" (im Normalfall AlphaBlend(SourceColor, DestinationColor)) ändern.
Hier ein Beispiel für ein LinearGradient mit einer Box die aber dann zum Kreis gefiltert wird, welcher 25 Pixel Unschärfe-Rand hat.
Code: Alles auswählen
Enumeration
#Window
#Gadget
EndEnumeration
Procedure FilterCallback(X.i, Y.i, SourceColor, DestinationColor)
; X, Y - Koordinaten
; SourceColor - Farbe die gezeichnet werden soll (vom Gradien oder die angabe in Box)
; DestinationColor - Untergrundfarbe
Protected Distance.f = Sqr(Pow(X-OutputWidth()/2,2)+Pow(Y-OutputHeight()/2,2))
Protected Alpha.a
If Distance > 125
SourceColor = $00000000
ElseIf Distance > 100
Alpha = Alpha(SourceColor)*(125-Distance)/25
SourceColor & $00FFFFFF | Alpha << 24
EndIf
ProcedureReturn AlphaBlend(SourceColor, DestinationColor)
EndProcedure
OpenWindow(#Window, 0, 0, 256, 256, "Beispiel", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
If StartDrawing(CanvasOutput(#Gadget))
Box(0, 0, OutputWidth()/2, OutputHeight()/2, $000000)
Box(OutputWidth()/2, OutputHeight()/2, OutputWidth()/2, OutputHeight()/2, $000000)
DrawingMode(#PB_2DDrawing_Gradient|#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_CustomFilter)
CustomFilterCallback(@FilterCallback())
LinearGradient(0, 0, OutputWidth()-1, OutputHeight()-1)
GradientColor(0.0, $FFFF8000)
GradientColor(1.0, $FF00FF80)
Box(0, 0, OutputWidth(), OutputHeight())
StopDrawing()
EndIf
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow

Re: Antialiased Drawing
Verfasst: 21.03.2012 00:12
von Lambda
Absolut perfektes Beispiel.
Nur leider versteh ich die Gebrauchsweise davon nicht richtig. Wie kann ich zb den radius so minimieren das daraus nur weiche kanten werden. Oder wenn ich für die nächste Form eine ganz andere Farbe verwende?
Re: Antialiased Drawing
Verfasst: 21.03.2012 00:36
von STARGÅTE
Hier mal etwas detailierter was passiert, wenn du ein CustomFilterCallback benutzt:
- Nehmen wir mal an, das gesamte Bild (200 x 200 Pixel) ist vorher Rot.
- Du rufst nun (nach CustomFilterCallback) den Befehl Box(50, 50, 100, 100, RGBA(0,0,255,128))
- Ohne den Callback würde nun eine Box mit halbtransparentem Blau auf das Rot gezeichnet werden.
- Durch den Filter passiert nun folgendes:
- Jeder Pixel, der durch Box() gezeinet werden würde, wird mit seinen Koordinaten, der Untergrundfarbe (Rot) und der Zeichnen-Farbe (halbtransparentes Blau) an den Filter gegeben.
- Im Filter errechnen ich nun zB den Abstand des Pixels zum Bildzentrum (für Kreis).
- Ist der Abstand > 50 Pixel, wird der Pixel nicht gezeichnet.
- ist der Abstand (Float) zwischen 49 und 50 Pixel (normale Kantenglättung), muss er "geglättet" werden, also ändere ich den Alpha-Wert der Zeichenfarbe, um den Pixel abzuschwächen.
- Ist der Abstand <= 99 Pixel, wird der Pixel normal gezeichnet.
Code: Alles auswählen
Enumeration
#Window
#Gadget
EndEnumeration
Global Radius.f = 50
Procedure FilterCallback(X.i, Y.i, SourceColor, DestinationColor)
Protected Distance.f = Sqr(Pow(X-OutputWidth()/2,2)+Pow(Y-OutputHeight()/2,2))
Protected Alpha.a
If Distance > Radius
SourceColor = $00000000
ElseIf Distance > Radius-1
Alpha = Alpha(SourceColor)*(Radius-Distance)
SourceColor & $00FFFFFF | Alpha << 24
EndIf
ProcedureReturn AlphaBlend(SourceColor, DestinationColor)
EndProcedure
OpenWindow(#Window, 0, 0, 200, 200, "Beispiel", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
If StartDrawing(CanvasOutput(#Gadget))
Box(0, 0, 200, 200, RGBA(255,0,0,255))
DrawingMode(#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_CustomFilter)
CustomFilterCallback(@FilterCallback())
Box(50, 50, 100, 100, RGBA(0,0,255,128))
StopDrawing()
EndIf
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Das heißt, was genau der Filter machen soll, muss du selber schreiben.
Was bei einem Kreis noch einfach ist (Glättung) ist bei einer Linie schon schwerer.
Das heißt, herauszufinden, wie der zu zeichnende Pixel verändert werden muss. (mehr Berechungen).
Re: Antialiased Drawing
Verfasst: 21.03.2012 03:51
von Lambda
Schön erklärt

mal sehn was sich so zusammenklopfen lässt.
Etwas offtopic aber ich möchte dazu kein extra Thread eröffnen. Wenn ich eine "Ribbon" ähnliche Toolbar programmiere ist das rechtlich ok? Es wäre vom funktionellem wie ein Panel mit dem man zwischen Toolbars schalten kann, was aber ähnlich aussieht wie eine Ribbonleiste.
Re: Antialiased Drawing
Verfasst: 21.03.2012 14:34
von bobobo
ämm -- Bilder muss man gar nicht malen zum Zeitpunkt wenn man sie braucht sondern kann
die auch vorab basteln und dann passend einbauen. Dann sollte das mit dem Antialiasing eigent-
lich gar kein Problem mehr sein.
Das sollte auch energetisch günstiger sein
