Tearing Beispiel

Übersicht BlitzBasic Codearchiv

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

 

walski

Ehemaliger Admin

Betreff: Tearing Beispiel

BeitragDi, Nov 30, 2004 20:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Hier ein kleines Beispiel für sogenanntes Tearing.

Es kommt Zustande, wenn der Double-Buffer geswapt wird, währrend der Monitor noch in einem Darstellungszyklus ist, also sich auf einmal die Daten ändern, die dargestellt werden, es kann dadurch zu Verschiebungen kommen, die man vor allem bei schnellen vertikalen Bewegungen sieht.

Abhile schafft hier das Synchronisieren der gesendeten Frames an die Bildschirmwiederholrate des Monitors ( sogenannter "vertical Sync" )oder das Einsetzen eines Triple statt eines Double Buffers.

Für das Einbauen letzterer Möglichkeit habe ich leider keine Zeit mehr, ich werde das aber sicher nachholen, da es mich selbst interessiert Wink

Bis dahin erstmal hier der Code:

BlitzBasic: [AUSKLAPPEN]

Const screen_mode_fullscreen = 1
Const screen_mode_windowed = 2

Const screen_width = 800
Const screen_height = 600
Const screen_depth = 32
Const screen_mode = screen_mode_windowed

Global fps_last_time
Global fps_counter
Global fps_fps
Global fps_interval

fps_interval = 100

Local vSync
Local timer
Local fBrake
Local blockX

vSync = False

timer = CreateTimer( 70 )

fBrake = False

Graphics screen_width,screen_height,screen_depth,screen_mode
SetBuffer BackBuffer()

While Not KeyHit( 1 )

If KeyHit( 57 ) Then

If vSync Then

vSync = False

Else

vSync = True

EndIf

EndIf

If KeyHit( 14 ) Then

If fBrake Then

fBrake = False

Else

fBrake = True

EndIf

EndIf

If fBrake Then

WaitTimer( timer )

EndIf

handleFPS()

blockX = blockX + 5

Cls

handleBG( blockX )

Text 1,1,\"FPS: \" + fps_fps
Text 1,20,\"vSync: \" + vSync
Text 1,40,\"Frame-Brake: \" + fBrake


Flip vSync

Wend


Function handleFPS()

Local tSecs

tSecs = MilliSecs()

If tSecs > fps_last_time + fps_interval Then

fps_fps = Int( Float( fps_counter ) * ( 1000.0 / fps_interval ) )

fps_counter = 0

fps_last_time = tSecs

Else

fps_counter = fps_counter + 1

EndIf

End Function

Function handleBG( curX )

Local tX

tX = ( curX Mod screen_width ) * -1

For i = tX To screen_width - tX Step 50

Rect i,0,5,screen_height,1

Next


End Function


Mit [SPACE] aktiviert ihr den vSync, mit [BACKSPACE] eine Frame-Bremse, die die FPS manuell auf 70 begrenzt.

Hat man die Bremse und den vSync an, so stimmt die Frame anzeige nicht mehr! Denn wenn bei einegschaltetem vSync die FPS-Rate unter die Bildwiederholrate des Monitors sinkt, sinken die wirklich angezeigten FPS auf die Hälfte der Wiederholrate, sinken dir Frames darunter, auf ein Drittel der Wiederholrate und so weiter.
Ich schätze also mal bei den, weiterhin angezeigten, 70 FPS kommt es zu Auslassungen, sogenannten dropped Frames das gelte es aber ersteinmal zu beweisen Wink

Mehr dazu, sobald ich mehr Zeit hab.

walski
buh!
  • Zuletzt bearbeitet von walski am So, Dez 05, 2004 17:15, insgesamt 2-mal bearbeitet

Spikespine

BeitragDi, Nov 30, 2004 20:53
Antworten mit Zitat
Benutzer-Profile anzeigen
AHHHH
MEINE AUGEN!!!

nachdem ich mir das programm 10 minuten lang angeschaut habe konnte ich die nächste halbe stunde überhaupt nichts sehen Wink


tja, du hast den effekt gezeigt...
mich würde mal interessieren wie das mit dem triple buffer funktioniert...

Travis

BeitragDi, Nov 30, 2004 21:23
Antworten mit Zitat
Benutzer-Profile anzeigen
Du solltest unbedingt eine Epilepsie-Warnung integrieren! Ansonsten aber sehr interessant.

Zitat:

Bei Personen, die an photosensibler Epilepsie leiden, kann es zu epileptischen Anfällen oder Bewußtseinsstörungen kommen, wenn sie bestimmten Blitzlichtern oder Lichteffekten im täglichen Leben ausgesetzt werden.

