Estoy buscando una manera de acelerar el dibujo de mi motor de juego, que actualmente es el importante cuello de botella y está causando ralentizaciones. Estoy a punto de convertirlo a XNA, pero acabo de notar algo.¿Por qué el dibujo en gráficos OnPaint es más rápido que los gráficos de imagen?
Supongamos que tengo una imagen pequeña que he cargado.
Image img = Image.FromFile("mypict.png");
Tenemos un recuadro de imagen en la pantalla que queremos dibujar. Entonces tenemos un controlador.
pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
Quiero que nuestra imagen cargada a revestir en el cuadro de imagen (esto es para un juego, después de todo). ¿Por qué en la tierra es este código:
void pictureBox1_Paint(object sender, PaintEventArgs e)
{
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x++)
e.Graphics.DrawImage(image, x * 16, y * 16, 16, 16);
}
más de 25 veces más rápido que este código:
Image buff = new Bitmap(256, 256, PixelFormat.Format32bppPArgb); // actually a form member
void pictureBox1_Paint(object sender, PaintEventArgs e)
{
using (Graphics g = Graphics.FromImage(buff))
{
for (int y = 0; y < 16; y++)
for (int x = 0; x < 16; x++)
g.DrawImage(image, x * 16, y * 16, 16, 16);
}
e.Graphics.DrawImage(buff, 0, 0, 256, 256);
}
Para eliminar lo obvio, lo he intentado comentando la última e.Graphics.DrawImage (lo que significa No veo nada, pero elimina una llamada que no está en el primer ejemplo). También me he quedado en el bloque de uso (innecesariamente) en el primer ejemplo, pero sigue siendo increíblemente rápido. Establecí las propiedades de g
para que coincida con e.Graphics
- cosas como InterpolationMode
, CompositingQuality
, etc., pero nada de lo que haga supera esta increíble brecha de rendimiento. No puedo encontrar ninguna diferencia entre los dos objetos de Gráficos. ¿Lo que da?
Mi prueba con un System.Diagnostics.Stopwatch
dice que el primer fragmento de código se ejecuta a aproximadamente 7100 fps, mientras que el segundo funciona a unos míseros 280 fps. Mi imagen de referencia es VS2010ImageLibrary\Objects\png_format\WinVista\SecurityLock.png
, que es de 48x48 px, y la modifiqué para que fuera de 72 dpi en lugar de 96, pero tampoco importó.
Crear objetos gráficos es muy costoso, creo que tiene razón y la configuración como parte de la cláusula de uso (y la creación del búfer) afectará el rendimiento, sin embargo, eso significa que no debe preocuparse por asegurarse de que el objeto gráfico se destruye después. Intente crearlos en el momento del inicio y vuelva a usarlos durante el tiempo de ejecución, pero asegúrese de destruirlos al salir. – Frozenskys
Dije en mi publicación, traté de irme en el bloque de uso. Es decir, tome el segundo fragmento, comente e.Graphics.DrawImage y cambie g.DrawImage en e.Graphics.DrawImage. De repente es tan rápido como el primer fragmento. – Tesserex