Actualmente estoy escribiendo un pequeño motor de juegos 2D multiplataforma basado en OpenGL para nuestro estudio. Cuando investigué qué clase de Vector 2D usar, me topé con tres paradigmas de diseño diferentes:
Flotador y llamada por valor, como en este artículo de Gamasutra . Parece ser rápido pero ofrece poca precisión (ver también este hilo ). Pro: rápido, portátil y compatible con la mayoría de las bibliotecas.
Doble y llamada por referencia. Si entiendo bien el artículo anterior, también podría usar 2 variables de doble precisión en lugar de los 4 números flotantes. De acuerdo con el hilo anterior, el doble aún es más lento que el flotador.
Plantilla para doble y flotante: El popular libro " Game Engine Architecture " utiliza plantillas para hacer posible usar flotante y doble según sea necesario. La desventaja obvia es la hinchazón de código. Además, dudo que el código pueda optimizarse sin básicamente escribir dos clases, de todos modos.
Apreciaría saber qué soluciones está utilizando en sus motores internos y cuán precisos son, por ejemplo, los motores de juegos populares, para poder decidir qué solución implementaré en nuestro motor. En este momento estoy pensando simplemente en usar la precisión de flotación y vivir con ella.
fuente
Respuestas:
Siempre uso float a menos que tenga una razón para usar double, tanto como uso int a menos que tenga una razón para usar int64_t.
Los flotadores no tienen problemas para hacer aritmética de enteros precisos hasta 2 24 , que es a lo que la mayoría de las personas temen (principalmente irracionalmente). Los dobles no resuelven el problema de que los valores comunes no sean representables exactamente; ya sea que obtenga 0.10000001 o 0.10000000000000001, aún debe asegurarse de que su código lo considere "igual" a 0.09999999.
Los dobles son más lentos en cada plataforma en la que te interesará escribir juegos, tomar el doble del ancho de banda de la memoria y tener menos instrucciones de CPU especializadas disponibles.
Los flotadores de precisión simple siguen siendo el estándar para las interfaces gráficas de hardware, tanto en el lado C / C ++ como en los sombreadores internos.
Probablemente necesitará un vector doble en algún momento, pero debe usarse cuando sea necesario, no de manera predeterminada.
En cuanto a la plantilla: tiene razón, para obtener el máximo rendimiento, de todas formas querrá especializar las plantillas manualmente. Aparte de eso, ejecuté algunas pruebas para un código con plantilla durante el fin de semana (haciendo un IntRect y FloatRect de 4 ple), y descubrí que la versión con plantilla tardó aproximadamente 20 veces más en compilarse que simplemente repetir el código, que ascendió a unas 15 líneas . La repetición apesta, pero esperar compilaciones apesta más, y no es como si fuera a necesitar un StringRect o FooRect.
fuente
El marco del juego Microsoft XNA tiene una clase Vector2 que utiliza flotantes. Esta sería mi mayor razón personal para ir con carrozas, ya que confío en que la sabiduría y la experiencia del equipo de XNA sean mucho mayores que las mías.
Me pareció bastante interesante leer la respuesta en esta pregunta de Stack Overflow: "Float vs Double Performance" . También hay un hilo de gamedev.net con una discusión sobre el doble rendimiento en las GPU. Creo que es seguro asumir que los dobles son más lentos que los flotantes, al menos en muchas GPU, y yo personalmente siempre utilicé las funciones flotantes de OpenGL sobre sus contrapartes dobles. Es posible que esto no se aplique hoy en día, pero si considera que no todos los que ejecutan su juego tienen la última GPU con soporte doble nativo, creo que esta es razón suficiente para usar flotadores y obtener ese rendimiento adicional.
fuente