Diese Personen können bei der Benutzung von Computer- oder Videospielen einen Anfall erleiden, in der Regel sind diese Spiele für Menschen mit Epilepsie jedoch nicht gefährlich. Es können auch Personen von Epilepsie betroffen sein, die bisher noch nie einen epileptischen Anfall erlitten haben. Falls bei Ihnen oder einem Ihrer Familienmitglieder unter Einwirkung von Blitzlichtern mit Epilepsie zusammenhängende Symptome (Anfälle oder Bewußtseinsstörungen) aufgetreten sind, wenden Sie sich bitte an Ihren Arzt, bevor Sie das Spiel benutzen.

Eltern sollten ihre Kinder bei der Benutzung von Computer- und Videospielen beaufsichtigen. Sollten bei Ihnen oder Ihrem Kind während der Benutzung eines Computer- bzw. Videospiels Symptome wie Schwindelgefühl, Sehstörung, Augen- oder Muskelzucken, Bewußtseinsverlust, Desorientiertheit oder jegliche Art von unfreiwilligen Bewegungen bzw. Krämpfen auftreten, so beenden Sie SOFORT das Spiel und suchen Sie einen Arzt auf.
www.funforge.org

Ich hasse WASD-Steuerung.

Man kann alles sagen, man muss es nur vernünftig begründen können.

Wild-Storm

BeitragDi, Nov 30, 2004 21:34
Antworten mit Zitat
Benutzer-Profile anzeigen
boah verdammt geil, ich hab das teil ca. 30sec angeschaut und dann die wand. die wand hat dann auch so geflimmert xD
Visit http://www.next-dimension.org
-------------------------------------------------
Freeware Modelle, Texturen & Sounds:
http://www.blitzforum.de/forum...hp?t=12875

Waveblue

BeitragDi, Nov 30, 2004 22:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Alter Schwede!

ein Konigreich für Aspirin!
This is 10% luck
20% skill
15% concentrated power of will
5% pleasure, 50% pain
and 100% reason to remember the name

DA

BeitragDi, Nov 30, 2004 22:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Bor, ich kipp gleich aus allen latschen.
*Flimmer*
*Schwankdurchdashaus* Laughing

Thx
DarkAngel
Deutscher Blitz Basic Chat

Jan_

Ehemaliger Admin

BeitragMi, Dez 01, 2004 8:33
Antworten mit Zitat
Benutzer-Profile anzeigen
komischer Weiße, klappt es hier, bei meiner Matrox G200 im Vollbildmodus nicht.
between angels and insects

Jan_

Ehemaliger Admin

BeitragMi, Dez 01, 2004 8:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich persönlihc bin ja Feind, von Tribble Buffering, aber hier mal ein ansatz, der sicherlich Falsch ist, ich sende dann gleich nochtmal, wie ich es machen würde.

BlitzBasic: [AUSKLAPPEN]


Const screen_mode_fullscreen = 1
Const screen_mode_windowed = 2

Const screen_width = 400
Const screen_height = 300
Const screen_depth = 16
Const screen_mode = screen_mode_windowed

Global fps_last_time
Global fps_counter
Global fps_fps
Global fps_interval

fps_interval = 100

;Local vSync
Global vSync
Local timer
Local fBrake
Local blockX

vSync = False

timer = CreateTimer( 70 )

fBrake = False

Graphics screen_width,screen_height,screen_depth,screen_mode
SetBuffer TribleBuffer();BackBuffer()

While Not KeyHit( 1 )

If KeyHit( 57 ) Then

If vSync Then

vSync = False

Else

vSync = True

EndIf

EndIf

If KeyHit( 14 ) Then

If fBrake Then

fBrake = False

Else

fBrake = True

EndIf

EndIf

If fBrake Then

WaitTimer( timer )

EndIf

handleFPS()

blockX = blockX + 5

Cls

handleBG( blockX )

Text 1,1,\"FPS: \" + fps_fps
Text 1,20,\"vSync: \" + vSync
Text 1,40,\"Frame-Brake: \" + fBrake

Flip_Trible()
;Flip vSync

Wend

Global TribleBufferHandle%

Global MonitorHZ%=85,TB_Time%

Function TribleBuffer()
If Not TribleBufferHandle Then
TribleBufferHandle = ImageBuffer(CreateImage(GraphicsWidth(),GraphicsHeight()))
MonitorHZ%=1000.0/MonitorHZ%
EndIf
Return TribleBufferHandle
End Function

Function Flip_Trible()

Local Time%
Time%=MilliSecs()

