ReadPixelFast gibt falsche Farbe aus?
Übersicht

![]() |
M0rgensternBetreff: ReadPixelFast gibt falsche Farbe aus? |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hey Leute.
Ich probier grade mal testweise was kleines zu basteln. Zuerstmal: Ich lasse einen Kreis aus Linien erstellen. Dabei geh ich aber Schrittweise vor. Also, ich hab eine Variable die sich immer dem Endpunkt annähert. Jetzt will ich mit readpixelfast überprüfen ob etwas andersfarbiges im Weg ist. Ich habe die Variable schwarz deklariert und in das Format für readpixel bzw writepixel umgerechnet. Dann überprüfe ich ob das Ergebnis von reapdpixel ungleich schwarz ist. Wenn dem so ist, dann soll er die Linie nicht fortzeichnen. Aber irgendwie zeichnet er nur den Mittelpunkt und das wars. Hier ist der Code: Code: [AUSKLAPPEN] AppTitle "Lichter"
Graphics 800,600,32,2 SetBuffer BackBuffer() SeedRnd MilliSecs() Global FTimer = CreateTimer(60) Global QuelleX = GraphicsWidth()/2 Global QuelleY = GraphicsHeight()/2 Global Radius = 2 Global schwarz = 0*$1000000 + 0*$10000 + 0*$100 + 0 ClsColor 0, 0, 0 Repeat WaitTimer(FTimer) Cls Color 250, 10, 10 Rect(100,100,100,100,1) Linien() Flip 0 Until KeyDown(1) Function Linien() Local i Local RGB = 0*$1000000 + 250*$10000 + 250*$100 + 250 Local XEnd Local YEnd Color 250, 250, 250 For i = 0 To 360 Step 360 Local NahX = QuelleX Local NahY = QuelleY XEnd = Int(QuelleX-Sin(i)*GraphicsWidth()/Radius) YEnd = Int(QuelleY+Cos(i)*GraphicsHeight()/Radius) Local abbruch = 0 Repeat Local Farbe ;Line(QuelleX,QuelleY,NahX, NahY);, RGB) ;Plot(NahX,NahY) If NahX < XEnd Then NahX = NahX + 1 ElseIf NahX > XEnd Then NahX = NahX - 1 EndIf If NahY < YEnd Then NahY = NahY + 1 ElseIf NahY > YEnd Then NahY = NahY - 1 EndIf LockBuffer BackBuffer() Farbe = ReadPixelFast(NahX, NahY) If Farbe <> schwarz Then abbruch = 1 UnlockBuffer BackBuffer() Until (NahX = XEnd And NahY = YEnd) Or abbruch = 1 Line(QuelleX, QuelleY, NahX, NahY) Next End Function Also, er bricht einfach ab, obwohl er eigentlich noch gar nichts gezeichnet hat. Kann mir vielleicht jemand helfen, und mir bitte auch erklären wie das richtig geht? Lg, M0rgenstern |
||
![]() |
Eingeproggt |
![]() Antworten mit Zitat ![]() |
---|---|---|
Im reinen 2D-Modus gibt es keine Alpha-Werte... oder anders gesagt es gibt nur einen, nämlich 255, daher musst du die Zeile am Anfang so schreiben:
Code: [AUSKLAPPEN] Global schwarz = 255*$1000000 + 0*$10000 + 0*$100 + 0
(Achtung, nicht getestet, hoffe cih liege richtig) mfG, Christoph. |
||
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9 |
![]() |
Nicdel |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] Global schwarz = 255*$1000000 + 0*$10000 + 0*$100 + 0
Da ist es egal, der Alphawert kann auch 0 sein. Hier jedoch muss er 255 sein: Code: [AUSKLAPPEN] Local RGB = 255*$1000000 + 250*$10000 + 250*$100 + 250
|
||
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7 |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Vielen Dank
Ich habs geändert. Im Prinzip funktioniert das auch (nebenbei ich arbeite mit B3d). Aber wenn ich jetzt den Code ausführe, dann hab ich eher eine Windmühle denn ein Kreis. Also, nur nach unten, rechts, oben und links gehen Strahlen weg undein Strahl geht zu dem Rechteck. Das wars auch schon. Eigentlich müssten es viel mehr Strahlen sein. Lg, M0rgenstern Achso: Beim Code bei der For-SChleife Step 360 einfach auf step 10 oder niedriger ändernl. Dann sieht man was ich meine. |
||
![]() |
ChesterBetreff: Re: ReadPixelFast gibt falsche Farbe aus? |
![]() Antworten mit Zitat ![]() |
---|---|---|
Außerdem läuft die Schleife nur einmal mit deinem Step 360:
Code: [AUSKLAPPEN] For i = 0 To 360 Step 360
Edit: zu späät |
||
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
@ NIcdel:
Die Variable RGB benutze ich im moment nicht. Das war für linien mit writepixelfast. Ist aber im moment draußen. @Chester: Das habe ich grade geschrieben. Das Problem mit den "Rädern" hab ich immernoch. Lg, m0rgenstern |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
In deinem Code sind mehrere Fehler:
Zum einen musst du in 2D immer den Alphawert rausfiltern, bevor du mit RGB-Farben vergleichst. Das geht so BlitzBasic: [AUSKLAPPEN] Farbe = ReadPixel(NahX, NahY) And $FFFFFF Zweitens musst du in der Abbruchsabfrage nicht nur Schwarz miteinbeziehen, sondern auch die Farbe, in der du zeichnest. Sobald du die ersten paar Linien gezeichnet hast, ist der Startpunkt nämlich schon übervoll mit weissen Pixeln, weswegen er da schon abbricht (das ergibt dann die "Windmühle", die du erwähnt hast). Die Zeile sähe korrigiert dann ungefähr so aus BlitzBasic: [AUSKLAPPEN] If Farbe <> schwarz And Farbe <> $FAFAFA Then abbruch = 1 $FAFAFA ist die Farbe deines Kreises (250, 250, 250) in Hex. Das sieht dann schon besser aus, allerdings werden immer noch nicht korrekte Resultate geliefert. Das liegt an der Methode, mit der du die Linien nachfährst (die Repeat-Schleife). Wenn du das "Plot(NahX,NahY)" wieder in den Code nimmst, siehst du auch, warum - du fährst nämlich nicht gerade die Linie nach, sondern eine Art "Scheeflockenform". Um das zu beheben, müsstest du fast einen DDA-Algorithmus verwenden; eine Beschreibung davon findest du hier. Das mag für dich vielleicht ein wenig schwierig ausschauen. Wenn du Probleme hast, kann ich gerne versuchen zu erklären bzw. dir eine simple Implementation schreiben, falls du das wünschst. Noch ein kleiner Tipp: LockBuffer bzw. UnlockBuffer kommen vor bzw. nach die For-Schleife. Jedesmal bei einem Line den Buffer sperren und entsperren ist sogar langsamer als Line alleine; du musst den Buffer für alle Lines nämlich nur ein einziges mal sperren. |
||
- Zuletzt bearbeitet von Noobody am Fr, Jan 08, 2010 19:16, insgesamt einmal bearbeitet
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Da du direkt mit dem BackBuffer arbeitest, liest du natürlich auch die vorher gemalten Linien wieder ein, welche zum Abbruch führen.
Male die Linien einfach in ein ImageBuffer eines zuvor erstellten Bildes und zeichne am Schluss der Funktion dieses Bild. Dann ersparst du dir auch das locken/unlocken pro Pixel. Und baue auf jeden Fall noch eine Überprüfung ein, ob die Koordinaten ausserhalb des Buffers sind - denn dein Code hat bei mir vorhin zum MAV geführt, weil er 600/400 auslesen wollte, obwohl der Buffer ja nur bis 599/399 geht. mfG |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also, das ganze sieht jetzt so aus:
Code: [AUSKLAPPEN] AppTitle "Lichter"
Graphics 800,600,32,2 SetBuffer BackBuffer() SeedRnd MilliSecs() Global FTimer = CreateTimer(60) Global QuelleX = GraphicsWidth()/2 Global QuelleY = GraphicsHeight()/2 Global Radius = 2 Global schwarz = 255*$1000000 + 0*$10000 + 0*$100 + 0 ClsColor 0, 0, 0 Repeat WaitTimer(FTimer) Cls Color 250, 10, 10 Rect(100,100,100,100,1) Linien() Flip 0 Until KeyDown(1) Function Linien() Local i Local RGB = 255*$1000000 + 250*$10000 + 250*$100 + 250 Local XEnd Local YEnd Color 250, 250, 250 LockBuffer BackBuffer() For i = 0 To 360 Step 1 Local NahX = QuelleX Local NahY = QuelleY XEnd = Int(QuelleX-Sin(i)*GraphicsWidth()/Radius) YEnd = Int(QuelleY+Cos(i)*GraphicsHeight()/Radius) Local abbruch = 0 Repeat Local Farbe ;Line(QuelleX,QuelleY,NahX, NahY);, RGB) ;Plot(NahX,NahY) If NahX < XEnd Then NahX = NahX + 1 ElseIf NahX > XEnd Then NahX = NahX - 1 EndIf If NahY < YEnd Then NahY = NahY + 1 ElseIf NahY > YEnd Then NahY = NahY - 1 EndIf Farbe = ReadPixelFast(NahX, NahY) And $FFFFFF If Farbe <> schwarz And Farbe <> $FAFAFA Then abbruch = 1 Until (NahX = XEnd And NahY = YEnd) Or abbruch = 1 Line(QuelleX, QuelleY, NahX, NahY) Next UnlockBuffer BackBuffer() End Function Aber jetzt ist das weiße noch kleiner. Also, nur noch so ca. 100 Pixel lang und auch nicht mehr so breit gefächert. Was hab ich falsch gemacht? @Nooboody: Ich weiß, dass das diese Form ergiebt. Ist mir beim Test aufgefallen. Den Algorythmus guck ich mir gleich mal an, aber ich glaube mein Englisch ist nicht gut genug. @Holzchopf: Werd ich noch einbauen. Vielen Dank. Lg, M0rgenstern EDIT: @Nooboody: Okay, ich geb zu. Ich verstehs nicht. Mein Englisch ist nicht gut genug und mit Vektoren hab ich noch nicht genug zu tun gehabt. |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
BlitzBasic: [AUSKLAPPEN] Global schwarz = 255*$1000000 + 0*$10000 + 0*$100 + 0 Da du jetzt mit dem "And $FFFFFF" den Alphateil rausfilterst, muss die obige Zeile einfach so heissen: BlitzBasic: [AUSKLAPPEN] Global schwarz = 0 |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habs jetzt geändert, aber das ganze funktioniert nur teilweise.
Hab mal hier nen Screenshot: Ich geh mal davon aus, dass es an diesen "Schneeflocken" liegt. @Nooboody könntest du mir bitte diesen Algorithmus erklären? Lg, M0rgenstern. |
||
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich hab jetzt statt dem DDA einfach einen simplen Bresenham eingebaut. Da DDA nur im Vorteil ist, wenn man wirklich alle Gitterzellen überprüfen will, die vom Strahl gekreuzt werden, ist Bresenham hier eher geeignet, da schneller. Code ist dreist aus der Wikipedia kopiert BlitzBasic: [AUSKLAPPEN] AppTitle "Lichter" |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
![]() |
M0rgenstern |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hey Noobody.
Vielen Dank für den Code. Wärst du aber vielleicht bitte so lieb mir das ganze noch zu erklären? Da ich damit arbeiten muss und eventuell nicht mit ReadPixel sondern eher mit den Koordinaten. Wäre echt nett, weil den Code blick ich irgendwie nicht. Lg, M0rgenstern |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Theorie dahinter ist vereinfacht ausgedrückt folgende:
Wenn du Linien durch einzelne PLOTs erstellst und dabei zur Berechnung mathematische Formeln verwendest, kommt es zwangsläufig zu Stellen die mehrfach berechnet werden. z.B. im Nahbereich deines Kreises malen viele der 360 Richtungen immer wieder die selben ersten Pixel. Aber selbst eine einzige der 360 Richtungen mal auf Ihrem Weg zum Ziel manchmal das selbe Pixel mehrfach, weil die Schrittweite sehr klein gewählt wurde. Weiter außen im Kreis kommt es dann zu Pixeln, die übersprungen werden, da trotz der kleinen Schrittweite, die du für die Berechung gewählt hast, nun plötzlich das übernächste Pixel ausgerechnet wird. Du wirst keine optimale Schrittweite finden, die im Nahbereich nicht zuviel und dann in der Ferne nicht zu wenig malt. Deshalb ein ganz anderer Ansatz. Du stehts auf einem Pixel P mit den Koordinaten (x,y). Nun muss ja die Linie irgendwo hingehen. Es gibt 8 Richtungen und auch nur 8 mögliche Pixel a bis h Code: [AUSKLAPPEN] a b c
d P e f g h Nun testet man einfach, welches der 8 Pixel einer Berechnung am nähesten kommt. z.b. welches Y ergibt sich, wenn ich den X-Wert Px-1 (der ja den Feldern a, d und f gemeinsam ist) in die Formel einsetze. Dieses Y-Ergebnis ist nun entweder nahe an Py-1 oder Py oder Py+1. Code: [AUSKLAPPEN] -1 Px +1
----------- a b c |-1 | d P e | Py | f g h |+1 Je nachdem wird also die Linie in a oder d oder f fortgesetzt. Ich plotte dieses Pixel und stell mich auf diesen Punkt. Von da aus starte ich das Suchen nun erneut. Hört sich umständlich an, ist aber teuflisch schnell. Bis zum Spielfeldrand sind es maximal nur 400 Pixel, eher weniger. |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group