Pixel - Rate
- Green Snake
- Beiträge: 1394
- Registriert: 22.02.2005 19:08
Pixel - Rate
hallo
habe eine grafische frage
weis jemand, wie man folgendes hinbekommt?
also ich habe einen schwarzen bildschirm (openscreen())
jetzt will ich, das der bildschirmm ganz rot wirt (RGB 255,0,0)
das sol aber nicht einfach so geschehen, sonder mit pixel effekt.
dh. es soll auf dem schwarzen bildschirm immer ein rotes pixel mehr zu sehen sein. dass sollte schnell gehen, so das in etwa 10 der ganze schirm rrot ist
wie mache ich dass?
habe eine grafische frage
weis jemand, wie man folgendes hinbekommt?
also ich habe einen schwarzen bildschirm (openscreen())
jetzt will ich, das der bildschirmm ganz rot wirt (RGB 255,0,0)
das sol aber nicht einfach so geschehen, sonder mit pixel effekt.
dh. es soll auf dem schwarzen bildschirm immer ein rotes pixel mehr zu sehen sein. dass sollte schnell gehen, so das in etwa 10 der ganze schirm rrot ist
wie mache ich dass?
-.-"
- Green Snake
- Beiträge: 1394
- Registriert: 22.02.2005 19:08
Ja sicher (ich versuchs)
Also ich meine, es sollte jede milli sekunde ein pixel (oder plot)
auf einer zufalls position auf dem screen erscheinen.
dies geht so lange, bis der screen ganz rot ist. wie mache ich das?
hoffe do / Ihrr hab das verstanden.
auf einer zufalls position auf dem screen erscheinen.
dies geht so lange, bis der screen ganz rot ist. wie mache ich das?
hoffe do / Ihrr hab das verstanden.
-.-"
Code: Alles auswählen
for i = 0 to 255
clearscreen(0,0,0)
startdrawing(screenoutput())
plot(random(breite_von_screen),random(höhe_von_screen),rgb(i,0,0))
stopdrawing()
flipbuffers()
next i
Mfg,
AndyX
- vonTurnundTaxis
- Beiträge: 2130
- Registriert: 06.10.2004 20:38
- Wohnort: Bayreuth
- Kontaktdaten:
Um den Screen zu füllen sollte man größere Flächen nehmen, z.B. Box. Um es dann ähnlich aussehen zu lassen wie bei PP müsste man dann widerum die bereits gesetzten Boxes nicht noch einmal setzen lassen. Am besten den Screen in Blöcke unterteilen.
Nicht das was gefordert, aber kleiner Ansatz :
Nicht das was gefordert, aber kleiner Ansatz :
Code: Alles auswählen
Width=640
Height=480
If OpenWindow(0, 0, 0, Width, Height, #PB_Window_SystemMenu|#PB_Window_ScreenCentered, "")
If StartDrawing(WindowOutput())
Repeat
EventID = WindowEvent()
Box(Random(Width),Random(Height), 20,20 ,RGB(i,0,0))
Delay(1)
If EventID = #PB_EventCloseWindow
quit=1
EndIf
If zaehler=1000
quit=1
Else
zaehler+1
EndIf
Until quit=1
StopDrawing()
MessageRequester("",Str(zaehler)+" mal gezeichnet")
EndIf
EndIf
- Green Snake
- Beiträge: 1394
- Registriert: 22.02.2005 19:08
Super danke
Super danke
hat geklappt
(hatte zwar nicht genau das gemeint, konnte den code aber umschreiben)
trotzdem vilen dank euch allen
hat geklappt
(hatte zwar nicht genau das gemeint, konnte den code aber umschreiben)
trotzdem vilen dank euch allen
-.-"
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
@Icke
schon mal guter Ansatz
> Um den Screen zu füllen sollte man größere Flächen nehmen, z.B. Box.
siehe B)
> ...dann widerum die bereits gesetzten Boxes nicht noch einmal setzen lassen.
siehe C)
ausserdem hast du durch das zeichnen aufs Fenster das Problem A) umgangen
Two-Picture-Fade
A) das erste Problem:
Die Screen-Buffer
durch das Double-Buffering ist es nicht möglich, auf bereits vorhandenes zu zeichnen,
da zwei Buffer existieren.
wenn wir jetzt in jedem frame ein neues Pixel setzen,
wird in jedem der zwei Screenbuffer nur die Hälfte der Informationen stehen.
also brauchen wir einen extra-Buffer (ein Sprite) in den wir zeichnen,
und der in jedem Frame angezeigt wird.
B) das zweite Problem:
Die Framerate
wenn wir in jedem Frame ein Pixel verändern, brauchen wir für einen 800x600 Screen
480000 Frames, bei 60FPS sind das 8000 Sekunden oder 2:13:20
auf einem TFT oder LCD können wir (bei manchen) die Framerate extrem pushen,
und ohne V-Sync Flippen, aber bei vielen Monitoren geht das nicht,
ich habe das in meinem Beispiel mal gemacht,
aber ich bräuchte Hilfe (hallo Danilo
oder wer immer sich damit auskennt),
um das Buffer-Drawing und das Screen-Drawing zeitlich zu trennen, z.b. durch Threads
mir ging es hauptsächlich um den Algorythmus, und damit zu
C) das dritte Problem:
Der Algorythmus
wenn wir die Pixel per Zufall auswählen,
dann werden bereits gesetzte Pixel erneut gezeichnet,
je weiter der Prozess fortgeschritten ist, umso mehr.
also brauchen wir einen algorythmus,
mit dem jedes pixel genau einmal gezeichnet wird.
Die Lösung hier stammt aus den 80er Jahren und wurde für den C64 veröffentlicht.
allerdings wurde das damals auf dem Textbildschirm mit 40*25 Zeichen gemacht,
also ging es um 1000 Punkte, nicht um 480000, aber das Prinzip ist das gleiche.
normalerweise überträgt man Daten,
indem man einen Zähler immer um 1 hochsetzt.
man kann auch um andere werte hochsetzen,
und am Ende des Buffers um die Bufferlänge runtersetzen,
dann wird "streifenweise" übertragen.
um wirklich jede Speicherstelle zu erreichen,
muss man ungerade Schrittweiten nehmen.
(mit geraden würde es zu überschneidungen kommen)
das löse ich dadurch, daß ich aus einem angegebenen Mode
eine ungerade Zahl für die Schrittweite erzeuge,
aus 0 wird 1, aus 1 wird 3, aus 2 wird 5, usw.
für die meisten Schrittweiten sieht die Übertragung sehr regelmäßig aus,
aber ein paar werte erzeugen scheinbar zufällige Muster.
leider weiss ich nicht mehr, in welchem Verhältnis diese Schrittweiten
zur Buffergröße standen, also müssen wir rumprobieren,
im vorliegenden Beispiel hab ich einfach mal eine willkürliche Zahl genommen,
leider ist das Ergebnis immer noch ziemlich regelmäßig.
aber es gibt Werte, mit denen es 'gut' aussieht, glaubt mir
ausserdem arbeite ich mit der überblendung von einem sprite zu einem anderen,
eine überblendung von einem rein schwarzen zu einem rein roten Screen
erscheint mir etwas 'anwendungsarm'
so, hier nun der
Taste drücken zum Starten,
am Ende nochmal Taste drücken.
der Vorgang kann mit ESC abgebrochen werden.
schon mal guter Ansatz
> Um den Screen zu füllen sollte man größere Flächen nehmen, z.B. Box.
siehe B)
> ...dann widerum die bereits gesetzten Boxes nicht noch einmal setzen lassen.
siehe C)
ausserdem hast du durch das zeichnen aufs Fenster das Problem A) umgangen

