GS-Zone

Limitar FPS con QueryPerfomance Ir al Indice

Moderadores: Moderadores de Argentum, Especialistas de Argentum, Especialistas de Programación

15

Nota » 14 Sep 2011 22:54

Paso este codigo que tenia hace mucho publicado en otro foro.

Paso a explicar:
Cuando nosotros limitamos el FPS en el AO se realiza con GetTickCount.

Para los que no saben, basicamente GetTickCount y QueryPerfomance son 2 funciones para medir los intervalos.
GetTickCount tiene el inconveniente de que mide intervalos minimos de 15-16ms (En Windows XP, esto varia dependiendo el Sistema Operativo que usen)
Y QueryPerfomance, es mas precisa, mide intervalos de hasta 1ms y menos!

Lo que hace, es realizar todos los FPS posibles, y cuando detecta que es superior a 101fps entonces pausea/tilda hasta cumplir el segundo.
Esto genera desastres en la reproduccion del motor grafico, haciendo que los calculos no sean tan exactos ya que en computadoras rapidas, procesa la mitad de un segundo los graficos y la otra mitad esta tildado.

La solución a esto es simple.
Limitar los FPS por frame mediante la funcion QueryPerfomance.
¿Como seria esto?
Pensemos en que queremos limitar a 100fps.
100fps = 100 frame per second = 100 cuadros por segundo = 100 bucles por segundo.

Entonces... si tenemos 100fps, ¿Cuanto tiene que ser el intervalo de cada bucle?
1segundo / 100fps = 1000ms / 100fps = 10ms por fps

Entonces, si limitamos 10ms cada bucle logramos tener aproximadamente 100fps.
Pero, tambien se realizan funciones en este bucle, que pueden alentar el bucle, en el caso del Argentum tenemos todo el procesamiento del motor grafico, desde los calculos, hasta la impresion en pantalla y mas!.
Normalmente en una computadora normal, este procesamiento puede tardar 5-7ms por bucle.
Pero entonces! Si tenemos 5-7ms de procesamiento y 10ms para limitar los FPS nos quedaria unos 15-17ms de pauseo por bucle. Entonces nuestros FPS seran de 58-59fps (lo saque haciendo este calculo FPS=1000/16).

Entonces lo que se puede hacer, es calcular el tiempo que tarda en procesar el bucle, y despues calcular el tiempo en que se pausea.
Por ejemplo, si el tiempo de procesamiento del bucle es de 6ms por loop entonces al pauseo de FPS le hacemos 10ms-6ms=4ms. Entonces pauseamos por 4ms.
Por lo tanto hay un pauseo de 6ms por el procesamiento + 4ms de pauseo por el limitador de FPS y llegamos a tener 10ms. Osea 100fps aproximadamente!

Esto sirve mucho en los calculos que se deben realizar a la hora de ejecutar el motor grafico.
Tambien evita que los usuarios se aceleren y cosas por el estilo.

¡Bueno! Basta de explicación y les dejo el codigo!

Buscamos:
Aclaración: El "\ 10" varia en diferentes codigos.
  1.        While (DirectX.TickCount - fpsLastCheck) \ 10 < FramesPerSecCounter
  2.             Sleep 5
  3.         Wend


Y reemplazamos por:
Aclaracion: Cambiar el numero 100, para poder cambiar el limite de FPS. Si lo escribes en 60, se limitara a aproximadamente 60fps.
  1.        Dim TimeSleep As Long ' Declaramos el tiempo para pausear la PC
  2.         TimeSleep = (1000 / 100 - 1) - SetElapsedTime(False) ' Cambiar numero 100 para cambiar los FPS
  3.         If TimeSleep > 0 Then 'Si el Tiempo es negativo entonces no limitamos
  4.             Sleep TimeSleep
  5.         End If
  6.         Call SetElapsedTime(True) 'Seteamos el tiempo


Buscar:


Y arriba poner
  1. Call SetElapsedTime(True) 'Iniciamos el tiempo


Buscar
  1. Private Function GetElapsedTime() As Single


Y arriba poner
  1. Public Function SetElapsedTime(ByVal Start As Boolean) As Single
  2. '**************************************************************
  3. 'Author: Aaron Perkins
  4. 'Last Modify Date: 23/05/2011 By MaTeO
  5. 'Gets the time that past since the last call
  6. '[MaTeO] Agrego cambios a la funcion
  7. '**************************************************************
  8.     Dim Start_Time As Currency
  9.     Static End_Time As Currency
  10.     Static Timer_Freq As Currency
  11.     'Get the timer frequency
  12.     If Timer_Freq = 0 Then
  13.         QueryPerformanceFrequency Timer_Freq
  14.     End If
  15.    
  16.     'Get current time
  17.     Call QueryPerformanceCounter(Start_Time)
  18.    
  19.     If Not Start Then
  20.         'Calculate elapsed time
  21.         SetElapsedTime = (Start_Time - End_Time) / Timer_Freq * 1000
  22.    
  23.         'Get next end time
  24.     Else
  25.         Call QueryPerformanceCounter(End_Time)
  26.     End If
  27. End Function


