На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> Плавный гуишный процесс , без загрузок
    Нужно реализовать плавный гуишный процесс. Например, процесс игры, где что-то плавно движется и отображается в окне. Либо что-то рисуется.
    Варианты:
    1. Использовать таймер.
    2. Использовать цикл с задержкой через Sleep (а обработку сообщений окна – через PeekMessage).
    3. Какой-то другой(?)

    Проблема п.1 и 2 заключается в том, что сделать достаточно короткую задержку весьма проблематично. У меня (на 10-ке) Sleep(1) работает примерно как Sleep(2), а Sleep(4) – как Sleep(5).
    Использование таймера работает ещё хуже, там при установке интервалов в 1 мс процедура таймера вызывается раз в 10-20 мс или что-то в этом духе.
    Вариант задержки через цикл с GetTickCount (или через QueryPerformanceCounter) вместо использования Sleep – отличный вариант, но грузит процессор по самое не хочу. Sleep(0), естественно, тут не помогает.

    Что можно сделать в данной ситуации. Может, с оконной функцией можно как-то поиграться?
    Как это вообще делается обычно?
      Цитата Jin X @
      Как это вообще делается обычно?

      Обычно -- вечным циклом и ожиданием мультимедийного таймера. Впрочем, задача изначально решается у тебя не тем инструментарием.
        Пока почитайте про игры
        https://m.habrahabr.ru/post/136878/
        А про таймеры сейчас напишу.

        Добавлено
        Цитата Jin X @
        2. Использовать цикл с задержкой через Sleep (а обработку сообщений окна – через PeekMessage).

        В побочном потоке sleep в 2 раза быстрее, чем в главном потоке!

        Цитата Jin X @
        1. Использовать таймер.

        Есть специальный мультимедийный таймер.

        uses mmsystem;

        timeBeginPeriod(1); // Устанавливаем частоту срабатывания мультимедийного таймера в 1 мс.
        Установка глобально и распространяется на все программы в ОС, так что всякие там СУБД и медиаплееры уже могли его выставить.

        MMTimer1 := timeSetEvent(1,1,@MyTimerCallBackProg,100,TIME_PERIODIC);

        Для gpGPU нужно точность меньше 1 мс.
        Некоторые писали о том, что на SetWaitableTimer им удалось добиться 250 мкс (на win 10).
          Есть ещё NtDelayExecution, он работает поточнее, чем Sleep, но всё равно не фонтан (точность 1 мс примерно).

          Добавлено
          Цитата B.V. @
          Обычно -- вечным циклом и ожиданием мультимедийного таймера.
          Под вечный циклом ты имеешь в виду цикл обработки сообщений или что?
            Цитата Jin X @
            Под вечный циклом ты имеешь в виду цикл обработки сообщений или что?

            Нет, я имею ввиду
            ExpandedWrap disabled
              while(!exit_event) {}

            Впрочем, Pavia выше уже привёл неплохую ссылочку
              Цитата Jin X @
              Есть ещё NtDelayExecution, он работает поточнее, чем Sleep, но всё равно не фонтан (точность 1 мс примерно).

              Точность 0.5 мс (обычно), только надо сначала установить эту точность:
              ExpandedWrap disabled
                ULONG minRes, maxRes, curRes, oldRes;
                NtQueryTimerResolution(&minRes, &maxRes, &curRes);
                NtSetTimerResolution(maxRes, true, &oldRes);


              Добавлено
              Цитата Jin X @
              Например, процесс игры, где что-то плавно движется и отображается в окне.

              Тут не таймер нужен, а VSync. Как именно его делать, зависит от используемого для отрисовки API (DirectX/OpenGL/что-то другое).
                Цитата Pacific @
                VSync. Как именно его делать, зависит от используемого для отрисовки API
                GDI :P

                Добавлено
                Цитата Pacific @
                Точность 0.5 мс (обычно), только надо сначала установить эту точность
                Огонь! Так и есть, 5000 :good:
                  Цитата Pacific @
                  Тут не таймер нужен, а VSync. Как именно его делать, зависит от используемого для отрисовки API (DirectX/OpenGL/что-то другое).

                  Зачем? В современных видео-картах есть двойная и тройная буферизация. VSync нужен только для WinXp, а эта ОС уже отжила своё. А Win10 буферизация по умолчанию включена.
                    Цитата B.V. @
                    Обычно -- вечным циклом и ожиданием мультимедийного таймера.
                    Цитата Pavia @
                    MMTimer1 := timeSetEvent(1,1,@MyTimerCallBackProg,100,TIME_PERIODIC);
                    Там всё равно разрешение 1 мс.
                    А вообще (мне тут намекнули в другом месте), поскольку частота обновления всё равно не бывает выше 240 Гц, можно делать задержки по 4 мс и просто отрисовывать больше за раз :)
                    Но тема минимальных задержек всё равно интересна... :)

                    Добавлено
                    Цитата B.V. @
                    while(!exit_event) {}
                    Ну это явно проц не разгрузит (вопрос был, в первую очередь, об этом).

                    Цитата Pavia @
                    Пока почитайте про игры
                    https://m.habrahabr.ru/post/136878/
                    Посмотрю, спасибо! :good:
                      Цитата Jin X @
                      А вообще (мне тут намекнули в другом месте), поскольку частота обновления всё равно не бывает выше 240 Гц, можно делать задержки по 4 мс и просто отрисовывать больше за раз :)
                      Но тема минимальных задержек всё равно интересна... :)

                      Человеческий глаз не видит мельканий, если частота выше 48 герц.
                      (Пусть 50 для ровного счёта.)
                      Значит, период обновления 20 [мс] уже устроит.

                      Добавлено
                      Цитата Jin X @
                      Может, с оконной функцией можно как-то поиграться?

                      Попробуй оконную функцию оставить только для вывода, а рабочий поток - для рисования.
                      И работать только по событиям.
                      Например, сработало событие-таймер.
                      Проснулись, нарисовали, передали главному потоку, заснули.
                      Главный поток вывел и успокоился.
                      И.т.д.
                        Цитата ЫукпШ @
                        Человеческий глаз не видит мельканий, если частота выше 48 герц.
                        (Пусть 50 для ровного счёта.)
                        Значит, период обновления 20 [мс] уже устроит.
                        Это всё очень условно и старо. Разве не видно мерцания обычной лампочки 50 Гц, по крайней мере, если смотреть чуть мимо? И это с учётом того, что вольфрамовая нить остывает не мгновенно, а гораздо медленнее, чем ЖК.
                        Я сделал движение с интервалом 20 мс – видно дёргание картинки (даже при смещении на 1 пиксель). На 10-15 уже плавно. В принципе да, 70-100 Гц достаточно. Если очень хочется – 200-250 Гц :)

                        Цитата ЫукпШ @
                        Попробуй оконную функцию оставить только для вывода, а рабочий поток - для рисования.
                        Так и есть.
                        Я про то, что, может, можно использовать оконную функцию для частого вывода.
                        Например, в конце отрисовки посылать UpdateWindow в конце отрисовки. Но я так уже попробовал – результат с загрузкой процессора тот же.
                        Поэтому подумал, что, может, как-то ещё можно сделать...
                          Цитата ЫукпШ @
                          Человеческий глаз не видит мельканий, если частота выше 48 герц.

                          Это миф. Частота фильмов 24 связано с тем что на плёнке параллельно шёл звук и его надо было синхронизировать. А так как плёнка была одна то и получилось 24 кадра или 24 КГц.
                          С глазом это не связано.
                          Что касается мозг и глаз я уже писал цифры,
                          Реакция мозга 115-150 мс.
                          Реакция глаза 9 мс.

                          Цитата Jin X @
                          Я сделал движение с интервалом 20 мс – видно дёргание картинки (даже при смещении на 1 пиксель).

                          Глаз меряет скорость довольно точно. А вот таймер может плавать достаточно сильно. Дело в том что ОС многозадачная и вашу программу могут прерывать и на 10 и даже на 100 мс.
                          Поэтому обязательно нужно рассчитывать интервал между срабатыванием таймеров и рассчитывать скорость перемещения, а не каждый раз на 1 пиксель смещать.
                            Цитата Jin X @
                            Разве не видно мерцания обычной лампочки 50 Гц, по крайней мере, если смотреть чуть мимо?
                            Глаз (не только у человека) устроен так, что центральная часть поля зрения отвечает за распознавание предметов, для чего требуется высокая чёткость, без необходимости реагировать на быстрые изменения, а периферия отвечает за безопасность владельца глаза, для чего чёткость не нужна, зато нужно очень быстро реагировать на малейшие изменения. Поэтому там и мерцание лучше обнаруживается. Некоторые боковым зрением мерцание ЖК мониторов видят (60 Гц). Там ещё и реакция быстрее.
                            Цитата Jin X @
                            Я сделал движение с интервалом 20 мс – видно дёргание картинки
                            Частота развёртки какая? Строго говоря, картинка на экране обновляется только при его перерисовке с частотой 60 Гц. Поэтому обновление кадра, если отношение частоты времени отрисовки к периоду развёртки где-то между 0.5 и 2 обычно лучше привязать к кадровой развёртке. Это не имеет значения на мониторах с высокой частотой кадров.
                              Цитата Pavia @
                              Поэтому обязательно нужно рассчитывать интервал между срабатыванием таймеров и рассчитывать скорость перемещения, а не каждый раз на 1 пиксель смещать.
                              Это всё понятно, но есть ещё один нюанс.
                              Допустим, нам нужно смещать картинку на 1 пиксель каждые 10 мс.
                              Исходные условия: время = 0.

                              ИТЕРАЦИЯ ОТРИСОВКИ 0.
                              1. Мы отрисовали стартовую картинку и вывели её.
                              2. Замеряем время, получили 10 мс.
                              ИТЕРАЦИЯ ОТРИСОВКИ 1.
                              3. Рисуем на 1 пиксель дальше, выводим картинку.
                              4. Замеряем время, получили 20 мс.
                              5. Произошла незапланированная задержка на 30 мс.
                              ИТЕРАЦИЯ ОТРИСОВКИ 2.
                              6. Рисуем на 1 пиксель дальше, выводим картинку (хотя по факту прошло уже 40 мс).
                              7. Замеряем время, получили 60 мс.
                              ИТЕРАЦИЯ ОТРИСОВКИ 3.
                              8. Рисуем на 4 пикселя дальше, выводим картинку (хотя по факту прошло 10 мс).

                              На 2 и 3 итерациях отрисовки произошло неверное перемещение: в первом случае задержка была больше, чем рассчитано, во втором – меньше. Всё равно картинка дёрнулась.


                              Цитата amk @
                              Частота развёртки какая?
                              60 Гц.
                                Цитата amk @
                                Некоторые боковым зрением мерцание ЖК мониторов видят (60 Гц). Там ещё и реакция быстрее.
                                Я совсем боковым вижу и 70 Гц-мерцание на ЭЛТ монике. :blush:
                                  Цитата Славян @
                                  Я совсем боковым вижу и 70 Гц-мерцание на ЭЛТ монике.
                                  Похоже у тебя хорошо развито определение движения. Большинство 70Гц уже не воспринимают даже самым краем глаза. Впрочем, некоторые уже за пределами градусов 60 от центра похоже вообще ничего не воспринимают, кроме яркости.
                                  Я 75 Гц ставил, на 70 через пару часов подташнивать начинало. Похоже наводки от сети в развёртку пробивались и этого пятигерцового покачивания картинки хватало. Хотя я морской болезнью вроде не страдаю.
                                    Цитата Славян @
                                    Цитата amk @
                                    Некоторые боковым зрением мерцание ЖК мониторов видят (60 Гц). Там ещё и реакция быстрее.
                                    Я совсем боковым вижу и 70 Гц-мерцание на ЭЛТ монике. :blush:

                                    я думаю, что это ошибка.
                                    ---
                                    Эдак я и килогерцовое мелькание видел. На 7-ми сегментном индикаторе с динамической
                                    индикацией 1000 гц. Этот эффект возникает, когда мелькание изображения с одной частотой,
                                    освещают внешним светом с другой частотой.
                                    Те при внешнем электрическом освещении от сети переменного тока вообще.
                                    Между частотами возникают "биения" (могут возникнуть).
                                    Если частота биений будет меньше 48 [гц], можно увидеть "мелькания" и другие эффекты.
                                    Особенно при быстром движении головы. Причину этого усиления заметности движением я не знаю.

                                    Добавлено
                                    Цитата Pavia @
                                    Цитата ЫукпШ @
                                    Человеческий глаз не видит мельканий, если частота выше 48 герц.

                                    Это миф. Частота фильмов 24 связано с тем что на плёнке параллельно шёл звук и его надо было синхронизировать. А так как плёнка была одна то и получилось 24 кадра или 24 КГц.

                                    Скрытый текст

                                    Товарищ !
                                    Соблюдай аккуратность и бдительность !
                                    Не путай герцы с килогерцами
                                    Иначе однажды больно и мучительно
                                    Остановится твоё сердце
                                    Необходимо точно и правильно
                                    величин порядки считать
                                    Перепутав киловольты с вольтами
                                    не сможешь даже закричать..

                                    Неверные представления.
                                    Частота протягивания плёнки - 24 кадра в секунду.
                                    Это ограничения было вызвано техническими возможностями протяга плёнки вообще.
                                    Такое мелькание хорошо было бы заметно.
                                    Чтобы не было видно мельканий каджый кадр "показывают два раза".
                                    К звуку это не имеет никакого отношения.
                                    У меня в детстве был домашний кинопроектор - показывал кино без звука.
                                    Скорость можно было регулировать вручную, и сразу визуально видна была граница,
                                    когда мелькания становились не заметны.
                                    ---
                                    Частота развёртки ТВ - 50 гц (20 мс). Кстати, меняется только половина кадра - развётка черезстрочная.
                                    Мельканий мы не видим. Однако, при "быстром движении головы" на быстрых изменениях сюжета можно
                                    увидеть некие "видеоэффекты".

                                    Добавлено
                                    Цитата Jin X @
                                    Я сделал движение с интервалом 20 мс – видно дёргание картинки (даже при смещении на 1 пиксель). На 10-15 уже плавно. В принципе да, 70-100 Гц достаточно. Если очень хочется – 200-250 Гц :)

                                    Дёргание картинки и частота обновления экрана - разные вещи. ;)
                                    Очевидно, любое резкое изменения сюжета будет заметно при любой частоте обновления.
                                    Вратарь неподвижно стоит в воротах.. и тут шайба пулей влетает в сетку, её
                                    и увидеть то трудно. Так и должно быть.

                                    Добавлено
                                    Цитата Jin X @
                                    Цитата ЫукпШ @
                                    Человеческий глаз не видит мельканий, если частота выше 48 герц.
                                    (Пусть 50 для ровного счёта.)
                                    Значит, период обновления 20 [мс] уже устроит.
                                    Это всё очень условно и старо. Разве не видно мерцания обычной лампочки 50 Гц, по крайней мере, если смотреть чуть мимо?

                                    я вообще не понимаю про "старо".
                                    Если посмотреть на график напряжения (и тока конечно) через лампочку,
                                    тогда мы увидем 2 пика тока за период 50 гц.
                                    Это значит, что лампочка "мигает" 2 раза за период, те с частотой 100 гц.
                                    Значит, частоты мелькания 100 гц тоже не достаточно ?
                                    Сообщение отредактировано: ЫукпШ -
                                      Цитата ЫукпШ @
                                      У меня в детстве был домашний кинопроектор - показывал кино без звука.
                                      Скорость можно было регулировать вручную, и сразу визуально видна была граница,
                                      когда мелькания становились не заметны.

                                      Это строб-эффект, в проекторе есть забыл слово. Есть сепаратор который разделяет кадры - вентилятор когда вы уменьшали частоту то уменьшалась частота плёнки но не сепаратора из-за чего возникал строб-эффект поэтому и казалось что кадры начинают "моргать".

                                      Возьмите не старый проектор, а обычный монитор и повторите свой эксперимент вы можете поставить воспроизведение на 10-15 кадров в секунду и картинка будет двигаться плавна без рывков. Всё потому что рефлексы мозга не превышает 115 мс = 8٫6 кадрос/с.
                                        Цитата ЫукпШ @
                                        Чтобы не было видно мельканий каджый кадр "показывают два раза".
                                        В простых проекторах, типа "Украины", что в школе использовался. В кинотеатрах протяжка немного быстрее, а кадр мелькает аж три раза. Получается 72 вспышки в секунду. Подавляющее большинство людей такую частоту вспышек не воспринимают даже боковым зрением.
                                        В "Украине" при просмотре старых плёнок, снятых с частотой 16 кадров в секунду, тоже можно было поменять протяжку и обтюратор, чтобы делать по три вспышки на кадр и получить 48 вспышек в секунду. Имело смысл, так как 32 вспышки видны как мерцание, даже при небольшом отведении глаз. А некоторые видят их даже глядя прямо.
                                        Цитата Pavia @
                                        Это строб-эффект, в проекторе есть забыл слово.
                                        Эта штука называется обтюратор. Диск с прорезями.
                                          Цитата ЫукпШ @
                                          Очевидно, любое резкое изменения сюжета будет заметно при любой частоте обновления.
                                          Я ж говорю - смещение на 1 пиксель, где тут резкое?
                                          Ставлю 20 мс - рывки, 10-15 - нет их.
                                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                          0 пользователей:


                                          Рейтинг@Mail.ru
                                          [ Script execution time: 0,0678 ]   [ 19 queries used ]   [ Generated: 16.04.24, 14:28 GMT ]