Two-Picture-Fade
A) das erste Problem:
Die Screen-Buffer
durch das Double-Buffering ist es nicht möglich, auf bereits vorhandenes zu zeichnen,
da zwei Buffer existieren.
wenn wir jetzt in jedem frame ein neues Pixel setzen,
wird in jedem der zwei Screenbuffer nur die Hälfte der Informationen stehen.
also brauchen wir einen extra-Buffer (ein Sprite) in den wir zeichnen,
und der in jedem Frame angezeigt wird.
B) das zweite Problem:
Die Framerate
wenn wir in jedem Frame ein Pixel verändern, brauchen wir für einen 800x600 Screen
480000 Frames, bei 60FPS sind das 8000 Sekunden oder 2:13:20
auf einem TFT oder LCD können wir (bei manchen) die Framerate extrem pushen,
und ohne V-Sync Flippen, aber bei vielen Monitoren geht das nicht,
ich habe das in meinem Beispiel mal gemacht,
aber ich bräuchte Hilfe (hallo Danilo

um das Buffer-Drawing und das Screen-Drawing zeitlich zu trennen, z.b. durch Threads
mir ging es hauptsächlich um den Algorythmus, und damit zu
C) das dritte Problem:
Der Algorythmus
wenn wir die Pixel per Zufall auswählen,
dann werden bereits gesetzte Pixel erneut gezeichnet,
je weiter der Prozess fortgeschritten ist, umso mehr.
also brauchen wir einen algorythmus,
mit dem jedes pixel genau einmal gezeichnet wird.
Die Lösung hier stammt aus den 80er Jahren und wurde für den C64 veröffentlicht.
allerdings wurde das damals auf dem Textbildschirm mit 40*25 Zeichen gemacht,
also ging es um 1000 Punkte, nicht um 480000, aber das Prinzip ist das gleiche.
normalerweise überträgt man Daten,
indem man einen Zähler immer um 1 hochsetzt.
man kann auch um andere werte hochsetzen,
und am Ende des Buffers um die Bufferlänge runtersetzen,
dann wird "streifenweise" übertragen.
um wirklich jede Speicherstelle zu erreichen,
muss man ungerade Schrittweiten nehmen.
(mit geraden würde es zu überschneidungen kommen)
das löse ich dadurch, daß ich aus einem angegebenen Mode
eine ungerade Zahl für die Schrittweite erzeuge,
aus 0 wird 1, aus 1 wird 3, aus 2 wird 5, usw.
für die meisten Schrittweiten sieht die Übertragung sehr regelmäßig aus,
aber ein paar werte erzeugen scheinbar zufällige Muster.
leider weiss ich nicht mehr, in welchem Verhältnis diese Schrittweiten
zur Buffergröße standen, also müssen wir rumprobieren,
im vorliegenden Beispiel hab ich einfach mal eine willkürliche Zahl genommen,
leider ist das Ergebnis immer noch ziemlich regelmäßig.
aber es gibt Werte, mit denen es 'gut' aussieht, glaubt mir