If Time% > TB_Time% + MonitorHZ% Then
TB_Time%=Time%
CopyRect 0,0,GraphicsWidth(),GraphicsHeight(),0,0,TribleBufferHandle,BackBuffer()
Flip vSync
EndIf

End Function

Function handleFPS()

Local tSecs

tSecs = MilliSecs()

If tSecs > fps_last_time + fps_interval Then

fps_fps = Int( Float( fps_counter ) * ( 1000.0 / fps_interval ) )

fps_counter = 0

fps_last_time = tSecs

Else

fps_counter = fps_counter + 1

EndIf

End Function

Function handleBG( curX )

Local tX

tX = ( curX Mod screen_width ) * -1

For i = tX To screen_width - tX Step 50

Rect i,0,5,screen_height,1

Next


End Function
between angels and insects
  • Zuletzt bearbeitet von Jan_ am Mi, Dez 01, 2004 9:32, insgesamt einmal bearbeitet

Jan_

Ehemaliger Admin

BeitragMi, Dez 01, 2004 9:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Scheiß Trible Poster Wink,

Look @ this: https://www.blitzforum.de/view...2520#82520 (Anti tearing)
between angels and insects
 

walski

Ehemaliger Admin

BeitragMi, Dez 01, 2004 11:35
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich bin gerade auf der Arbeit und habe daher nur kurz über dein Programm rüberluschern können, aber ich glaube es ist etwas zu kompliziert Wink

Ich habe zu Hause schon einen 99% fertigen Triple Buffering Ansatz, ich poste ihn heute Nachmittag, versprochen ( kA ob der dann besser ist als deiner, aber ich glaube du machst dir das Leben einfach zu schwer Wink ).

Bis nachher

walski
buh!

Jan_

Ehemaliger Admin

BeitragMi, Dez 01, 2004 11:57
Antworten mit Zitat
Benutzer-Profile anzeigen
Kann sein Smile

(Bin auch auf arbeit --> hatte Zeit, das zu machen Smile Freue mich schon auf heute nachmittag)
between angels and insects

regaa

BeitragMi, Dez 01, 2004 15:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Ohne VSynch quietscht meine Graka O_o, das merke ich immer beim umswitchen^^.
UltraMixer Professional 3 - Download
QB,HTML,CSS,JS,PHP,SQL,>>B2D,B3D,BP,BlitzMax,C,C++,Java,C#,VB6 , C#, VB.Net

Wild-Storm

BeitragMi, Dez 01, 2004 16:11
Antworten mit Zitat
Benutzer-Profile anzeigen
lol, ne quietschende graka xD
Visit http://www.next-dimension.org
-------------------------------------------------
Freeware Modelle, Texturen & Sounds:
http://www.blitzforum.de/forum...hp?t=12875

Holzchopf

Meisterpacker

BeitragMi, Dez 01, 2004 19:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Wild-Storm hat Folgendes geschrieben:
lol, ne quietschende graka xD
Gibts bei mir auch Rolling Eyes Wenn ich in Valves Hammer Editor für HL² Mappe, ist der Editor aktiviert (also das Fenster), dann "quitscht" sie. Nagut, eigentlich ist es nur der Lüfter, der seine Drehzahlen ändert Laughing

Nebenbei (ne eigentlich OnTopic, egal): Wie genau meinst du das mit den Dropped Frames?
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BYBinaryBorn - Yogurt ♫ (31.10.2018)
Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm
 

walski

Ehemaliger Admin

BeitragMi, Dez 01, 2004 20:12
Antworten mit Zitat
Benutzer-Profile anzeigen
So, ich habe mal ein Triple-Buffer Modell gebaut, allerdings stößt man bei der sequentiellen, strict synchronen Arbeitsweise von Blitzbasic dabei schnell an Grenzen.

Das große Problem ist eigentlich nur: Wie schafft man es, den "Rücksprungs-Punkt" des Elektronenstrahls des Monitors von Zeile screen:height auf 0 möglichst genau zu treffen um ein Tearing zu verhindern oder es zumindest auf wenige Zeilen zu begrenzen...

Ich habe es nicht geschafft, es gibt daher nun zwei Methoden die bei meinem Modell angewendet werden.
Zu erst wird geprüft, ob die momentane Zeile etwa in der Nähe dieses "Rücksürung-Punktes" liegt ( es kann eine Toleranz eingestellt werden ).
Sollte dies n ( kann auch eingestellt werden ) mal nicht geklappt haben, so werden die Buffer getauscht, sobald die aktuelle Zeile kleiner als die vorangehende ist, das wird natürlich wieder genau dann zum Problem, wenn eure FPS knapp unter die Bildwiederholrate sinken... das alte "Double-Buffering-Problem", das es ja eigentlich zu beheben galt.

