Pregunta

Estoy en el proceso de escribir un juego Java 2D. Estoy usando las bibliotecas de dibujo Java 2D integradas, dibujando en un Graphics2D que adquirí de un BufferStrategy de un Canvas en un JFrame (que a veces es de pantalla completa). BufferStrategy tiene doble búfer. El repintado se realiza activamente, a través de un temporizador. Sin embargo, tengo algunos problemas de rendimiento, especialmente en Linux.

Y Java2D tiene tantas maneras de crear buffers gráficos y dibujar gráficos que simplemente no sé si estoy haciendo lo correcto. He estado experimentando con graphics2d.getDeviceConfiguration (). CreateCompatibleVolatileImage, que parece prometedor, pero no tengo ninguna prueba real de que vaya a ser más rápido si cambio el código del dibujo a eso.

En su experiencia, ¿cuál es la forma más rápida de representar gráficos 2D en la pantalla en Java 1.5+? Tenga en cuenta que el juego está bastante avanzado, por lo que no quiero cambiar a un método de dibujo completamente diferente, como OpenGL o un motor de juego. Básicamente quiero saber cómo obtener la forma más rápida de usar un objeto Graphics2D para dibujar cosas en la pantalla.

¿Fue útil?

Solución

Creo que tengo los mismos problemas que tú. Echa un vistazo a mi publicación aquí:

Problemas de rendimiento de Java2D

Muestra el motivo de la degradación del rendimiento y cómo solucionarlo. Sin embargo, no se garantiza que funcione bien en todas las plataformas. Verás por qué en la publicación.

Otros consejos

Una síntesis de las respuestas a esta publicación, las respuestas a Consty's , y mi propia investigación:

Qué funciona:

  • Use GraphicsConfiguration.createCompatibleImage para crear imágenes compatibles con lo que está dibujando. ¡Esto es absolutamente esencial!
  • Utilice el dibujo de doble búfer a través de Canvas.createBufferStrategy .
  • Use -Dsun.java2d.opengl = True donde esté disponible para acelerar el dibujo.
  • Evite usar transformaciones para escalar. En su lugar, guarde en caché las versiones a escala de las imágenes que va a utilizar.
  • ¡Evita las imágenes translúcidas! Las imágenes enmascaradas están bien, pero la translucidez es muy costosa en Java2D.

En mis pruebas, usando estos métodos, obtuve un aumento de velocidad de 10x - 15x, lo que hace posible los gráficos Java 2D adecuados.

Aquí hay algunos consejos de la parte superior de mi cabeza. Si fueras más específico y lo que estabas tratando de hacer podría ayudarte más. Suena como un juego, pero no quiero asumirlo.

¡Solo dibuja lo que necesitas! No llame ciegamente a repintar () todo el tiempo, intente con algunos de los hermanos como repintar (Rect) o repintar (x, y, w, h).

Tenga mucho cuidado con la mezcla alfa, ya que puede ser una operación costosa para combinar imágenes / primitivos.

Intenta preprendir / caché tanto como sea posible. Si te encuentras dibujando un círculo de la misma manera, una y otra vez, considera dibujar en una BufferedImage y luego dibuja la BufferedImage. Estás sacrificando la memoria por la velocidad (típica de los juegos / gráficos de alto rendimiento)

Considere usar OpenGL, use JOGL de LWJGL. JOGL es más parecido a Java, mientras que LWJGL proporciona más funciones de juego además del acceso a OpenGL. OpenGL puede generar órdenes de magnitud (con el hardware y los controladores adecuados) que Swing.

Creo que hay una importante que aún no se ha mencionado: almacenar en caché las imágenes de todo lo que pueda. Si tiene un objeto que se está moviendo a través de la pantalla y su apariencia no cambia mucho, dibuje una imagen y luego renderice la imagen en la pantalla en una nueva posición en cada cuadro. Haga eso incluso si el objeto es muy simple: puede que se sorprenda de cuánto tiempo ahorra. La representación de un mapa de bits es mucho más rápida que la de los primitivos.

Es posible que también desee ver la configuración de las sugerencias de representación de forma explícita y desactivar el antialiasing si las consideraciones de calidad lo permiten.

He hecho algunas aplicaciones de dibujo básicas usando Java. No he trabajado en algo demasiado gráfico, pero recomendaría que tenga un buen manejo de todas las invocaciones de "repintado". Una llamada de repintado adicional en un contenedor primario podría duplicar la cantidad de renderizado.

He estado viendo esta pregunta, esperando que alguien te ofrezca una mejor respuesta que la mía.

Mientras tanto, encontré el siguiente Libro blanco de Sun que fue escrito después de una versión beta de jdk 1.4. Aquí hay algunas recomendaciones interesantes sobre el ajuste fino, incluidas las banderas de tiempo de ejecución (al final del artículo):

" Indicador de tiempo de ejecución para Solaris y Linux

A partir de la versión Beta 3 del SDK, versión 1.4, Java 2D almacena las imágenes en pixmaps de forma predeterminada cuando DGA no está disponible, ya sea que esté trabajando en un entorno de visualización local o remoto. Puede anular este comportamiento con la marca pmoffscreen:

-Dsun.java2d.pmoffscreen = verdadero / falso

Si establece este indicador en verdadero, la compatibilidad con mapas de píxeles fuera de la pantalla está habilitada incluso si DGA está disponible. Si establece este indicador en falso, se deshabilita la compatibilidad con el mapa de píxeles fuera de pantalla. Desactivar el soporte de pixmap fuera de la pantalla puede resolver algunos problemas de representación. "

asegúrese de utilizar el doble almacenamiento en búfer, dibuje primero en un gran búfer en la memoria que luego va a la pantalla cuando termine todo el dibujo.

Hay algunas cosas que deberás tener en cuenta

1) es refrescante este enlace muestra cómo usar swingtimers que podría ser una buena opción para llamar a repintar. Descubrir el repintado (como han dicho los pósters anteriores es importante para que no esté haciendo demasiado trabajo).

2) Asegúrate de que solo estás dibujando en un hilo. Actualizar la interfaz de usuario a partir de múltiples hilos puede llevar a cosas desagradables.

3) Doble búfer. Esto hace que el renderizado sea más suave. este sitio tiene más información buena para usted

Una alternativa si no quieres usar Java 2D puro es usar una biblioteca de juegos como GTGE o JGame (búscalos en Google), luego ofrece un acceso fácil a los gráficos y también ofrece doble búfer y un dibujo mucho más simple. comandos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top