| |
|
|
Sven Bader | Nachdem Yo en mi letzten Ver código fuente el Genauigkeit de "Sleep" gefixt habe, hier nun una algo umfangreicheres Ejemplo para una konstante Framerate en Spielen. Bisher Tuve con pro Frame aufsummierten Rundungsfehlern gelebt y Bildberechnung y Logik (Ticks) siempre gemeinsam abgewickelt, hier funktioniert beides mejor!
Features: -Verwendung uno präzisen Perfomance Counters -Physik se ejecuta más, auch si la Bildberechnung hinterherhinkt -Framerate abweichend de Ticks wählbar -kein Aufsummieren de Zeitabweichungen -Sleep para verbleibende Frame-Tiempo (0% CPU), außer letzter Rest con genauem Performance Counter
Einschränkungen: -no automatische Anpassung el Framerate, sólo Bilddrops -Framerate sólo como vielfaches de Ticks wählbar (cada, cada Zweite, cada Dritte,...) -Gar kein Bild, si Tiempo no una vez para Physik ausreicht (Drop cada Frames)
Alles wäre machbar, Yo quería no a komplex hacer. Zudem debería en OpenGL abgefragt voluntad, si VSync verwendet se, como el FPS hier ya por OpenGL en el Bildrate des Monitors gekappt voluntad.
Declarar qpc#, freq_factor!, qpc_freq#, caps#
Declarar timeNextFrame!,timeNextFrameSecure!,timeend!,ticks&
Declarar framedrop&,mod&, frame&,countFramedrops&
Dim qpc#,8'Performance Counter aktuelle Tiempo
Dim qpc_freq#,8'Performance Counter Frequenz
Dim caps#,8'Temporizador Intervalle min/max auslesen
Def timeGetDevCaps(2) !"winmm","timeGetDevCaps"
Def timeBeginPeriod(1) !"winmm","timeBeginPeriod"
Def timeEndPeriod(1) !"winmm","timeEndPeriod"
Def QueryPerformanceFrequency(1) !"Kernel32","QueryPerformanceFrequency"
Def QueryPerformanceCounter(1) !"Kernel32","QueryPerformanceCounter"
Ventana de Estilo 16'+ 64
Ventana (%maxx * 0.5 - 250), (%maxy * 0.5 - 262) - 500,524
QueryPerformanceFrequency(qpc_freq#)'Performance Counter Frequenz
freq_factor! = (1 / (long(qpc_freq#,0) / 1000.0))'macht el spätere Umrechnung lesbarer
'Benutzereinstellungen
ticks& = 120'Ticks son Physik-Frames pro Sekunde
mod& = 1'Jeder wievielte Tick se una Bild suscrito? 1 si fps = ticks
timeGetDevCaps(caps#,8)'Auflösung des Timers anfragen (caps# = min ms, max ms)
timeBeginPeriod(long(caps#,0))'minimale Auflösung des Timers conjunto, como en manchen Systemen Sleep sonst sólo 15ms genau es!!
'Physikzeug, Position y Geschwindigkeit
declarar x&,y&,speedx&,speedy&
speedx& = 1
speedy& = 1
x& = 77
y& = 299
declarar mousekey1&,mousekey2&
timeNextFrameSecure! = 1
mcls 500,500
whilenot iskey(27)'ESC
inc frame&
'Manuelle Änderung el FPS y Ticks
if (iskey(1)) AND not(mousekey1&)
inc mod&
mousekey1& = 1
endif
casenot (iskey(1)) : mousekey1& = 0
caso mod& > 8 : mod& = 1
if (iskey(2)) AND not(mousekey2&)
ticks& = ticks& + 30.0
mousekey2& = 1
endif
casenot (iskey(2)) : mousekey2& = 0
caso ticks& > 240 : ticks& = 30.0
'1. PHYSIK
caso (x& <= 16) O (x& >= 484) : speedx& = speedx& * (-1)
caso (y& <= 16) O (y& >= 484) : speedy& = speedy& * (-1)
x& = x&+speedx&
y& = y&+speedy&
'2. GRAFIK
if (frame& = 1) O (not(framedrop&) AND (frame& MOD mod& = 0))
startpaint -1
cls RGB(192,192,192)
USEP 0,0,RGB(0,128,192)
Color del texto RGB(40,40,40),-1
UseBrush 1, RGB(0,128,192)
Ellipse (x&-16),(y&-16) - (x&+16),(y&+16)
DrawText 16, 16, str$(countFramedrops&) + " drops (Bilder übersprungen)"
DrawText 16, 32, str$(int(ticks&)) + " ticks (Physik/Logik pro Sekunde)"
decimals 1
DrawText 16, 48, str$((ticks& / mod&)) + " fps (Bilder pro Sekunde, mod& = "+str$(mod&)+")"
DrawText 16, 80, "Linke Botón del ratón ändert FPS"
DrawText 16, 96, "Rechte Botón del ratón ändert Ticks"
DrawText 16, 112, "ESC para Beenden"
endpaint
MCopyBmp 0,0 - 500,500 > 0,0;0
endif
'3. TIMING
'ungenaues Sleep a kurz antes gewünschtem Frame-Ende
if int(timeend!) < int(timeNextFrameSecure!)
sleep int(timeNextFrameSecure!) - int(timeend!)
framedrop& = 0
más
framedrop& = 1
inc countFramedrops&
endif
'Restliche Tiempo genauem Performance-Counter abwarten
'mindestens una Duchlauf, a aktuelle Tiempo a holen
mientras que timeend! < timeNextFrame!
QueryPerformanceCounter(qpc#)'Endzeit des Counters
timeend! = long(qpc#,0) * freq_factor!
'Sollte salvo beim ersten Frame no passieren, se de otra manera aber auch hiermit gerettet
if abs(timeend! - timeNextFrame!) > 2000
timeNextFrame! = timeend! + (1000.0 / ticks&)'Intento lo a retten
endif
endwhile
timeNextFrame! = timeNextFrame! + (1000.0 / ticks&)' Endzeit para nächsten Frame
timeNextFrameSecure! = timeNextFrame! - 2.0' y otra vez 2ms früher
endwhile
timeEndPeriod(long(caps#,0))'zuvor gesetzte minimale Temporizador-Auslösung zurücksetzen
Disponer caps#, qpc_freq#, caps#, qpc#, qpc_freq#
|
|
|
| |
|
|
|
Georg Teles | Nabend,
muy bien, nu kann Yo media 144 Hz Monitor auch con XProfan testen
Grüße |
|
|
| |
|
|