С# .Net есть ли способ узнать, сколько кадров монитора было показано, или показать что-то на экране для заданного количества кадров?

Мне нужно что-то показать на экране за точный, очень маленький интервал времени. При работе с мониторами с фиксированной (и относительно медленной для этой задачи) частотой обновления это будет ограничивающим фактором — и мне придется разрешить пользователю устанавливать время отображения в количестве «кадров» (= 16, (6) мс для мониторов с частотой 60 Гц).

Первоначально я рассматривал просто использование точного таймера (на основе класса секундомера), но проблема в том, что нет способа (известного мне) узнать, сколько кадров было фактически показано, поэтому, если я покажу что-то, скажем, 21 мс, у меня есть ~ 25% вероятность того, что он будет отображаться в течение 2 кадров (33,3 мс) и ~ 75% вероятность того, что он будет показан в течение 1 кадра (16,6 мс), в зависимости от того, как интервал обновления 16,6 мс совпадает с моим Интервал 21 мс.

Я знаю, что это, вероятно, можно сделать с помощью Vsync в DirectX/opengl/etc, но я бы хотел, если возможно, остаться с простыми формами Windows. Итак, есть ли способ либо узнать, сколько кадров было показано с некоторого времени, либо перехватить событие отрисовки нового кадра на мониторе, либо вручную заказать перерисовку кадра или что-то в этом роде?


person Istrebitel    schedule 28.10.2013    source источник


Ответы (1)


Не совсем понятно, что вы подразумеваете под "рамкой монитора".

Если вы хотите измерить частоту обновления монитора, то измерять особо нечего. Это фиксированное число, которое полностью зависит от модели монитора и настроек дисплея. Вы можете найти его или использовать вызов win API, чтобы получить его программно: http://msdn.microsoft.com/en-us/library/dd162611%28v=VS.85%29.aspx. Ваше программное обеспечение не влияет на частоту обновления.

Если вы хотите измерить fps, вам понадобится таймер (например, StopWatch) и количество кадров. Вы можете получить последнее, увеличивая некоторую переменную каждый раз, когда вы обновляете экран. OnPaint в вашей форме, вероятно, является одним из мест, где вы можете это сделать. Fps не зависит от монитора (если вы не включите VSync).

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

person Nikita B    schedule 28.10.2013
comment
Я хочу точно знать, сколько кадров монитора было показано. Представьте, что при t=0 мс вы рисуете X на своей форме, затем используете Thead.Spin() до тех пор, пока не пройдет 20 мс (на вашем секундомере), и при t=20 мс вы очистите свою форму. Теперь по факту пользователь вашей программы (если у него типичный 60Гц дисплей) не видел Х 20мс. Он видел его либо 16,(6) мс, либо 33,(3) мс. Поскольку дисплей обновляется независимо от вашего кода — вашего OnPaint или w/e. Мне нужно знать, как долго ПОЛЬЗОВАТЕЛЬ видел изображение. - person Istrebitel; 31.10.2013