All diese Unwäglichkeiten lassen meinen Ansatz leider nicht wirklich schön aussehen, an Double-Buffering mit aktiviertem v-Sync kommt es nich heran, aber dafür erreicht man natürlich auch deutlich höhere FPS und das bei wirklich verbesserter Bildqualität im Gegensatz zum Double-Buffering ohne v-Sync.

Performanz... noch so ein Problem... das Triple-Buffering schafft nur noch maximal die hälfte der FPS, die ich mit Double-Buffering ohne v-Sync erreicht habe, dies liegt wohl vor allem daran, dass ich

BlitzBasic: [AUSKLAPPEN]

CopyRect


zum tauschen des End-Buffers mit dem Mid-Buffer benutze, ein einfacher Tausch der Referenzen der beiden Buffer wäre sicherlich sinnvoller, aber ich habe keine Ahnung wie das geht *g

Ok, schreiten wir zur Tat, das Triple-Buffering-Modul:

BlitzBasic: [AUSKLAPPEN]

; just a tiny and bad triple buffering sample
; (c) 2004 by T. Schroeder
; netkowalski@web.de

Global tripleBuffer

Const tb_lineTolerance = 20
Global tb_mishitCount
Const tb_emergencyRate = 50
Global tb_isEmergency

Global tb_avLoopTime#
Global tb_lastSLine

Function createTripleBuffer()

tripleBuffer = CreateImage( screen_width,screen_height )
tripleBuffer = ImageBuffer( tripleBuffer )

End Function

Function setupTB()

createTripleBuffer()
SetBuffer tripleBuffer

End Function

Function tripleFlip()

Local tSLine

CopyRect 0,0,screen_width,screen_height,0,0,tripleBuffer,BackBuffer()

tSLine = ScanLine()

If tSLine < tb_lineTolerance Or tSLine >= screen_height - tb_lineTolerance Then

If Not tb_isEmergency Then

Flip 0

Else

tb_mishitCount = tb_mishitCount - 1

EndIf

Else

tb_mishitCount = tb_mishitCount + 1

EndIf

If tb_mishitCount > tb_emergencyRate Then

tb_mishitCount = tb_emergencyRate

EndIf

If tb_mishitCount = tb_emergencyRate Then

tb_isEmergency = True

EndIf

If tb_mishitCount <= 0 And tb_isEmergency Then

tb_isEmergency = False
tb_mishitCount = 0

EndIf

If tb_isEmergency Then

If tSLine < tb_lastSLine Then

Flip 0

EndIf


EndIf

tb_lastSLine = tSLine

End Function


und das dazugehörige Hauptprogramm:

BlitzBasic: [AUSKLAPPEN]

Const screen_mode_fullscreen = 1
Const screen_mode_windowed = 2

Const screen_width = 800
Const screen_height = 600
Const screen_depth = 32
Const screen_mode = screen_mode_fullscreen

Global fps_last_time
Global fps_counter
Global fps_fps
Global fps_interval

Include \"tripleBuffer.bb\"

fps_interval = 100

Local vSync
Local timer
Local fBrake
Local blockX

timer = CreateTimer( 110 )

fBrake = False

Graphics screen_width,screen_height,screen_depth,screen_mode

setupTB()

While Not KeyHit( 1 )


If KeyHit( 14 ) Then

If fBrake Then

fBrake = False

Else

fBrake = True

EndIf

EndIf

If fBrake Then

WaitTimer( timer )

EndIf

handleFPS()

blockX = blockX + 5

Cls

handleBG( blockX )

Text 1,1,\"FPS: \" + fps_fps
Text 1,20,\"Emergency: \" + tb_isEmergency
Text 1,40,\"Frame-Brake: \" + fBrake

tripleFlip()

Wend


Function handleFPS()

Local tSecs

tSecs = MilliSecs()

If tSecs > fps_last_time + fps_interval Then

fps_fps = Int( Float( fps_counter ) * ( 1000.0 / fps_interval ) )

fps_counter = 0

fps_last_time = tSecs

Else

fps_counter = fps_counter + 1

EndIf

End Function

Function handleBG( curX )

Local tX

tX = ( curX Mod screen_width ) * -1

For i = tX To screen_width - tX Step 50

Rect i,0,5,screen_height,1

Next


End Function


Ich habe die Frame-Bremse etwas nach oben geschraubt, aber das werdet ihr schon gerade noch korrigieren können Wink

