2010-05-03 7 views
5

Estaba leyendo a través de la documentación de DirectX y encontré algo interesante en la página de IDirect3DDevice9::BeginScene:DirectX: orden de bucle de juego, dibujar primero y luego manejar la entrada?

Para habilitar el paralelismo máximo entre la CPU y el acelerador de gráficos, es ventajoso para llamar IDirect3DDevice9 :: EndScene hasta antes de llamar al presente como sea posible.

He estado acostumbrado a escribir mi bucle de juego para manejar la entrada y tal, luego dibujar. ¿Lo tengo al revés? Tal vez el bucle de juego debe ser de la misma familia: (semi-pseudocódigo, obviamente)

while(running) { 
    d3ddev->Clear(...); 
    d3ddev->BeginScene(); 
    // draw things 
    d3ddev->EndScene(); 

    // handle input 
    // do any other processing 
    // play sounds, etc. 

    d3ddev->Present(NULL, NULL, NULL, NULL); 
} 

De acuerdo con esa frase de la documentación, este bucle podría "permitir paralelismo máxima".

¿Esto se hace comúnmente? ¿Hay algún inconveniente para ordenar el bucle del juego de esta manera? No veo ningún problema real después de la primera iteración ... Y sé que la mejor manera de saber el aumento real de velocidad de algo como esto es compararlo realmente, pero ¿alguien más ya lo ha intentado y puedes dar fe de cualquier real aumentar la velocidad?

+1

No tengo experiencia en DirectX (XNA dev), pero sé que esto probablemente provocará una sensación levemente "laggy" en el juego ya que las cosas se dibujarán antes de que su juego se adelante y se actualice con la nueva entrada suministrada. – RCIX

+0

@RCIX Ver mi respuesta –

Respuesta

2

Como siempre sentí que era "incómodo" dibujar-antes-sim, tendí a empujar los dibujos hasta después de la actualización pero también después de la llamada "presente". P.ej.

while True: 
    Simulate() 
    FlipBuffers() 
    Render() 

Mientras que en el primer fotograma que está volteando nada (y hay que configurar las cosas para que el primer tirón en efecto, dar la vuelta a un estado conocido), esto siempre me pareció un poco mejor que poner el Render() primero, aunque el orden de las operaciones sea el mismo una vez que esté en camino.

2

La respuesta corta es sí, así es como se hace comúnmente. Echar un vistazo a la siguiente presentación en el bucle del juego de God of War III en la PS3:

http://www.tilander.org/aurora/comp/gdc2009_Tilander_Filippov_SPU.pdf

Si está ejecutando un juego doble buffer a 30 fps, el retraso de la entrada será de 1/30 ~ = 0.033 segundos, que es demasiado pequeño para ser detectado por un humano (por comparación, cualquier tiempo de reacción por debajo de 0.1 segundos en 100 metros se considera un comienzo en falso).

+0

3msec definitivamente no está muy por debajo de lo detectable para un ser humano, cuando se reproduce midi-piano cualquier cosa por encima de 4-5 mseg es notable y cualquier cosa por encima de 10 mseg es, si no se puede reproducir, muy molesto. Puede ser una diferencia entre tocar un instrumento musical \ videojuego. –

2

Vale la pena señalar que en casi todos los hardware de PC, BeginScene y EndScene no hacen nada. De hecho, el controlador almacena temporalmente todos los comandos de extracción y cuando llama al presente puede que ni siquiera comience a dibujar. Comúnmente almacenan varios marcos de comandos de dibujo para suavizar la velocidad de cuadros. Por lo general, el conductor hace cosas en función de la presente llamada.

Esto puede causar un retraso de entrada cuando la velocidad de fotogramas no es particularmente alta.

Apostaría que si hicieras tu renderizado inmediatamente antes del presente no notarías ninguna diferencia en el ciclo que das arriba. Por supuesto, en algunos bits extraños de hardware, esto puede causar problemas, por lo que, en general, es mejor que salgas de forma automática como sugieres arriba.

Cuestiones relacionadas