Gdiplus - проблема с анимацией
Работаю с Gdiplus.
Мне нужно вывести анимацию. Причем вопрос не в том как отобразить анимированный *.gif, а как вывести последовательность кадров, чтобы получилась анимация.
Как это сделать - я, в принципе знаю, но возникла следующая проблема:
Имеем:
Сама анимация загружается в небольшой по размеру PaintBox1:
{
static int N = 20;
N++;
Gdiplus::Graphics *grphics = new Gdiplus::Graphics(PaintBox1->Canvas->Handle);
AnsiString Fname = ExtractFilePath(Application->ExeName) + "loop_animation\\loop_000" + IntToStr(N) + ".png";
WCHAR* buf = new WCHAR[ Fname.WideCharBufSize() ];
Gdiplus::Image *imge = new Gdiplus::Image( Fname.WideChar(buf, Fname.WideCharBufSize()) );
grphics->DrawImage(imge,
Gdiplus::Rect(0, 0,imge->GetWidth(), imge->GetHeight()));
if( N >= 56 ) N = 21;
delete grphics;
delete imge;
delete [] buf;
}
Изображение фона загружается в PaintBox2, растянутый на всю форму:
{
graphics = new Gdiplus::Graphics(PaintBox2->Canvas->Handle);
graphics->DrawImage(image,
Gdiplus::Rect(0, 0,image->GetWidth(), image->GetHeight()));
delete graphics;
}
Ну и таймер конечно:
{
//this->PaintBox2->OnPaint = NULL;
this->PaintBox1->Repaint();
//this->PaintBox2->OnPaint = PaintBox2Paint;
}
Проблема в том, что при такой организации при отображении анимации прога хавает порядка 70% проца.
Комментарии в таймере - то, что я пытался сделать. Просто при вызове Repaint'a PaintBox1 происходит прежде событие OnPaint PaintBox2.
Не спасло - получается, что область под PaintBox1 у PaintBox2(изображение прозрачное) не отрисовывается.
Проблема усугубляется тем, что пользователь имеет возможность изменять скорость анимации(таймера) в программе. А при такой работе ни о какой скорости и речи быть не может!..
Работаю с Gdiplus.
Мне нужно вывести анимацию. Причем вопрос не в том как отобразить анимированный *.gif, а как вывести последовательность кадров, чтобы получилась анимация.
Как это сделать - я, в принципе знаю, но возникла следующая проблема:
Имеем:
Сама анимация загружается в небольшой по размеру PaintBox1:
{
static int N = 20;
N++;
Gdiplus::Graphics *grphics = new Gdiplus::Graphics(PaintBox1->Canvas->Handle);
AnsiString Fname = ExtractFilePath(Application->ExeName) + "loop_animation\\loop_000" + IntToStr(N) + ".png";
WCHAR* buf = new WCHAR[ Fname.WideCharBufSize() ];
Gdiplus::Image *imge = new Gdiplus::Image( Fname.WideChar(buf, Fname.WideCharBufSize()) );
grphics->DrawImage(imge,
Gdiplus::Rect(0, 0,imge->GetWidth(), imge->GetHeight()));
if( N >= 56 ) N = 21;
delete grphics;
delete imge;
delete [] buf;
}
Изображение фона загружается в PaintBox2, растянутый на всю форму:
{
graphics = new Gdiplus::Graphics(PaintBox2->Canvas->Handle);
graphics->DrawImage(image,
Gdiplus::Rect(0, 0,image->GetWidth(), image->GetHeight()));
delete graphics;
}
Ну и таймер конечно:
{
//this->PaintBox2->OnPaint = NULL;
this->PaintBox1->Repaint();
//this->PaintBox2->OnPaint = PaintBox2Paint;
}
Проблема в том, что при такой организации при отображении анимации прога хавает порядка 70% проца.
Комментарии в таймере - то, что я пытался сделать. Просто при вызове Repaint'a PaintBox1 происходит прежде событие OnPaint PaintBox2.
Не спасло - получается, что область под PaintBox1 у PaintBox2(изображение прозрачное) не отрисовывается.
Проблема усугубляется тем, что пользователь имеет возможность изменять скорость анимации(таймера) в программе. А при такой работе ни о какой скорости и речи быть не может!..
Для начала - определи наиболее узкое место в программе. Кроме того - в форме включи двойную буферизацию, загрузку файла лучше делать заранее и возможно в потоке, и я бы отказался от использования PaintBox - я так понял фон у тебя постоянный - не проще ли рисовать анимацию непосредственно на нем?
Более того при неиспользовании двойной буферизации прога хавает лишь 10 процентов проца - что тоже ненормально. Так что двойная буферизация тут вообще ни при чем!!
2) Загрузка файла происходит в конструкторе формы, удаление - в деструкторе - аналогичная ситуация. В данной случае в таком количестве ест проц не загрузка файла, а его рисование - и только это!!
3) А что делать если фон непостоянный? Приведенный мною код 'немного' отличается от кода моей программы. Это лишь пример, который отражает возникшую проблему!
Более того при неиспользовании двойной буферизации прога хавает лишь 10 процентов проца - что тоже ненормально. Так что двойная буферизация тут вообще ни при чем!!
2) Загрузка файла происходит в конструкторе формы, удаление - в деструкторе - аналогичная ситуация. В данной случае в таком количестве ест проц не загрузка файла, а его рисование - и только это!!
3) А что делать если фон непостоянный? Приведенный мною код 'немного' отличается от кода моей программы. Это лишь пример, который отражает возникшую проблему!
Для начала определи - что именно тормозит программу - тем более что в приведенном тобой коде загрузка файла происходит при рисовании
Загрузка и рисование самого кадра - не приводит к съеданию проца. Если фон не рисуется - проц вообще не хавается(смотрю в диспетчере)!!
Я уже который раз объясняю, что тормозит прогу!! - РИСОВАНИЕ ФОНА, а ты меня не слушаешь!!
Загрузка и рисование самого кадра - не приводит к съеданию проца. Если фон не рисуется - проц вообще не хавается(смотрю в диспетчере)!!
Я уже который раз объясняю, что тормозит прогу!! - РИСОВАНИЕ ФОНА, а ты меня не слушаешь!!
Не кричи, бл%, не дома. И дома не кричи.
Русским языком тебе говорят - используй старый способ, работавший еще в досе - рисуешь картинку заранее - а потом ее копируешь на форму. Зачем использовать два пайтбокса, если полностью достаточно одного? А можно просто рисовать на канве формы - нафига цеплять лишние компоненты? Для анимации характерен последовательный вывод - т.е. ты можешь готовить сразу 20-30 картинок в отдельных потоках - но правда если нужна анимация с хорошей частотой - то лучше юзать DX - в противном случае тормоза при частоте порядка 10-25 кадров/сек. все равно будут - так как видеопамять напрямую не доступна.
Насчет двух и более PaintBox - а если произошли какие-либо изменения, результат которых отображается изображением меньшим изображения фона раз в 20. Например графическое выделение какого-либо объекта на фоне при наведении курсора!! По прежнему предлагаешь использовать один PaintBox-фон(загрузить сначала фон, а потом этот маленький Image)?? Не легче перерисовывать этот маленький PaintBox!!
Насчет DX - уже практически пришел к этому и сам!!
Интересует реализация именно на Gdiplus!! Считаю, что эта либа может с этим справиться!!
Насчет двух и более PaintBox - а если произошли какие-либо изменения, результат которых отображается изображением меньшим изображения фона раз в 20. Например графическое выделение какого-либо объекта на фоне при наведении курсора!! По прежнему предлагаешь использовать один PaintBox-фон(загрузить сначала фон, а потом этот маленький Image)?? Не легче перерисовывать этот маленький PaintBox!!
Насчет DX - уже практически пришел к этому и сам!!
Интересует реализация именно на Gdiplus!! Считаю, что эта либа может с этим справиться!!
Ни PaintBox ни Image не годятся для нормальной анимации. Если картинка большая - ее нужно загонять напрямую в видиопамять - иначе тормоза обеспечены.