Sollte irgendwem ne Idee kommen, wie ich den "Rücksprung-Punkt" genauer treffen kann, erwarte ich eine SOFORTIGE Antwort Smile

Ich stelle mir zum Beispiel sowas vor wie ein direktes Ansprechen von DX oder der Graka, welche dann automatisch und asynchron vom weiteren BB Verlauf dafür sorgen, dass der Front- und Mid-Buffer ( regulär Back-Buffer ) beim "Rücksprung-Punkt" getauscht werden oder so, aber auch da habe ich keine Ahnung, wie man vorgehen müsste.

Ok, ich hoffe das reicht fürs erste: enjoy.

walski
buh!
 

walski

Ehemaliger Admin

BeitragMi, Dez 01, 2004 20:13
Antworten mit Zitat
Benutzer-Profile anzeigen
@Holzchopf: Wenn "mechanisch" nur 50 Frames möglich sind, aber anscheinend die Hauptschleife 70 mal pro Sekunde durchlaufen wird, muss ja irgendwo ein Fehler sein *g

walski
buh!

Jan_

Ehemaliger Admin

BeitragDo, Dez 02, 2004 8:35
Antworten mit Zitat
Benutzer-Profile anzeigen
@Walski

Hm, mit dem Gedanken, habe ich auch gespielt, aber es ist unsinn,

Du Flipst den Buffer nur, wenn de Scanline bei 0 ist, Kopierst in aber jedes Frame in den Backbuffer() --> Arg Reso fressend,
Wieso Zeichnest du nciht gleich in den Backbuffer und FLipst ihn, wenn die Scanline in der Nähe von 0 ist?
wofür brauchst du da den 3. Buffer?
between angels and insects
 

walski

Ehemaliger Admin

BeitragDo, Dez 02, 2004 16:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, in meinem Beispiel ist das in der Tat nicht allzu sinnvoll, aber hier mal die normale Funktionsweise:

-> 2 Backbuffer
-> Frames werden in den Backbuffer 2 gezeichnet und dann in den Backbuffer 1 geswapt
-> Bei jedem "Rücksprung" des Elektronenstrahls an die Ausgangsposition wird der Backbuffer 1 in den Frontbuffer geschaufelt

Vorteil:
Es kann sehr schnell gezeichnet werden, denn auch wenn ein Frame kurz nach Anfangen des Bildaufbaus am Monitor, also zum Beispiel bei Zeile 20, auftritt, der Frame erstmal im Backbuffer 1 gespeichert wird und schon der nächste Frame berechnet werden kann.
Beim normalen Double Buffering dagegen muss dann mit der weiteren Ausführung des Programms solange gewartet werden, bis der nächste "Rücksprungpunkt" erreicht ist.

Warum es in BB nicht geht:

Um das zu realisieren bräuchte man wirklich einen asynchronen Thread, der aufgerufen wird, sobald der Rücksprungpunkt erreicht ist und dann das Kopieren des Back- in den Fronbuffer vollführt...

Dabei stelle ich mir gerade eine Frage:

Ich dachte bisher, auch beim Triple Buffering würden die Buffer einfach geswapt werden, aber das würde ja das komplette Konzept über den Haufen werfen, es ist also wahrscheinlicher, das der Backbuffer in den Framebuffer kopiert wird, oder?!

Naja

walski
buh!

stfighter01

BeitragFr, Dez 03, 2004 22:19
Antworten mit Zitat
Benutzer-Profile anzeigen
hmm eine möglichkeit etwas ähnliches zu realisieren gäbe es allerdings schon.
mit millisecs() die monitorfrequenz messen und kurz vor erreichen des nächsten frames VWsync aufrufen für vollständige sync. danach den renderbuffer in den frontbuffer kopieren.
dabei gehen aber 1-2 msecs verloren und daher bin ich nicht sicher ob die vorteile die nachteile aufwiegen.
Denken hilft!
 

walski

Ehemaliger Admin

BeitragFr, Dez 03, 2004 22:36
Antworten mit Zitat
Benutzer-Profile anzeigen
stfighter, du das wäre alles nicht das Problem, das eigentliche Problem ist eben einfach mal diesen Punkt zu erwischen!!!

Wenn du eine 100hz Vertikal-Frequenz am Monitor hast, dann hast du beo 700 FPS eben auch nur 7 Stellen, an denen dein Programm pro Bildaufbau in eben diesen eingreifen kann.

In einem ungüstigen Fall kann dies bei einer x*768 Auflösung so aussehen:

80,189,298,...,734...

Und das ist halt einfach kacke Wink

Aber mir kam da da eh noch eine tolle Idee, also abwarten und Tee trinken Wink

walski
buh!

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group