Autor |
Beitrag |
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Fr 03.09.10 17:41
Gibt es für diesen Code evtl noch ne bessere Möglichkeit? Bei einer grossen Fläsche hat er ganz schön zu Zeichen/zu rechnen!
Was dann natürlich zu leichten Verzögerungen führt. Im Prinzip könnte man damit leben. Man vergrössert ja nicht ständig die Fläche auf 2600x1024  Es könnte aber sein das es besser geht!?
Die beiden Variablen peakbufl/peakbufr sind Bitmaps.
DoubleBuffered für die beiden Painboxen ist auch schon an.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| for ypos:= 0 to peakbufr.Width do begin peakbufl.Canvas.Pen.Color:= RGB( Trunc(102+ (255 - 102) / peakbufl.Height *ypos) , Trunc(113+ (255 - 113) / peakbufl.Height *ypos) , Trunc(126+ (255 - 126) / peakbufl.Height *ypos) ); peakbufl.Canvas.MoveTo(0, ypos); peakbufl.Canvas.LineTo(peakbufl.Width, ypos); peakbufr.Canvas.Pen.Color:= RGB( Trunc(102+ (255 - 102) / peakbufr.Height *ypos) , Trunc(113+ (255 - 113) / peakbufr.Height *ypos) , Trunc(126+ (255 - 126) / peakbufr.Height *ypos) ); peakbufr.Canvas.MoveTo(0, peakbufr.Height - ypos); peakbufr.Canvas.LineTo(peakbufr.Width, peakbufr.Height - ypos); end; |
Währe schon, wenn es dafür was optimaleres gäbe.
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Fr 03.09.10 20:27
Generell kann ich in Sachen Bitmaps nur die Graphics32 empfehlen. Ob die bei den Zeichenroutinen auch schnell wie beim Pixelzugriff sind, weiß ich nicht.
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.09.10 16:59
Externes Bitmap erzeugen; dadrin zeichnen mit ScanLine; Backbuffer mit BitBlt auf's Front-Bitmap schieben.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Sa 04.09.10 22:03
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.09.10 22:08
Such einfach mal hier im Forum nach SCANLINE, da findet sich genug
Edit: Ach ja, glatt vergessen:
ALF hat folgendes geschrieben : | BenBE hat folgendes geschrieben : | dadrin zeichnen mit ScanLine; | ist Scanline schneller als Canvas? |
Ja.
Wobei die Frage so nicht ganz stimmt, weil Scanline nur ein Teil der TCanvas-Klasse ist. Insgesamt hängt da eine etwas andere Vorgehensweise dran. Von daher ist das mit dem Ja nur für den Fall, dass man weiß, was man tut 
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Sa 04.09.10 22:14
extern heißt: du hast ein canvas auf dem formular, was sichtbar ist und tbitmap, was nicht sichtbar ist.
dann zeichnest du auf das bitmap und danach kopierst du das per bitblt auf die canvas auf dem form.
und scanline verwenden da schneller als moveto/lineto
BTW: Du hast ein haufen multiplikationen und divisionen in der schleife.
1) "ypos" dürfte ein fehler sein, oder? weil du teils durch die höhe aber ypos läuft durch die breite...
da solltest du nochmal gucken. besonders der fall, dass das canvas breiter als hoch ist. dann kommst du mit moveto(0,ypos) nämlich außerhalb an...
vermutlich in der for-schleife ein "to peakbufr.width"
2) überleg mal, ob du lookup tabellen verwenden kannst (also die farb-werte schon vorberechnen)
3) ansonsten die farbe nur 1 mal ausrechnen. nicht für beide canvas getrennt.
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Sa 04.09.10 22:22
mh... jetzt muss ich das erst mal alles verstehen  Bin nicht so schnell wie ihr
im Anhang mal die Fläsche die ich zeichne!
Werd mich mal daran machen, erst mal Danke
Edit: Verstanden hab ich erst mal gar nicht, aber erst mal schauen was ihr damit so meint!
Gruss ALf
oops, das sollte gar nicht so gross sein 
Einloggen, um Attachments anzusehen!
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.09.10 22:43
Wenn das so ist ... dann würde ich auch zu Lookup-Tabelle für die Farben raten und zusätzlich die Farbwerte mit ner optimierten Move-Methode (12 Bytes schreiben + Rest durch Bereichsüberlappung kopieren). Bearbeitung des Bitmaps erfolgt dadurch via ScanLine zeilenweise.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Sa 04.09.10 23:35
befor ich mich jetzt dusslig suche!
Scanline ist mir bekannt.
BenBE hat folgendes geschrieben : | Von daher ist das mit dem Ja nur für den Fall, dass man weiß, was man tut  |
keine Ahnung was Du damit sagen willst?
Flamefire hat folgendes geschrieben : | extern heißt: du hast ein canvas auf dem formular, was sichtbar ist |
Ist das meine Paintbox wo ich dann später, die Bitmaps reinkopierer. Oder ist das was ganz anderes?
Flamefire hat folgendes geschrieben : | und tbitmap, was nicht sichtbar ist.
dann zeichnest du auf das bitmap |
das sind doch meine peakbufl,peakbufr oder nicht?
Flamefire hat folgendes geschrieben : | und danach kopierst du das per bitblt auf die canvas auf dem form. |
Delphi-Quelltext 1: 2:
| leftcannelpb.Canvas.Draw(0, 0, peakbufl);rightcannelpb.Canvas.Draw(0, 0, peakbufr); | mach ich doch schon oder ist das auch verkehrt oder was soll der Begriff "bitblt" bedeuten?
Sorry also für das Nachfragen, falls ich die gängigen Begriffe noch nicht ganz verstanden habe.
Gruss ALf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Sa 04.09.10 23:41
ALF hat folgendes geschrieben : | befor ich mich jetzt dusslig suche!
Scanline ist mir bekannt.
BenBE hat folgendes geschrieben : | Von daher ist das mit dem Ja nur für den Fall, dass man weiß, was man tut  | keine Ahnung was Du damit sagen willst? |
Man kann ein Auto mit Super fahren, oder beim Gasgeben die Bremse voll durchtreten ...
ALF hat folgendes geschrieben : | Flamefire hat folgendes geschrieben : | extern heißt: du hast ein canvas auf dem formular, was sichtbar ist | Ist das meine Paintbox wo ich dann später, die Bitmaps reinkopierer. Oder ist das was ganz anderes? |
Ja, das ist die Paintbox. Nennt sich Double Buffering, die Technik.
ALF hat folgendes geschrieben : | Flamefire hat folgendes geschrieben : | und tbitmap, was nicht sichtbar ist.
dann zeichnest du auf das bitmap | das sind doch meine peakbufl,peakbufr oder nicht?
Flamefire hat folgendes geschrieben : | und danach kopierst du das per bitblt auf die canvas auf dem form. |
Delphi-Quelltext 1: 2:
| leftcannelpb.Canvas.Draw(0, 0, peakbufl);rightcannelpb.Canvas.Draw(0, 0, peakbufr); | mach ich doch schon oder ist das auch verkehrt oder was soll der Begriff "bitblt" bedeuten? |
BITBLT
ALF hat folgendes geschrieben : | Sorry also für das Nachfragen, falls ich die gängigen Begriffe noch nicht ganz verstanden habe.
Gruss ALf |
NP.
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 05.09.10 00:19
Oder du nutzst OpenGL/DirectX. Kriegste auch gleich Kantenglättung, wenn du willst.
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: So 05.09.10 00:41
jooo Danke BITBLT gibts nen schönes Beispiel bei DF hätt ja selber drauf kommen können(Dusel ich  )habe ich ja auch noch vor kurzen gelesen mhh....
Danke @delfiphan , ist mir als gelegenheits proger zu heiss!
Kann nur stunden weise an meinem progi sitzen
Mach mich mal an @BenBE + @Flamefire Ideen run
Flamefire hat folgendes geschrieben : | 3) ansonsten die farbe nur 1 mal ausrechnen. nicht für beide canvas getrennt. |
und evtl spiegelverkehrt auf die zweite raufkopieren
Danke
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: So 05.09.10 13:02
Sorry wenn ich pushen tu
Habe das ganze nun mit Scanline gemacht und BitBlt. Ok kein Problem
Frage, gibt es nun ne Möglichkeit, das ich für die 2.bitmap die Farben irgendwie invertiere, so das ich nur einmal die Schleife habe?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| for ypos:= 0 to peakbufr.Height-1 do begin r:= trunc(102+ (255 - 102) / peakbufl.Height *ypos); g:= trunc(113+ (255 - 113) / peakbufl.Height *ypos); b:= trunc(126+ (255 - 126) / peakbufl.Height *ypos); pl:= peakbufl.ScanLine[ypos]; pr:= peakbufr.ScanLine[ypos]; for x:= 0 to peakbufl.Width-1 do begin pl.rgbRed:= r; pl.rgbGreen:= g; pl.rgbBlue:= b; pr.rgbRed:= r; pr.rgbGreen:= g; pr.rgbBlue:= b; inc(pl); inc(pr); end; end; |
habe mit xor, and, or, shr shl experimentiert. War klar das es nicht so geht, hätt ja sein können mhh..
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 05.09.10 13:11
Btw. Du kannst mit einem einzigen Scanline Aufruf auf das gesamte Bitmap zugreifen. Musst einfach auf die Ränder aufpassen, und ob die Bitmap verkehrt rum im Speicher liegt.
|
|
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: So 05.09.10 13:11
was meinst du mit invertieren? ist bei deinem ocde nirgends was zu sehen, wo du das mal gemacht hast.
PS: wenn du vor der x-schleife das rgb-tupel erstellst und dann im ganzen zuweist, ist es nochmal eins stück schneller.
und scanline brauchst du nur einmal vor der ypos schleife.
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: So 05.09.10 13:17
Ich kann mich nur wiederholen: Graphics32 + Scanline = extremer Perfomanceboost...
_________________ Wissenschaft schafft Wissenschaft, denn Wissenschaft ist Wissenschaft, die mit Wissen und Schaffen Wissen schafft. (myself)
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: So 05.09.10 13:40
Fang doch beim unteren Bitmap einfach von unten zu zeichnen an. Dann musst du nix invertieren sondern einfach nur beim zeichnen Y-Pos minus aktuelle Zeile rechnen.
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
Für diesen Beitrag haben gedankt: ALF
|
|
ALF 
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: So 05.09.10 13:49
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: So 05.09.10 14:09
Deine innere Schleife brauchst Du nicht mal:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| r := ...; g := ...; b := ...;
pl.r := r; pl.g := g; pl.b := b; w := peakbufl.Width; pl2 := pl; inc(pl2); Move ( pl, pl2, SizeOf(PixelRGB) * (w - 1) ); Move ( pl, pr, SizeOf(PixelRGB) * w ); |
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: So 05.09.10 14:20
sicher, dass das funktioniert?
a) ist es nicht sehr leserlich. hab gerade erst verstanden, warum das funktionieren KÖNNTE
b) kann das schief gehen, wenn z.b. die Größen verschieden sind (z.b. der 64Bit register, MMX o.ä. verwendet)
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| pl:= peakbufl.ScanLine[0]; pr:= peakbufr.ScanLine[0]; for ypos:= 0 to peakbufr.Height-1 do begin r:= trunc(102+ (255 - 102) / peakbufl.Height *ypos); g:= trunc(113+ (255 - 113) / peakbufl.Height *ypos); b:= trunc(126+ (255 - 126) / peakbufl.Height *ypos); pRGB.rgbRed:=r; pRGB.rgb... for x:= 0 to peakbufl.Width-1 do begin pl:= pRGB; pr:= pRGB inc(pl); inc(pr); end; end; |
So meinte ich das. Mach dir mal klar, wie die bitmap im speicher liegt. scanline ist nix weiter als ein GetPointerAufSpeicher()
was meinst du nun mit invertieren?
da die Farben der unteren Bitmap andersrum sind als oben? Oder das die invertierte Farbe genommen wird?
|
|
|