Ребята, подскажите плз! Не могу сообразить, как в GDI+ можно избежать мерцания, при выводе на экран? В обычной GDI всё очень просто: с помощью блиттинга (BitBlt), ...
В структуре, которая передается в RegisterClassEx, есть член style, в нем есть флаги, которые отвечают за перерисовку окна
Rustem CS_WREDRAW, CS_HREDRAW? Наверно, ты имеешь ввиду стили перерисовки окна при изменении размеров по вертикали и по горизонтали: CS_HREDRAW or CS_VREDRAW... А если, я заставляю перерисовать окно не при изменении размера, а, например, при перемещении мыши по окну? Что тогда? Мне почему-то кажется, что нужно что-то выключить, а потом включить. Или рисовать в памяти (CompatibleDC, CompatibleBitmap, ...), как в обычной GDI... Но как это делается в GDI+ я не догоняю
Vasil Можно рисовать без мерцания и прямо на экран, если хорошо понимать из-за чего происходит мерцание. В противном случае, спасает двойной буфер. Погугли по GDI+ flicker double buffer. Есть несколько рабочих методов.
Да, нашёл GDI+ flicker double buffer http://rsdn.ru/article/gdi/gdiplus2mag.xml#ETIAE ЗЫ: Жаль, что ни на асме, - не удобно копаться в SDK по GDI+ )
Vasil Тут Rustem дал правильное направление при регистрации класса: mov [wc.hbrBackground], 0 иначе винда сначала сама заливает окно Backgroundом, а только потом передаёт тебе возможность рисовать, так что никакие буферизации от этого не лечат ))
Делаю демку ElasticCollisions, оригинал на канале Даниила. Переделка на ассемблер SSE2 и GDI+ и эти шарики мерцают, я так понял лучше использовать буфер, рисуем сначала в буфер а потом копируем на форму командой GdipSetClipGraphics. Или ещё как-то надо разбираться, все примеры для С++, для асма либо просто Си не нашёл. --- Сообщение объединено, 2 сен 2024 --- Непонятно как создать буфер. GdipSetClipGraphics(hGraphics, hSrcGraphics, 0) Надо создать hSrcGraphics нужного размера, но что-то я не понял как.
Как-то так создаётся буфер. Код (ASM): ;создание буфера ;Bitmap backBuffer(g_iWidth, g_iHeight, &hGraphics); // создаем буфер, кот. будет хранить рисуемое изображение GdipCreateBitmapFromGraphics(g_iWidth, g_iHeight, hGraphics, &backBuffer) ;Graphics hBuffGraphics(&backBuffer); // создаем объект класса Graphics для рисования в буфер GdipGetImageGraphicsContext(backBuffer, &hBuffGraphics) Это UASM если что. Рисуем на форму: GdipGraphicsClear(hBuffGraphics, 0FF000000h) ;// чёрный цвет фона ... ;//тут что рисуем в буфер GdipDrawImage(hGraphics, backBuffer, 0, 0) ;// выводим на экран, т.е. главную форму. И ещё рекомендации от Y_Mur использую.
возможно, я брякну мимо кассы пять коп, но во времена до-GDI+ не мерцающие GUI тоже создавали, с помощью объяснения винде, какой именно прямоугольник окна "грязный" и нуждается в перерисовке доки можно полистать для InvalidateRect() и WM_PAINT то есть, если цель только указатель мышки отобразить на экране, то нет необходимости перерисовывать всю площадь формы - достаточно в старых и новых границах курсора что как правило быстрее получается
miilalex, раньше было лучше! Во времена ДОС я бы создал в памяти В/К два буфера, в один я бы рисовал спрайт круга, и на моменте кадра переключал бы их. Это обеспечило очень хорошую оптимизацию и высокую скорость. Но к сожалению виндавоз не обеспечил нужными функциями, их просто нет, а так бы хотелось каллбек на завершения кадра. Но это возможно лишь в дериктрихс............