Entwickler-Ecke
Multimedia / Grafik - Kantenglättung und Doublebuffering
AXMD - Sa 05.03.05 14:04
Titel: Kantenglättung und Doublebuffering
Moin moin :)!
Irgendwie sind mir meine Zeigerdiagramme noch zu pixelig - und unschön flackern tun sie auch, wenn sie neu gezeichnet werden. Obwohl DoubleBuffering des Panels auf dem die PaintBox liegt beim Start auf true gestellt wird. Wär nett, wenn mir jemand sagen könnte wie ich das Flackern wegbekomme ;).
Außerdem wär sowas wie leichtes Antialiasing nicht schlecht. Hab bereits im Forum gesucht, aber nur einen Link zu einem Code aus dem SDC von Horst Kniebusch gefunden, der extrem langsam ist. Jemand eine bessere Idee für's Antialising? Muss nicht weiß Gott wie aufwendig sein, soll nur nicht ganz so pixelig aussehen.
Thx
AXMD
Lossy eX - Sa 05.03.05 15:10
Also ich benutze für DoubleBuffering immer ein - zwie zusätzliches Bitmaps und unterdrücke die WM_ERASEBKGND. Damit habe ich bisher noch nie Probleme gehabt.
Und zum Thema Antialising. Also je nachdem würde dir da wohl empfehlen auf OpenGL umzusteigen. Das hat dann noch den Vorteil, dass es auch Hardwarebeschleunigt ist. Kann aber sein, dass du zu viel von Hand zeichnen musst. Dann isses natürlich eher nachteilig als vorteilhaft. Anderfalls meine ich, das die
Graphics32 / G32 [
http://www.g32.org/] Komponenten so etwas können. Weiß es aber nicht 100%tig.
AXMD - Sa 05.03.05 18:48
Bei den Schweizern hab ich schon geschaut. Daher hatte ich ja die langsame Routine ;)
AXMD
delfiphan - So 06.03.05 03:11
Linien zeichnen mit Kantenglättung, sowas hab ich mal gemacht. Ist mit Pixels[X,Y] programmiert, also sofern nicht top Performance gefragt ist wirds reichen :) Für deine Zeiger reicht es alle male.
Wenn du die Prozedur willst, werd ich sie posten.
AXMD - So 06.03.05 10:35
| delfiphan hat folgendes geschrieben: |
Linien zeichnen mit Kantenglättung, sowas hab ich mal gemacht. Ist mit Pixels[X,Y] programmiert, also sofern nicht top Performance gefragt ist wirds reichen :) Für deine Zeiger reicht es alle male.
Wenn du die Prozedur willst, werd ich sie posten. |
Ja bitte :). Sieht nämlich ganz schön hässlich aus, wenn überall solche Zacken rausstehen ;)
AXMD
delfiphan - So 06.03.05 11:58
Okidoki, OpenGl ist sicher einiges schneller, aber hier ist sie: :)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88:
| procedure SLineTo(Canvas : TCanvas; X2,Y2 : Integer); Var dx, dy, X, Y, E, R, L, dT, dB, X1, Y1 : Integer; MainColor : TColor; S : Boolean; procedure Swap(var A, B : Integer); Var T : Integer; begin T := A; A := B; B := T; end; function Blend(const Color : TColor; I : Integer) : TColor; Type RGB = record R, G, B, A : byte; end; begin RGB(Result).R := (RGB(MainColor).R*I+RGB(Color).R*(2*L-I)) div 2 div L; RGB(Result).G := (RGB(MainColor).G*I+RGB(Color).G*(2*L-I)) div 2 div L; RGB(Result).B := (RGB(MainColor).B*I+RGB(Color).B*(2*L-I)) div 2 div L; RGB(Result).A := 0; end; begin with Canvas do begin X1 := PenPos.X; Y1 := PenPos.Y; dx := X2 - X1; dy := Y2 - Y1; if (dx=0) or (dy=0) then begin LineTo(X2,Y2); exit; end; MoveTo(X2,Y2); if abs(dy) > abs(dx) then begin Swap(dx,dy); Swap(X1,Y1); Swap(X2,Y2); S := True; end else S := False; if dx < 0 then begin Swap(X1,X2); Swap(Y1,Y2); dx := -dx; dy := -dy; end; if dy < 0 then begin R := -1; dy := -dy; end else R := 1; Y := Y1; E := 0; L := Round(Sqrt(dx*dx+dy*dy)); MainColor := Pen.Color; For X := X1 to X2 do begin dT := L-2*E; dB := L+2*E; if dT > L then begin if S then Pixels[Y-R,X] := Blend(Pixels[Y-R,X],dT-L) else Pixels[X,Y-R] := Blend(Pixels[X,Y-R],dT-L); dT := L; end; if dB > L then begin if S then Pixels[Y+R,X] := Blend(Pixels[Y+R,X],dB-L) else Pixels[X,Y+R] := Blend(Pixels[X,Y+R],dB-L); dB := L; end; if (dT >= 0) and (dB >= 0) then if S then Pixels[Y,X] := Blend(Pixels[Y,X],dT+dB) else Pixels[X,Y] := Blend(Pixels[X,Y],dT+dB); inc(E, dy); if E*2 >= dx then begin Y := Y + R; dec(E, dx); end; end; end; end; |
AXMD - So 06.03.05 12:05
Danke dir vielmals :)! Sieht schon super aus :)
AXMD
wdbee - So 06.03.05 12:12
Titel: Re: Kantenglättung und Doublebuffering
| AXMD hat folgendes geschrieben: |
Moin moin :)!
- und unschön flackern tun sie auch |
Schau mal in der Delphihilfe zu TControl.ControlStyle: csOpaque.
Wenn das Steuerelement die ganze Zeichenfläche überdeckt, werden unnötige Hintergrund-Zeichnenbefehle wohl unterdrückt. Vieleicht reicht das ja schon.
AXMD - So 06.03.05 12:18
Ich glaub heute ist nicht mein Tag :shock:
Delphi-Quelltext
1:
| PaintBox1.ControlStyle := csOpaque; |
ergibt
| Zitat: |
| [Fehler] cmpxmain.pas(772): Inkompatible Typen: 'TControlStyle' und 'Enumeration' |
:?: AXMD
delfiphan - So 06.03.05 12:23
;)
Gruss
AXMD - So 06.03.05 12:30
:autsch: :autsch: :autsch:
Danke dir
AXMD
AXMD - So 06.03.05 13:37
Hat vielleicht irgendjemand eine Routine, die Ellipsen glättet? Die Linien funktionieren dank delfiphans Routine super. Das Flckerproblem wurde auch behoben - nur die geglättete Ellipse wär noch das Tüpfelchen auf dem i ;)
AXMD
delfiphan - So 06.03.05 14:26
So, hab dir was ähnliches wie Canvas.Ellipse mit Kantenglättung per PM geschickt. Also das ganze funktioniert mehr oder weniger per Brute-Force, deswegen getrau ich mich fast nicht den Code hier zu posten ;)
retnyg - So 06.03.05 14:31
brute-force ist immer gut ;)
die gemeinde wartet auf deinen code, delfiphan... :mrgreen:
delfiphan - So 06.03.05 14:48
Grml... Okay hmmm, aber ich weise explizit darauf hin, dass diese Prozedur
in keiner Weise schnell ist! Ich hab das nu mal kurz auf die Beine gestellt, und mit Brute-Force programmiert, da die Geschwindigkeit nebensächlich ist.
Zur Anwendung: SEllipse(Canvas, MittelpunktX, MittelPunktY, RadiusX, RadiusY);
Die Prozedur ist also nicht gleich in der Anwendung wie Canvas.Ellipse(left,top,right,bottom)!
Flache Ellipsen (0 Pixel) können damit nicht gezeichnet werden, dann gibt es eine Division durch Null.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| Procedure SEllipse(Canvas: TCanvas; CX, CY, RX, RY : Integer); Const SuperSample = 16; Var X, Y : Integer; SX, SY : Integer; L : Integer; MainColor : TColor; function Blend(const Color : TColor; E : Extended) : TColor; Type RGB = record R, G, B, A : byte; end; begin RGB(Result).R := Trunc(RGB(MainColor).R*E+RGB(Color).R*(1-E)); RGB(Result).G := Trunc(RGB(MainColor).G*E+RGB(Color).G*(1-E)); RGB(Result).B := Trunc(RGB(MainColor).B*E+RGB(Color).B*(1-E)); RGB(Result).A := 0; end; begin with Canvas do begin MainColor := Pen.Color; For X := 0 to RX+1 do For Y := 0 to RY+1 do begin L := 0; if ((RX<=2) or (RY<=2)) or ((X*X/Sqr(RX-2)+Y*Y/Sqr(RY-2)>=1) and (X*X/Sqr(RX+2)+Y*Y/Sqr(RY+2)<=1)) then begin For SX := 0 to SuperSample-1 do For SY := 0 to SuperSample-1 do begin if (Sqr(X+SX/SuperSample)/Sqr(RX-0)+Sqr(Y+SY/SuperSample)/Sqr(RY-0)>1) and (Sqr(X+SY/SuperSample)/Sqr(RX+1)+Sqr(Y+SY/SuperSample)/Sqr(RY+1)<1) then inc(L); end; Pixels[CX+X,CY+Y] := Blend(Pixels[CX+X,CY+Y], L/SuperSample/SuperSample); Pixels[CX+X,CY-Y] := Blend(Pixels[CX+X,CY-Y], L/SuperSample/SuperSample); Pixels[CX-X,CY+Y] := Blend(Pixels[CX-X,CY+Y], L/SuperSample/SuperSample); Pixels[CX-X,CY-Y] := Blend(Pixels[CX-X,CY-Y], L/SuperSample/SuperSample); end; end; end; end; |
//Edit: kleiner Bugfix...
AXMD - So 06.03.05 14:50
Gut, ich habs jetzt eingebaut :). Sieht super aus.
Danke nochmal :)
AXMD
torud - Do 06.09.07 12:14
Titel: Ich würde dazu gern wissen
wie ich denn noch die Pen.Width mit übergeben kann, denn ich benötige Linien, die breiter als 1 Pixel sind. Ich habe schon versucht die PixelBreite vorher im Canvas zu setzen, aber das half auch nichts. Könnte man die procedure nochmals dahingehend anpassen, dass die gleich von der vorher eingestellten Canvas.Pen.Width übernommen wird?
Das wäre echt Klasse...
Danke Tom
delfiphan - Di 11.09.07 22:25
Für Kantenglättung: Schau dir GdiPlus an.
torud - Do 13.09.07 10:35
Hm, das ist doch mal ein Wort. Könntest Du mir bitte auch mitteilen, wo ich Infos dazu finde, mit denen Leute wie ich auch was anfangen können? Also möglichst ein Tutorial?
Konnte leider keins über Google finden...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!