ausserdem arbeite ich mit der überblendung von einem sprite zu einem anderen,
eine überblendung von einem rein schwarzen zu einem rein roten Screen
erscheint mir etwas 'anwendungsarm'
so, hier nun der
Code: Alles auswählen
#ScrW = 800
#ScrH = 600
InitSprite()
InitKeyboard()
OpenScreen( #ScrW, #ScrH,32,"Test")
; ich Create mal alle 3 verwendeten Sprites vorab,
; damit man sieht, welche nummern ich verwende...
CreateSprite(8000, #ScrW, #ScrH) ; Ursprung
CreateSprite(8001, #ScrW, #ScrH) ; Ziel
CreateSprite(8002, #ScrW, #ScrH) ; Angezeigter Blendzustand
; ***************** Anfang Demo-Sprites Erzeugung
; ich grabbe hier mal irgendwas,
; man kann auch beliebige Grafix laden,
; (bitte auf exaktes format achten...)
; oder den vorher dargestellten Screen
; in Sprite 8000 grabben....
; einfach ein buntiges Bildchen für Sprite 8000
ClearScreen(0,0,0)
StartDrawing(ScreenOutput())
For n=0 To 999
Circle(Random(#ScrW),Random(#ScrH),4+Random(28),RGB(130+Random(120),130+Random(120),130+Random(120)))
Next
StopDrawing()
FlipBuffers()
Repeat:ExamineKeyboard():Until KeyboardPushed(#PB_Key_All) ; einfach mal schauen, wie's aussieht
FlipBuffers()
GrabSprite(8000, 0, 0, #ScrW, #ScrH)
; und nen rein roten Screen für 8001
ClearScreen(255,0,0)
GrabSprite(8001, 0, 0, #ScrW, #ScrH)
ClearScreen(0,0,0)
; ***************** Ende Demo-Sprites Erzeugung
; *** die Argumente für die Routine
; der Blendmode bestimmt das relative Pixel-Offset (Schrittweite der Überblendung)
; erlaubt sind alle Werte von 0 bis zur Hälfte der Pixel-Anzahl
BlendMode = 126845
; Die Festlegung der Blendtime ist notwendig, um die adäquate Framerate zu berechnen
; Angabe in Sekunden
BlendTime = 10
; ****
; **** Die Eigentliche Routine
; ****
AnzPix.l = #ScrW * #ScrH ; Gesamtanzahl der vorhandenen Pixel
Nxt.l = BlendMode*2+1
; aus dem Mode wird eine ungerade Zahl gemacht
; für die Schrittweite der Überblendung
If Nxt > AnzPix Or Nxt < 0 : End : EndIf ; Abbruch, wenn die Schrittweite größer als der Screen ist.
ActPix.l = 0 ; aktuelles Pixel, das übertragen wird.
FrmRt = AnzPix / BlendTime ; VORSICHT: dreckige Lösung
SetFrameRate(FrmRt) ; die Framerate wird hochgepusht
CopySprite(8000,8002)
DisplaySprite(8002,0,0)
FlipBuffers(0)
count = 1
Repeat
PixY = ActPix/#ScrW
PixX = ActPix-PixY*#ScrW
UseBuffer(8002) ; in Sprite 8002 ausgeben
ClipSprite(8001, PixX, PixY, 1, 1) ; nur das aktuelle Pixel
DisplaySprite(8001, PixX, PixY) ; in den Blend-Buffer übertragen
UseBuffer(-1) ; wieder auf Screen ausgeben
ActPix + Nxt ; Pixel-Offset dazuaddieren
If ActPix >= AnzPix ; innerhalb des Bereichs halten
ActPix - AnzPix
EndIf
DisplaySprite(8002,0,0) ; aktuellen Blend-Buffer anzeigen
FlipBuffers(0) ; OHNE V-SYNC flippen !
count+1
ExamineKeyboard()
Until count >= AnzPix Or KeyboardPushed(1)
Repeat:ExamineKeyboard():Until KeyboardPushed(#PB_Key_All) ; und nochmal auf taste warten
am Ende nochmal Taste drücken.
der Vorgang kann mit ESC abgebrochen werden.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.
-
- Beiträge: 17389
- Registriert: 10.11.2004 03:22
so, nochmal Danke an Icke
ich hab jetzt mein prog mal umgestrickt auf direktes plotten ins Window,
damit wird das Screen-Problem (Buffer & Framerate) umgangen,
ausserdem kann man auf allen Monitoren den Effekt beobachten...
...spielt mal mit dem Wert für BlendMode herum
gibt schicke Effekte
[EDIT]
Shit, ich merke grad, nicht alle Werte für BlendMode Funktionieren.
und zwar solche, die einen ganzzahligen Teiler für AnzPix ergeben.
...hmmm da war doch noch irgendwas getrickst bei dem 20 jahre alten algo...
ich hab halt die hefte nicht mehr, das ist alles aus der Erinnerung...
[EDIT2]
hm... also, werte, die funktionieren, machen auch einen guten eindruck..
z.b. 3 oder 5 oder 6
liegt wahrscheinlich auch daran, dass bei der menge der pixel und dem tempo
die regelmässigkeit garnicht so auffällt.
ich hab jetzt mein prog mal umgestrickt auf direktes plotten ins Window,
damit wird das Screen-Problem (Buffer & Framerate) umgangen,
ausserdem kann man auf allen Monitoren den Effekt beobachten...
...spielt mal mit dem Wert für BlendMode herum

gibt schicke Effekte
Code: Alles auswählen
#ScrW = 800
#ScrH = 600
OpenWindow(1,0,0,#ScrW, #ScrH,#PB_Window_SystemMenu|#PB_Window_ScreenCentered,"Test")
; einfach ein buntiges Bildchen für den Window-Background
StartDrawing(WindowOutput())
For n=0 To 999
Circle(Random(#ScrW),Random(#ScrH),4+Random(28),RGB(130+Random(120),130+Random(120),130+Random(120)))
Next
StopDrawing()
Delay(2000)
;ich war zu blöd und zu faul, auf ne taste zu warten ;)
; *** die Argumente für die Routine
; der Blendmode bestimmt das relative Pixel-Offset (Schrittweite der Überblendung)
; erlaubt sind alle Werte von 0 bis zur Hälfte der Pixel-Anzahl
BlendMode = 126845
; ****
; **** Die Eigentliche Routine
; ****
AnzPix.l = #ScrW * #ScrH ; Gesamtanzahl der vorhandenen Pixel
Nxt.l = BlendMode*2+1
; aus dem Mode wird eine ungerade Zahl gemacht
; für die Schrittweite der Überblendung
If Nxt > AnzPix Or Nxt < 0 : End : EndIf ; Abbruch, wenn die Schrittweite größer als der Screen ist.
ActPix.l = 0 ; aktuelles Pixel, das übertragen wird.
count = 1
StartDrawing(WindowOutput())
FrontColor(255,0,0)
Repeat
If count < AnzPix
PixY = ActPix/#ScrW
PixX = ActPix-PixY*#ScrW
Plot(PixX,PixY)
ActPix + Nxt ; Pixel-Offset dazuaddieren
If ActPix >= AnzPix ; innerhalb des Bereichs halten
ActPix - AnzPix
EndIf
count +1
EndIf
Until WindowEvent() = #PB_Event_CloseWindow
Shit, ich merke grad, nicht alle Werte für BlendMode Funktionieren.
und zwar solche, die einen ganzzahligen Teiler für AnzPix ergeben.
...hmmm da war doch noch irgendwas getrickst bei dem 20 jahre alten algo...
ich hab halt die hefte nicht mehr, das ist alles aus der Erinnerung...
[EDIT2]
hm... also, werte, die funktionieren, machen auch einen guten eindruck..
z.b. 3 oder 5 oder 6
liegt wahrscheinlich auch daran, dass bei der menge der pixel und dem tempo
die regelmässigkeit garnicht so auffällt.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Der Weise weiß, dass er ein Narr ist.