Я ищу способ ускорить рисунок моего игрового механизма, который в настоящее время является значительным узким местом и вызывает замедление. Я нахожусь на грани преобразования его закончен к XNA, но я просто заметил что-то.
Скажите, что у меня есть маленькое изображение, которое я загрузил.
Image img = Image.FromFile("mypict.png");
У нас есть поле изображения на экране, который мы хотим привлечь. Таким образом, у нас есть обработчик.
pictureBox1.Paint += new PaintEventHandler(pictureBox1_Paint);
Я хочу, чтобы наше загруженное изображение было размещено рядом на поле изображения (это для игры, в конце концов). С какой стати этот код:
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);
}
БОЛЕЕ ЧЕМ В 25 РАЗ БЫСТРЕЕ, чем этот код:
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);
}
Для устранения очевидного я испытал комментарий последнего e. Графика. DrawImage (что означает, что я ничего не вижу, но он избавляется вызов, который не находится в первом примере). Я также уехал в блоке использования (напрасно) в первом примере, но это все еще столь же ослепительно быстро. Я установил свойства g
соответствовать e.Graphics
- вещи как InterpolationMode
, CompositingQuality
, и т.д., но ничто, что я делаю, не устраняет этот невероятный разрыв в производительности. Я не могу найти различие между двумя Графическими объектами. Что дает?
Мой тест с a System.Diagnostics.Stopwatch
говорит, что первый фрагмент кода работает на уровне приблизительно 7 100 кадр/с, в то время как вторые выполнения на уровне ничтожных 280 кадр/с. Мое ссылочное изображение VS2010ImageLibrary\Objects\png_format\WinVista\SecurityLock.png
, который составляет 48x48 пкс, и который я изменил, чтобы быть 72 точки на дюйм вместо 96, но имевшие никакое значение также.
Когда вы рисуете на экране, ОС может использовать преимущества специального оборудования графического адаптера для выполнения простых операций, таких как копирование изображения. около.
Я получаю ~ 5 мс для обоих. 7100 кадров в секунду - это слишком быстро для программного рендеринга, выполняемого GDI +. Видеодрайверы, как известно, обманывают, чтобы выиграть тесты, они могут обнаружить, что BitBlt не нужно выполнять, потому что изображение не изменилось. Попробуйте передать случайные значения в e.Graphics.TranslateTransform, чтобы устранить чит.
Вы уверены, что разница не в использовании блока, т. Е. В настройке блока try-finally и создании экземпляра Graphics из буфера изображений.
Я мог бы легко увидеть е последнее - дорогостоящая операция, в отличие от события рисования, когда вы просто получаете ссылку на уже созданный экземпляр графики.