¡Y listo!
Ahora si limitan los FPS les queda mas comodo.
Ensima es mas facil de calcularlos, directamente ponen el numero que desean limitar y se limita ^^.
Igual, no lo pausea exacto pero sin embargo sirve igual.
Si lo limitas a 100fps tira entre 100 a 110fps.
Última edición por MaTeO el 16 Sep 2011 16:20, editado 3 veces en total

Usuario Registrado
132
Aprendiz [7]
Registrado: Años de membresíaAños de membresíaAños de membresíaAños de membresía
Mensajes: 492
Aportes: 11

Nota » 14 Sep 2011 23:04

Mateo , me dejaste sin palabras! Excelente aporte , me encanto la explicación , estos son los APORTES que se merecen mas que lo que son.

"No existen comentarios boludos, sino boludos que comentan."


Imagen


Imagen
-Staff Argentum Online-
882
Dragon Ancestral [2]
Registrado: Años de membresía
Ubicación: Buenos Aires
Mensajes: 3094
Aportes: 181
Premios: 3
Mister S.O.S. (2) Aportes (1)

Nota » 15 Sep 2011 09:10

Es interesante, mas preciso, eso si.. pero yo no hubiese usado este metodo. Por algo Directx8 nos proporciona limitar fps por vsync del pc.

Vicinity of obscenity
525
Legendario Inmortal [2]
Registrado: 5 Años de membresía!
Ubicación: España
Mensajes: 5580
Aportes: 50
Premios: 3
Mister Programador FreeForAll (3)

Nota » 15 Sep 2011 10:28

Pero es para dx7 esto parra :P, buen aporte.

pd: no se si es lo mismo para dx8..

daroh escribió:es porque no tiene los drivers de video ¬¬
Noi Due escribió:No se si lo reportaron, pero tácticas de combate y combate de armas, están al revez.


JAJAJAJA

Adf.ly

Imagen

• Acortar links.
• Gana dinero.

Haz click en la imagen de Adf.ly para registrarte.

TheFranK@hotmail.com.ar
316
Dragon Ancestral [4]
Registrado: Años de membresíaAños de membresía
Ubicación: Necochea
Mensajes: 3831
Aportes: 20
Premios: 1
Embajador (1)

Nota » 15 Sep 2011 13:26

En DirectX 7 creo que tambien tienes la opción para limitar vsync.. igual que opengl.

Vicinity of obscenity
525
Legendario Inmortal [2]
Registrado: 5 Años de membresía!
Ubicación: España
Mensajes: 5580
Aportes: 50
Premios: 3
Mister Programador FreeForAll (3)

Nota » 15 Sep 2011 15:53

Muy lindo MaTeO , sigue así ,me gustó el código. Seguramente mañana haga mis 5 primeros aportes en lo que es AO :D

Llegué aquí con un solo propósito.


Imagen
- Shak -
Aprendiz [1]
Registrado: Septiembre 2011
Mensajes: 207
Aportes: 4

Nota » 16 Sep 2011 01:27

Que buen aporte MateO, cada vez me sorprendes más!


LuuuQ.-

¿Tu área de especialidad es Graficación o Mapeación? Te presento el proyecto serio que esperabas para trabajar...

~ Para que aprendas ~
821
Dragon Ancestral [2]
Registrado: Años de membresía
Mensajes: 2707
Aportes: 98

Nota » 18 Sep 2011 00:33

Muy bueno Mateo, pero ami me sigue gustando más el vsync para Dx7...

Aunque ya que lo tenemos a Parra presente aca, le voy a hacer una pregunta:



Parra, que pasa si al poner la vsync y agarras y pones para que los FPS se limiten en 70 ponele... Pasaria algo, o seria al pedo ?
Saludos
Xtreem

Imagen
By Francoxe
^[ Inbooker Ao ]^ Busca Programador con mucha exp.
35
Oraculo [2]
Registrado: Años de membresíaAños de membresía
Mensajes: 1355
Aportes: 4
Premios: 1
Embajador (1)

Nota » 18 Sep 2011 12:52

II XTREEM II escribió:Muy bueno Mateo, pero ami me sigue gustando más el vsync para Dx7...

Aunque ya que lo tenemos a Parra presente aca, le voy a hacer una pregunta:



Parra, que pasa si al poner la vsync y agarras y pones para que los FPS se limiten en 70 ponele... Pasaria algo, o seria al pedo ?
Saludos
Xtreem

No pasaria nada, funcionaria igual.. pero seria absurdo hacerlo.

