Еще о работе различных видео функций.

Насколько я понимаю, SetBitmapBits не выполняе ни каких преобразований - тупо копируя ВСЕ байты изображения из буфера в видеопамять... Есть у меня своя функция которая попиксельно обрабатывет то же изображение, при этом для каждого пиксела выполняется оператор IF, так вот эта функция работает в 5-10 раз быстрее чем SetBitmapBits... Либо я чего-то непонимаю либо скорость работы SetBitmapBits искусвенно снижена раз в 50...
MSDN говорит, что:
1. SetBitmapBits оставлена для совместимости с Win16, и все доджны пользовать SetDIBits
2. SetDIBits может выполнять преобразования цветовых данных и даже использовать ICM.
ЗЫ Может с CreateDIBSection проще будет?
Ну если для выполнения SetBitmapBits каждый раз происходит переключение в 16 разрядный режим тогда понятно...
C CreateDIBSection может и проще, но есть готовые функции ориентированные на DDB изображения, а на DIB все надо по новой писать
Попробуй вызывать SetDIBits. Может все же быстрее будет, тем более форматы цветовой информации совпадают.
SetDIBits - попробовал, какого-либо выигрыша в скорости не заметил...
CreateDIBSection - тоже попробовал, с тем же результатом.
А что ты делаешь с пикселами битмапа (постановку задаче поподробнее)? Может какой еще подход сработает...
Беру с экрана прямоугольную область накладываю на нее изображение и возвращаю все на экран. Все было бы гораздо проще если бы был "прзрачный" цвет, хотя это не решит всех проблем
Все кнопочки в винде рисуются в два этапа, используя генерящиеся по одному цвету маски. В WinApi есть функция MaskBlt, которая этим и занимается... Да и маску сделать не очень сложно... В дельфе TBitmap умеет... могу привести кусочек кода оттуда..
Да, возможно MaskBlt поможет решить часть проблем...
И еще обнаружилась странная ситуация на P-1 233 и S3 все работает быстрее чем на P-3 600 и Velocity 100, немного, но быстрее, но если делаю простой тест видеовывода (BitBlt всего экрана в цикле) то P-3 почти в 10 раз быстрее!
В чем может быть дело, где копать?
Скорее всего причина в этом, большинство видеокарточек очень сильно тормозят при чтении видеопамяти. Храни фон отдельно в памяти, накладывай и выводи. А вообще если хочешь максимальную скорость используй DirectDraw, там и прозрачные пиксели есть.
Насчёт MaskBlt, он в Win95-98 не работает.
Где ты рнаньше был :)
Я только переделал все на MaskBlt! и прибалдел как оно все быстро... Но впрочем под Win 9x SetBit... работает раза в 2 быстрее чем под NT, придется наверно держать 2 варианта функций под NT и 9x...
А зачем если не секрет ты читаешь с экрана ? Вернее, так: ты читаешь туда то, что записала твоя программа или нет ?
В данном конкретном случае читаю то-что записала моя программа, а для хранения образа экрана в памяти нужно лишних 3Mb RAM - жалко... но видимо придется пожертвовать.
Конечно жертвуй.
Offscreen drawing - сила
И используй CreateDIBSection
в качестве примера к вопросу о производительности: (хоть код и delphi c её объектом TBitmap, но я думаю это не важно)
procedure TForm1.Button1Click(Sender: TObject);
var
Bitmap :TBitmap;
pBitmapLine :PByteArray;
i,j,i3 :integer;
time1,time2 :integer;
begin
// берём время в начале
time1 := GetCurrentTime;

// создаём Bitmap
Bitmap := TBitmap.Create;
Bitmap.Width := 1024;
Bitmap.Height := 768;
Bitmap.PixelFormat := pf24bit; //RGB

// заполняем изображение (синие поле)
for j:=0 to 767 do
begin
pBitmapLine := Bitmap.ScanLine[j];
for i:=0 to 1023 do
begin
i3 := i*3;
pBitmapLine^[i3 ] := $FF; // Blue
pBitmapLine^[i3+1] := $00; // Green
pBitmapLine^[i3+2] := $00; // Red
end;
end;

// отображаем Bitmap на экране
PaintBox1.Left := 0;
PaintBox1.Top := 0;
PaintBox1.Width := Bitmap.Width;
PaintBox1.Height := Bitmap.Height;
PaintBox1.Canvas.Draw(0,0,Bitmap);

// выгружаем Bitmap
Bitmap.Free;

// считаем время
time2 := GetCurrentTime;
Caption := Format('%d',[(time2-time1)])+' msec';
end;


на Cel333 - 64RAM - S3Trio (1Mb)

время исполнения этого кода (этого рисования) составляет в среднем 180 миллисекунд

180 ms это все 5 fps, а нужно минимум 20-30 для боле-менее приличного анимирования. Ну под NT за счет MaskBlt все получается отлично с запасом, а для 9х чего-нибудь придумаем...
для начала - это же не OpenGL или D3D - какие тут fps-ы в GDI - на этой Trio (1 метр + полностью отключено ускорение) даже через DirectX в разрешении 640x480x32 дай бог 3 fps в играх, гы , а тут я ведь измерял картинку 1024x768x24 + в это время вошло создание, заполнение, отображение, удаление
И тем не менее, даже на P-1 233 вполне можно получить 40-50 fps для 2D анимашки, без DirectX и OpenGL, только поизгалятся придется...
40-50 fps мне как-то сомнительным кажется, тем более какого размера? но то что Можно поизгалятся с этим согласен переписать всё без лишних наворотов без объектных библиотек, всё на комбинации API + asm ну и естественно качественно продуманный оптимизированный алгоритм.
Если захочешь реальные fps, то прийдётся писать на asm-е Кстати, писать на API или на MFC тут не так критично - единственно что для часто используемых DC не стоит сабклассить их в CDC, да и GDI-ные обьекты лучше юзать через API.
CreateDIBSection, как раз и хороша тем, что ты можешь рисовать как через GDI, так и напрямую в bitmap через указатель памяти
CreateDIBSection - хороша то она хороша но работает во много раз медленне чем CompatibleBitmap, хотя скорее всего именно ее и предется использовать... Хотя MaskBlt очень бвстро работает, какого [] ее в 9х не поддерживают, но впроочем всех проблем она все равно не решает так что остается CreateDIBSection.
Вообще, как я понял, когда создается CompatibleBitmap то вынь старается разместить битовый буфер в локальной видеопамяти и если это удается то работает она ооочень быстро, но почему перекрыты (почти) все лазейки для быстрого копирования из основной памяти в память видеокарты!
Кстати потестировал сейчас CreateDIBSection, оказалось что максимальная скорость достигается в том случае если кол-во цветов в Bitmap совпадает с кол-во цветов экрана, причем различие в скорости в 2-3 раза! так что все равно придется делать 4 разных наборов функци (4- битный цвет я проигнорирую )

TopList Rambler's Top100