2012-06-15 23 views
10

Estoy escribiendo un juego de plataformas 2D usando SDL con C++. Sin embargo, me he encontrado con un gran problema que implica escalar a la resolución. Quiero que el juego se vea bien en Full HD para que todas las imágenes del juego hayan sido creadas de modo que la resolución natural del juego sea 1920x1080. Sin embargo, quiero que el juego se reduzca a la resolución correcta si alguien está usando una resolución más pequeña, o para escalar más si alguien está usando una resolución más grande.¿Cómo escalar a resolución en SDL?

El problema es que no he podido encontrar una forma eficiente de hacerlo. Comencé utilizando la biblioteca SDL_gfx para escalar previamente todas las imágenes, pero esto no funciona, ya que crea una gran cantidad de desvíos -one error, donde se estaba perdiendo un píxel. Y como mis animaciones están contenidas en una imagen cuando se reproduce la animación, la animación se moverá ligeramente hacia arriba o hacia abajo en cada fotograma.

Luego, después de un vistazo, he intentado usar OpenGL para manejar la escala. Actualmente mi programa dibuja todas las imágenes a una SDL_Surface que es 1920x1080. Luego convierte esta superficie en una textura opengl, escala esta textura a la resolución de la pantalla y luego dibuja la textura. Esto funciona bien visualmente, pero el problema es que no es eficiente en absoluto. Actualmente estoy recibiendo un fps máximo de 18 :(

Así que mi pregunta es ¿alguien sabe de una manera eficiente a escala de la pantalla SDL para la resolución de la pantalla?

+1

¿Está dibujando, convirtiendo y escalando sobre la marcha cuando está usando opengl? – silent

+0

Pregunte también a los chicos en el foro gamedev, deberían poder ayudarlo. – silent

+0

Sí, por eso soy tan ineficiente. Pero actualmente no puedo encontrar otra forma de hacerlo que funcione. OK lo haré. –

Respuesta

10

Es ineficiente porque OpenGL no fue diseñado para trabajar de esa . Via principal problemas de rendimiento con diseño actual:

  • primer problema:.. Eres rasterización de software con SDL lo sentimos, pero no importa lo que hagas con esta configuración, que será un cuello de botella a una resolución de 1920x1080, tiene 2.073.600 píxeles para colorear. Suponiendo que le tome 10 ciclos de reloj para sombrear cada píxel de 4 canales, en un procesador de 2 GHz está ejecutando un máximo de 96.4 fps. Eso no suena mal, excepto que probablemente no puede sombrear píxeles que rápido, y todavía no ha hecho AI, la entrada del usuario, la mecánica del juego, el sonido, la física y todo lo demás, y es probable que dibujando sobre algunos píxeles al menos una vez de todos modos. SDL_gfx puede ser rápido, pero para resoluciones grandes, la CPU solo está fundamentalmente acertada.
  • Segundo problema: cada fotograma, está copiando datos en el bus de gráficos a la GPU. Esta es la cosa más lenta que puedes hacer en cuanto a gráficos. Los datos de imagen son probablemente los peores de que, porque normalmente hay tanto. Básicamente, cada fotograma le está diciendo a la GPU que copie dos millones de píxeles de RAM a VRAM. De acuerdo con Wikipedia, puede esperar, para 2,073,600 píxeles a 4 bytes cada uno, no más de 258,9 fps, lo que de nuevo no suena mal hasta que recuerde todo lo demás que debe hacer.

Mi recomendación: cambie su aplicación completamente a OpenGL. Esto elimina la necesidad de renderizar una textura y copiarla a la pantalla, ¡simplemente renderiza directamente en la pantalla! Además, la escala se maneja automáticamente mediante su matriz de vista (glOrtho/gluOrtho2D para 2D), por lo que no tiene que preocuparse por en absoluto: su ventana solo mostrará todo en la misma escala. Esta es la solución ideal para su problema.

Ahora, viene con el inconveniente principal de que tiene que volver a codificar todo con los comandos de extracción de OpenGL (que funciona, pero no demasiado, especialmente a largo plazo). A falta de eso, puedes probar las siguientes ideas para mejorar la velocidad:

  • PBOs.Los objetos de búfer de píxeles se pueden usar para abordar el problema dos haciendo que la carga/copia de texturas sea asíncrona.
  • Multithread su representación. La mayoría de las CPU tienen al menos dos núcleos y en los chips más nuevos se pueden guardar dos estados de registro para un solo núcleo (Hyperthreading). Básicamente estás duplicando cómo la GPU resuelve el problema de renderizado (tienen muchos hilos en proceso). No estoy seguro de cómo es seguro el hilo SDL_gfx, pero apuesto a que algo podría resolverse, especialmente si solo está trabajando en diferentes partes de la imagen al mismo tiempo.
  • Asegúrate de prestar atención a qué lugar está la superficie de dibujo en SDL. Probablemente debería ser SDL_SWSURFACE (porque está dibujando en la CPU).
  • Eliminar VSync. Esto puede mejorar el rendimiento, incluso si no está funcionando a 60Hz
  • Asegúrese de estar dibujando su textura original - NO la suba o baje a una nueva. ¡Dibuja en un tamaño diferente, y deja que el rasterizador haga el trabajo!
  • Esporádicamente actualizada: solo actualice la mitad de la imagen a la vez. Esto probablemente se acercará al doble de su "velocidad de fotogramas", y (por lo general) no se nota.
  • De forma similar, solo actualice las partes cambiantes de la imagen.

Espero que esto ayude.

+0

SDL 2.0 ahora está fuera, y utiliza la aceleración 3D 'bajo el agua'. Entonces, ¿quizás esto podría estar ayudando a tu desempeño? –