[BB, B+, B3D] SpecialRect()
Übersicht

Weazle25Betreff: [BB, B+, B3D] SpecialRect() |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Mit dieser Function kann man Rechtecke mit abgerundeten Ecken zeichnen.
Der Unterschied zu anderen "RoundedRect()" liegt darin das bei SpecialRect() jede Ecke einen anderen Radius haben kann. Darüberhinaus kann auch die Breite der Outline verändert und das Rechteck mit einer Füllung (2. Farbe) versehen werden. Die Parameter sollten selbsterklärend sein. Die Radien: R1 -> oben links R2 -> oben rechts R3 -> unten links R4 -> unten rechts Code: [AUSKLAPPEN] Graphics( 800, 600, 32, 2 ) SetBuffer( BackBuffer() ) ClsColor( 150, 150, 255 ) Cls LockBuffer( BackBuffer() ) SpecialRect( 100, 100, 200, 100, 50, 10, 10, 50, 1, $FFFFFF00, $FF0000FF, 1 ) For i = 0 To 359 Step 1 Kreis( 350, 100, 100, 1, $FF000000, ARGB( 255, Rand( 0, 255 ), Rand( 0, 255 ), Rand( 0, 255 ) ), i, i + 1 ) Next UnlockBuffer( BackBuffer() ) Flip FlushKeys() WaitKey() Function SpecialRect( X, Y, W, H, R1, R2, R3, R4, BorderWidth, ARGB_Border = $FF0000FF, ARGB_Inner = $FFFFFFFF, Fill = 1 ) Kreis( X, Y, R1, BorderWidth, ARGB_Border, ARGB_Inner, 0.0, 90.0, Fill ) Kreis( X + W - R2 - R2 - 1, Y, R2, BorderWidth, ARGB_Border, ARGB_Inner, 90.0, 180.0, Fill ) Kreis( X, Y + H - R3 - R3 - 1, R3, BorderWidth, ARGB_Border, ARGB_Inner, 270.0, 360.0, Fill ) Kreis( X + W - R4 - R4 - 1, Y + H - R4 - R4 - 1, R4, BorderWidth, ARGB_Border, ARGB_Inner, 180.0, 270.0, Fill ) For Y1 = 0 To H - 1 X2 = 0 W2 = W - 1 If Y1 < R1 Then X2 = R1 W2 = W - R1 - 1 EndIf If Y1 > ( H - R3 - 1 ) Then X2 = R3 W2 = W - R3 - 1 EndIf If Y1 < R2 Then W2 = W2 - R2 - 1 If Y1 > ( H - R4 - 1 ) Then W2 = W2 - R4 - 1 For X1 = 0 To W - 1 If X1 >= X2 And X1 <= ( X2 + W2 ) Then If X1 < BorderWidth Or ( W - 1 - X1 ) < BorderWidth Or Y1 < BorderWidth Or ( H - 1 - Y1 ) < BorderWidth Then WritePixel( X1 + X, Y1 + Y, ARGB_Border ) Else If Fill = 1 Then WritePixel( X1 + X, Y1 + Y, ARGB_Inner ) EndIf EndIf Next Next End Function Function Kreis( X, Y, Radius, BorderWidth, ARGB_Border = $FF0000FF, ARGB_Inner = $FFFFFFFF, StartSeg# = 0.0, EndSeg# = 360.0, Fill = 1 ) Local deg#, yp, xp, r BorderWidth=BorderWidth-1 StartSeg# = StartSeg# + 180.0 EndSeg# = EndSeg# + 180.0 For deg# = StartSeg# To EndSeg# Step 0.1 For r = 0 To Radius yp = Int( -Sin#(deg#) * Float#( r ) * Float#( -1 ) + Float#( Y ) + Float#( Radius ) ) xp = Int( Cos#(deg#) * Float#( r ) + Float#( X ) + Float#( Radius ) ) If (Radius - r ) <= BorderWidth Then WritePixel( xp,yp, ARGB_Border ) Else If Fill = 1 Then WritePixel( xp,yp, ARGB_Inner ) EndIf Next Next End Function Function ARGB( A, R, G, B ) Return A * $1000000 + R * $10000 + G * $100 + B End Function End Gruss Weazle |
||
- Zuletzt bearbeitet von Weazle25 am Di, Mai 22, 2007 18:28, insgesamt einmal bearbeitet
![]() |
Smily |
![]() Antworten mit Zitat ![]() |
---|---|---|
Tip für das nächste mal:
Du solltest deine Funktionen nicht einfach irgendwo mitten im Programm reinschreiben. Schreibe sie ganz oben oder noch besser ganz unten hin. Sowas kommt besser an ^^ |
||
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets "Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!" stummi.org |
Weazle25 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
@Smily0412
Jetzt besser? Normaler Weise habe ich meine Functionen immer in separaten Dateien. Nur hier hatte ich mal ne Ausnahme gemacht weils ja nur ein Mini-Programm ist. Gruss Weazle |
||
![]() |
Smily |
![]() Antworten mit Zitat ![]() |
---|---|---|
joa so sieht es schon besser aus ![]() Leider ist die Funktion für Realtime-Effekte nich zu gebrauchen (bei mir ~3 sekunden berrechnungszeit) vlt solltest du nur den Rand per Writepixelfast machen und größere Flächen dann mit rect füllen, das macht das ganze bestimmt schneller ![]() gruß, Smily0412 |
||
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets "Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!" stummi.org |
Weazle25 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Smily0412 hat Folgendes geschrieben: joa so sieht es schon besser aus ![]() Leider ist die Funktion für Realtime-Effekte nich zu gebrauchen (bei mir ~3 sekunden berrechnungszeit) 3 Sekunden? Also bei mir ist das Proggi seeehhhrrr viel schneller. Wie schnell kann ich Dir jetzt nicht sagen aber devinitiv weniger als 1 Sekunde. Wenn ich aber LockBuffer( BackBuffer() ) und UnlockBuffer( BackBuffer() ) weg lasse dann braucht das Proggi auch 2-3 Sekunden. Smily0412 hat Folgendes geschrieben: vlt solltest du nur den Rand per Writepixelfast machen und größere Flächen dann mit rect füllen, das macht das ganze bestimmt schneller ![]() gruß, Smily0412 Ich habe das absichtlich so gemacht denn so unterstützt SpecialRect() auch Alphas so das man auch halbtransparente Rechtecke auf ne Alpha Textur zeichnen kann. Und genau dafür brauche ich diese Function auch. Mit Rect() ist das allerdings nicht möglich und bei WritePixelFast() gibts Probleme wenn man ausserhalb des Buffers zeichnen will. Ich habe allerdings keine Ahnung wie ich das abfangen soll denn wie soll ich die Grösse des Buffers ermitteln wenn ich nicht weiss auf welchen Buffer gezeichnet werden soll? ( SpecialRect() sollte ja Buffer-neutral sein ) Gruss Weazle |
||
![]() |
Smily |
![]() Antworten mit Zitat ![]() |
---|---|---|
ah mein fehler. Der Debug ist an allem schuld ^^
Zeit ohne debug: 300ms zeit mit debug: 6000ms |
||
Lesestoff:
gegen Softwarepatente | Netzzensur | brain.exe | Unabhängigkeitserklärung des Internets "Wir müssen die Rechte der Andersdenkenden selbst dann beachten, wenn sie Idioten oder schädlich sind. Wir müssen aufpassen. Wachsamkeit ist der Preis der Freiheit --- Keine Zensur!" stummi.org |
![]() |
PowerProgrammer |
![]() Antworten mit Zitat ![]() |
---|---|---|
Trotzdem nicht sehr schnell, mit Rect kann man wohl noch etwas an Performance rausholen, denke ich mal. | ||
www.xairro.com Alles für Webmaster und Programmierer! Es gibt mehr als bloß einen Counter! |
FWeinbehemals "ich" |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ja wenn man es mit recht machen will und dann auf die Tranßperenz verzichtet aber es scheint ja nicht so als ob er das wolte ^^ | ||
"Wenn die Menschen nur über das sprächen, was sie begreifen, dann würde es sehr still auf der Welt sein." Albert Einstein (1879-1955)
"If you live each day as if it was your last, someday you'll most certainly be right." Steve Jobs |
Weazle25 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Schaut euch mal den Code etwas genauer an dann sollte euch etwas auffallen.
Nagut ich wills mal nicht so schwer machen: Das Problem sind nicht die grossen Flächen denn da wird gar nicht so viel Speed verbraten. Die Rundungen sind das Problem! Bei den Rundungen wird jeder Pixel separat mit sin()/Cos() berechnet was allein schon ne Menge Speed kostet. Beim zeichnen grösserer Kreise (Radius > 40) wurden viele Pixel vergessen was ich bisher nur umgehen konnte indem ich den Kreis (und damit auch die Rundungen des SpecialRects) in 0,1° Schritten berechnen lasse. Das hat aber den Nachteil das wesentlich mehr Pixel berechnet und gezeichnet werden müssen als eigentlich notwendig wären. Um richtig Speed zu sparen müsste man das SpecialRect zeilenweise zeichnen. Dann müsste man nur die äussersten Pixel berechnen und diese dann durch eine horizontale Linie verbinden. Ich vermute mal das so auch die BB-Kreise/Ovale gezeichnet werden weil es eben die schnellste Methode ist. Allerdings gibts dann wieder Probleme mit der Outline. Man müsste dann also erst die Füllung zeichnen und dann die Outline drüberbügeln. Mal schauen vielleicht bau ich SpecialRect und Kreis entsprechend um. Gruss Weazle |
||
![]() |
PowerProgrammer |
![]() Antworten mit Zitat ![]() |
---|---|---|
Der Line-Befehl ist auch noch ziemlich langsam.
Das, was am schnellsten gezeichnet wird, sind tatsächlich Bilder, die sind quasi sofort da. Vllt wäre es schlau, ein rechteckiges Image vollständig zu füllen und dann die Ecken herauszuschneiden. Wenn man das Teil vorberechnet, wenn man es in einer Hauptschleife nutzen möchte, dann ist es sowieso viel schneller. Was solls, Anfänger können an deinem Code schauen, wie soetwas funktioniert und den Code für sich anpassen. |
||
www.xairro.com Alles für Webmaster und Programmierer! Es gibt mehr als bloß einen Counter! |
Weazle25 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
PowerProgrammer hat Folgendes geschrieben: Der Line-Befehl ist auch noch ziemlich langsam. Wer redet denn von der Line-Function? Line() versuche ich immer so weit wie möglich zu vermeiden. Für horizontale und vertikale Linien sollte man eher Rect() WritePixel() oder WritePixelFast() benutzen. PowerProgrammer hat Folgendes geschrieben: Das, was am schnellsten gezeichnet wird, sind tatsächlich Bilder, die sind quasi sofort da. Übertreib mal nicht denn Images brauchen auch ne ganze Menge Speed. Besonders bei grossen Bildern fällt das sehr schnell auf. PowerProgrammer hat Folgendes geschrieben: Vllt wäre es schlau, ein rechteckiges Image vollständig zu füllen und dann die Ecken herauszuschneiden. Und wie machst Du das dann mit der Outline? PowerProgrammer hat Folgendes geschrieben: Wenn man das Teil vorberechnet, wenn man es in einer Hauptschleife nutzen möchte, dann ist es sowieso viel schneller. Eben dafür war's ja auch gedacht. Ich arbeite gerade an einer GUI-Lib bei der künftig keine Texturen mitgeliefert werden sollen. Statt dessen sollen die Default-Texturen bei Programmstart mit SpecialRect() gezeichnet werden. Gruss Weazle |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group