Мерцание в GDI+

Тема в разделе "WASM.WIN32", создана пользователем Vasil, 19 окт 2006.

  1. Vasil

    Vasil Василь

    Публикаций:
    0
    Регистрация:
    7 янв 2006
    Сообщения:
    228
    Адрес:
    Ижевск
    Ребята, подскажите плз!
    Не могу сообразить, как в GDI+ можно избежать мерцания, при выводе на экран?
    В обычной GDI всё очень просто: с помощью блиттинга (BitBlt), ...
     
  2. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    В структуре, которая передается в RegisterClassEx, есть член style, в нем есть флаги, которые отвечают за перерисовку окна
     
  3. Rustem

    Rustem New Member

    Публикаций:
    0
    Регистрация:
    8 мар 2004
    Сообщения:
    429
    Адрес:
    Russia
    CS_WREDRAW, CS_HREDRAW
     
  4. Vasil

    Vasil Василь

    Публикаций:
    0
    Регистрация:
    7 янв 2006
    Сообщения:
    228
    Адрес:
    Ижевск
    Rustem
    CS_WREDRAW, CS_HREDRAW?
    Наверно, ты имеешь ввиду стили перерисовки окна при изменении размеров по вертикали и по горизонтали:
    CS_HREDRAW or CS_VREDRAW...

    А если, я заставляю перерисовать окно не при изменении размера, а, например, при перемещении мыши по окну? Что тогда?

    Мне почему-то кажется, что нужно что-то выключить, а потом включить. Или рисовать в памяти (CompatibleDC, CompatibleBitmap, ...), как в обычной GDI...
    Но как это делается в GDI+ я не догоняю :dntknw:
     
  5. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    Vasil
    Можно рисовать без мерцания и прямо на экран, если хорошо понимать из-за чего происходит мерцание. В противном случае, спасает двойной буфер.

    Погугли по GDI+ flicker double buffer. Есть несколько рабочих методов.
     
  6. Vasil

    Vasil Василь

    Публикаций:
    0
    Регистрация:
    7 янв 2006
    Сообщения:
    228
    Адрес:
    Ижевск
  7. Y_Mur

    Y_Mur Active Member

    Публикаций:
    0
    Регистрация:
    6 сен 2006
    Сообщения:
    2.494
    Vasil
    Тут Rustem дал правильное направление при регистрации класса:
    mov [wc.hbrBackground], 0
    иначе винда сначала сама заливает окно Backgroundом, а только потом передаёт тебе возможность рисовать, так что никакие буферизации от этого не лечат :)))
     
    miilalex нравится это.
  8. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    Делаю демку ElasticCollisions, оригинал на канале Даниила. Переделка на ассемблер SSE2 и GDI+ и эти шарики мерцают, я так понял лучше использовать буфер, рисуем сначала в буфер а потом копируем на форму командой GdipSetClipGraphics. Или ещё как-то надо разбираться, все примеры для С++, для асма либо просто Си не нашёл.
    --- Сообщение объединено, 2 сен 2024 ---
    Непонятно как создать буфер.
    GdipSetClipGraphics(hGraphics, hSrcGraphics, 0)
    Надо создать hSrcGraphics нужного размера, но что-то я не понял как.
     
  9. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    Как-то так создаётся буфер.
    Код (ASM):
    1. ;создание буфера
    2. ;Bitmap backBuffer(g_iWidth, g_iHeight, &hGraphics);  // создаем буфер, кот. будет хранить рисуемое изображение
    3. GdipCreateBitmapFromGraphics(g_iWidth, g_iHeight, hGraphics, &backBuffer)
    4. ;Graphics hBuffGraphics(&backBuffer);  // создаем объект класса Graphics для рисования в буфер
    5. GdipGetImageGraphicsContext(backBuffer, &hBuffGraphics)
    Это UASM если что.
    Рисуем на форму:
    GdipGraphicsClear(hBuffGraphics, 0FF000000h) ;// чёрный цвет фона
    ... ;//тут что рисуем в буфер
    GdipDrawImage(hGraphics, backBuffer, 0, 0) ;// выводим на экран, т.е. главную форму.
    И ещё рекомендации от Y_Mur использую.
     
  10. miilalex

    miilalex New Member

    Публикаций:
    0
    Регистрация:
    8 сен 2024
    Сообщения:
    8
    возможно, я брякну мимо кассы пять коп, но во времена до-GDI+ не мерцающие GUI тоже создавали, с помощью объяснения винде, какой именно прямоугольник окна "грязный" и нуждается в перерисовке

    доки можно полистать для InvalidateRect() и WM_PAINT

    то есть, если цель только указатель мышки отобразить на экране, то нет необходимости перерисовывать всю площадь формы - достаточно в старых и новых границах курсора
    что как правило быстрее получается
     
  11. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    600
    miilalex, раньше было лучше! Во времена ДОС я бы создал в памяти В/К два буфера, в один я бы рисовал спрайт круга, и на моменте кадра переключал бы их. Это обеспечило очень хорошую оптимизацию и высокую скорость. Но к сожалению виндавоз не обеспечил нужными функциями, их просто нет, а так бы хотелось каллбек на завершения кадра. Но это возможно лишь в дериктрихс............
     
    miilalex нравится это.