Vicinity of obscenity
525
Legendario Inmortal [2]
Registrado: 5 Años de membresía!
Ubicación: España
Mensajes: 5580
Aportes: 50
Premios: 3
Mister Programador FreeForAll (3)

Nota » 18 Sep 2011 16:15

II XTREEM II escribió:Muy bueno Mateo, pero ami me sigue gustando más el vsync para Dx7...

Aunque ya que lo tenemos a Parra presente aca, le voy a hacer una pregunta:



Parra, que pasa si al poner la vsync y agarras y pones para que los FPS se limiten en 70 ponele... Pasaria algo, o seria al pedo ?
Saludos
Xtreem


le mandas un if y listo xD, si no usa vsync, q los limite cn esto



Santty.- escribió:Si, soy hincha de tu padre, el que te gana cada vez que te cruza, el dueño del barrio, el orgullo nacional, rey de copas y el máximo ganador de copa libertadores

PROBLEM?





La gente que cuando camina mueve un poco los labios está practicando respuestas originales para discusiones que ya perdieron hace dos horas.
YPF etatizada: -Hola q carga? -Deme Néstor Súper
686
Dragon Ancestral [4]
Registrado: Años de membresíaAños de membresía
Ubicación: Mendoza
Mensajes: 3545
Aportes: 40

Nota » 19 Sep 2011 14:39

No leí muy bien los códigos de 13.0 pero lo testee y no funciona en 13.0

Llegué aquí con un solo propósito.


Imagen
- Shak -
Aprendiz [1]
Registrado: Septiembre 2011
Mensajes: 207
Aportes: 4

Nota » 19 Sep 2011 19:22

Ajamhel.- escribió:No leí muy bien los códigos de 13.0 pero lo testee y no funciona en 13.0

Esto es 12.x.....




ON: Muy buen aporte Mateo! :ok:

Imagen
- IDE -
730
Moderador Global
Registrado: Años de membresíaAños de membresía
Ubicación: Sídney
Mensajes: 5335
Aportes: 47
Premios: 6
Especial de Navidad (1) Señor Organizador (1) Señor Reglamento (2) Reportes resueltos (1) Embajador (1)

Nota » 19 Sep 2011 19:23

[Z]ion! escribió:
Ajamhel.- escribió:No leí muy bien los códigos de 13.0 pero lo testee y no funciona en 13.0

Esto es 12.x.....




ON: Muy buen aporte Mateo! :ok:



Entendiste mal , claramente dije que lo testee en 13.0 y no funciona en esa versión que es lo que me importaba.

Ya sé que es 12.x a menos de que se le bugueo algo a GS y cambio todo esto sigue siendo 12.X

Saludos :D

Llegué aquí con un solo propósito.


Imagen
- Shak -
Aprendiz [1]
Registrado: Septiembre 2011
Mensajes: 207
Aportes: 4

Nota » 22 Sep 2011 01:34

Este codigo sirve para todas las versiones, no tiene ningun valor muy caracteristico de la version.

Esa forma de limitar los FPS se hace desde antes de la 99z, asi que Fenix, 0.11.X, etc deberia funcionar.
Lo unico que cambia es el numerito que divide porque en la 0.11.5 y anteriores a 18 fps andaba y despues de la 0.12.X funciona a 101fps.

Parra... si VSYNC es mejor, sin embargo no me gusta 60fps, me gusta mas 100fps :), y la diferencia se nota.
Y aparte, antes que el codigo con TickCount prefiero esto xD.

Ajamhel si no te funco en 0.13.0 es porque algo hiciste mal, o pusiste algun codigo que lo arruina. Si podes dejar los resultados de tu intento.

Saludos ^^

Usuario Registrado
132
Aprendiz [7]
Registrado: Años de membresíaAños de membresíaAños de membresíaAños de membresía
Mensajes: 492
Aportes: 11

Nota » 02 Oct 2011 13:08

Vsync es un asco para ao, y mas para esta versiones, lo que hace vsync es pausar hasta que te llame la impresion que pantalla segun el refresco, y porejemlpo si mientra está esperando nsootros caminamos, tiene que esperar el refresco y despues va a llamar al flush buffer, otro motivo es que en la mayoria de los dx8 que vemos aca, tienen doble ecena (por el inventario) entonces el dx8 piensa que es la misma, dejandote en 30 fps (60/2). lo recomendable es usar esto, pero sin SLEEP, Sleep es inexacto tambien! Usa un While con el QueryPerfomance y queda bien, total aca el objetivo es no quemar el cpu, y que el usuario pueda jugar fluido!
Este mensaje ha obtenido 1 Moneda de Oro.


Director de Buth AO. 9.9z Protocolo Binario, Directx8 y todo lo lindo para jugar fluidamente feliz ;D
Programador
361
Oraculo [1]
Registrado: Años de membresíaAños de membresíaAños de membresía
Mensajes: 1135
Aportes: 30


Volver a AO 0.12.x

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados