Warum ist die Zeichnung zu OnPaint-Grafiken schneller als Bild-Grafik?
Ich bin auf der Suche nach einem Weg, um die Geschwindigkeit der Zeichnung meiner game-engine, die derzeit den maßgeblichen Engpass, und verursacht Verzögerungen. Ich bin kurz davor, zu konvertieren über XNA, aber ich habe gerade etwas bemerkt.
Sagen, ich habe ein kleines Bild, das ich geladen habe.
Image img = Image.FromFile("mypict.png");
Haben wir eine picturebox auf dem Bildschirm, die wir zeichnen möchten, auf. So haben wir eine handler.
pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
Möchte ich unsere geladenen Bild zu Kacheln auf der picturebox (das ist für ein Spiel, nachdem alle). Warum auf der Erde ist dieser code:
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);
}
über 25 MAL SCHNELLER als diese-code:
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);
}
Zur Beseitigung der offensichtlichen, habe ich versucht, das auskommentieren der letzten e.Grafik.DrawImage (was bedeutet, ich sehe nichts, aber es befreit einen Anruf, der nicht in dem ersten Beispiel). Ich habe auch Links in der using-block (unnötig) in dem ersten Beispiel, aber es ist immer noch genauso rasend schnell. Ich habe die Eigenschaften von g
passend e.Graphics
- Dinge wie InterpolationMode
, CompositingQuality
etc, aber nichts, was ich tun Brücken diese unglaubliche Lücke in der Leistung. Ich finde keine Unterschied zwischen die zwei Grafik-Objekte. Was gibt?
Meinem test mit einem System.Diagnostics.Stopwatch
sagt, dass der erste code-snippet läuft bei etwa 7100 fps, während die zweite läuft auf eine mickrige 280 fps. Mein Referenzbild ist VS2010ImageLibrary\Objects\png_format\WinVista\SecurityLock.png
, die 48x48 px, und die ich geändert werden 72 dpi statt 96, aber diejenigen, die entweder kein Unterschied gemacht.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie die Zeichnung auf dem Bildschirm ist das OS nutzen zu können, wird spezielle hardware in der Grafikkarte zu tun, einfache Vorgänge wie das kopieren eines Bildes um.
Ich bin immer ~5 msec für beide. 7100 fps ist Weg zu schnell für die software-rendering von GDI+. Video-Treiber notorisch betrügen, um zu gewinnen benchmarks, können Sie erkennen, dass ein BitBlt muss nicht durchgeführt werden, weil das Bild nicht ändern. Versuchen Weitergabe random-Werte e.Grafik.TranslateTransform zu beseitigen, den cheat.
e.Graphics.TranslateTransform((float)rand.NextDouble(), (float)rand.NextDouble());
innerhalb der Zeichnung Schleife. Es ging von 7100 bis 5000 fps. Versuchen Sie es erneut?Sind Sie sicher, dass der Unterschied nicht aus den using-block, D. H. das einrichten der try-finally-block und die Erstellung der Grafiken Beispiel aus dem Bild-Puffer.
Ich konnte leicht sehen, den letzteren als eine teure operation, im Gegensatz zu den paint-event, wo man einfach einen Verweis auf eine bereits erstellte Grafiken Instanz.