Часовой пояс: UTC + 3 часа




Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 17 
  Пред. тема | След. тема 
В случае проблем с отображением форума, отключите блокировщик рекламы
Автор Сообщение
 

Заблокирован
Заблокирован
Статус: Не в сети
Регистрация: 07.07.2012
Необходимо сделать задержку на полмилисекунды. Не знаю как, а у функция Sleep(int) минимальная задержка 1мс :( Кто-нибудь знает решение?



Партнер
 

Member
Статус: Не в сети
Регистрация: 16.05.2007
Откуда: Швеция
VIIX
Тебе и со Sleep(1) никто не гарантирует задержку ровно в 1 миллисекунду. Может быть 1, а может быть и 15 миллисекунд. Windows - не система реального времени. Единственное, что может (может, но не обязано) сработать - запустить в цикле QueryPerformanceCounter() и завершить его, когда он отсчитает 0.5 миллисекунды.


 

Заблокирован
Заблокирован
Статус: Не в сети
Регистрация: 07.07.2012
Мне не нужна гарантированная 1 мс или 0.5мс. Мне нужно как-то реализовать задержку. Сейчас сделано Sleep(1) и это долго. Что-то типа Sleep(0.25) или Sleep(0.5) меня устроило бы, но увы ... 1 мс у этого метода "минимум" :(


 

Member
Статус: Не в сети
Регистрация: 16.05.2007
Откуда: Швеция
VIIX
Ну так и используй цикл
Код:
void SleepDouble(double ms)
{
  LARGE_INTEGER f, t1, t2;
  QueryPerformanceFrequency(&f);
  QueryPerformanceCounter(&t1);
  double delta = ms * 0.001 * f.QuadPart;
  do {
    QueryPerformanceCounter(&t2);
  } while (t2.QuadPart - t1.QuadPart < delta);
}

P.S. Код не проверял, но должен работать.


 

Заблокирован
Заблокирован
Статус: Не в сети
Регистрация: 07.07.2012
SilverDaemon Спасибо, попробую


 

Заблокирован
Заблокирован
Статус: Не в сети
Регистрация: 07.07.2012
SilverDaemon писал(а):
void SleepDouble(double ms)
{
  LARGE_INTEGER f, t1, t2;
  QueryPerformanceFrequency(&f);
  QueryPerformanceCounter(&t1);
  double delta = ms * 0.001 * f.QuadPart;
  do {
    QueryPerformanceCounter(&t2);
  } while (t2.QuadPart - t1.QuadPart < delta);
}

К сожалению, не подходит - данай функция очень сильно грузит проц :(


 

Member
Статус: Не в сети
Регистрация: 16.05.2007
Откуда: Швеция
VIIX
Ну тогда твою задачу никак не решить, в Windows API нет такого Sleep. Может расскажешь подробней, почему нужно именно 0.5 мс? Sleep(1) обычно дает задержку в 10-15 мс, если не увеличивать точность таймера вызовом timeBeginPeriod(1).


 

Заблокирован
Заблокирован
Статус: Не в сети
Регистрация: 07.07.2012
SilverDaemon На форме надо плавно передвинуть объект интервалом +1px c задержкой на каждый пиксель. Получается плавно, но надо чуть быстрее.


 

Member
Статус: Не в сети
Регистрация: 12.09.2010
Откуда: Калининград
Код:
LARGE_INTEGER freq, start, end;
::QueryPerformanceFrequency( &freq );
double mult = 1.0 / freq.QuadPart;
::QueryPerformanceCounter( &start );

do
{
    for( unsigned index = 0; index < 10; ++index )
    {
        ::SwitchToThread();
    }
    ::QueryPerformanceCounter( &end );
} while( (static_cast < double >(end.QuadPart - start.QuadPart) * mult) < 0.0005 );

Попробуйте так. Ну и попробуйте в for поменять конечное значение или вообще цикл выкиньте. Можете попробовать заменить SwitchToThread() на Sleep( 0 ) или вообще их вместе поюзать
Ещё вариант - попробуйте для вашей задачи поюзать вещественные числа и передвигать не на целое число, а на дробное. Возможно будет немного дёргаться - уже не помню. Сам когда-то делал такие штуки

Добавлено спустя 33 минуты 25 секунд:
Сейчас попробовал, на моём ПК
Sleep( 1 ) - в среднем 0.000950 секунд
Sleep( 0 ) - 0.000001
SwitchToThread() - 0.000004


 

Advanced member
Статус: Не в сети
Регистрация: 10.04.2003
Откуда: Москва
Industrialice, я специально измерял стабильность команды Sleep,1.
При уровне приоритета 'realtime' время выдерживается точно, именно 1 мс. Соседние отсчеты (0.99мс и 1.01) имеют интенсивность 20% и вызваны округлением измерения. Еще есть по ~1% отсчетов на 0.98мс и 1.02мс. Других отсчетов (в интервале 0.01мс - 10мс) нет. Время сбора статистики 5 минут.

denisr, не хами.


 

Member
Статус: Не в сети
Регистрация: 12.09.2010
Откуда: Калининград
serj Я потом тоже протестирую, и с разными приоритетами, данные тесты были при запуске "как есть прямо из Вижуал Студио" и с кучей параллельно выполняющихся программ - так что результат там заметно плавает, привёл средние значения чисто для прикидочной информации насколько выкручивать счётчик цикла, не судите слишком строго


 

Junior
Статус: Не в сети
Регистрация: 07.03.2012
Частота обновления экрана - 60-100Hz.
Задержка между обновлениями = 1000/60=16ms. Sleep(1) именно поэтому равен Sleep(16), потому что достаточно обновлять экран только каждые 16ms. Обновление каждые 1ms или тем более 0.5ms просто отбросит 16 изменений картинки, зря сожрёт процессорное время и в итоге покажется только одно изменение картинки.


 

Advanced member
Статус: Не в сети
Регистрация: 10.04.2003
Откуда: Москва
denisr, остается проблема с получением события VSync (ибо как_раз_по_нему и надо обрабатывать оконную процедуру перерисовки изображения).


 

Junior
Статус: Не в сети
Регистрация: 02.08.2012
Получение события VSync :roll:
На практике "плавно" в 0.5мс задержки это не реальное значение.
Анимация передвиганием кнопки в цикле с задержкой это большооой костыль.
Скажем так попытка рубания дубов микроскопом.
Дело не в задержке, а в невозможности "плавно двигать" окна самой графической подсистемой.
А в форточках кнопка это окно... :haha:

Вам нужен пример анимации посредством GDI.
Другое дело что при событиях onClick (или что там у вас)
нужно учитывать текущее положение объекта на холсте, и размер холста.
Но это будет работать отлично.

http://www.daniweb.com/software-development/cpp/code/241875/fast-animation-with-the-windows-gdi

Добавлено спустя 6 минут 46 секунд:
Ну или как вариант реализовать двойную буферизацию контекста дисплея для объекта и его контейнера который будет работать с хуками на перерисовку...


 

Advanced member
Статус: Не в сети
Регистрация: 10.04.2003
Откуда: Москва
mopc.sladkoff, ага WM_***. )) Да ну, ты всё понял. )
Если размер холста большой и FPS случайно окажется близким или кратным частоте кадров, дефекты изображения 'обеспечены'.


 

Member
Статус: Не в сети
Регистрация: 20.03.2009
Откуда: Санкт-Петербург
VIIX Если использовать Qt, то есть функция QThread::msleep(unsigned long msecs).

_________________
Задачи бывают простыми и очень простыми...


 

Member
Статус: Не в сети
Регистрация: 16.05.2007
Откуда: Швеция
VIIX писал(а):
SilverDaemon На форме надо плавно передвинуть объект интервалом +1px c задержкой на каждый пиксель. Получается плавно, но надо чуть быстрее.

Вот с этого и надо было начинать. Не с той стороны задачу решаешь. Если у тебя обычное окно windows-приложения, то нужно как минимум включить двойную буферизацию и обновлять картинку чаще, чем 60 раз в секунду. Если используешь DirectX или OpenGL для отрисовки объекта, просто включи в них VSync.

P.S. Но идельно плавное перемещение будет только если частота изменения картинки будет точно равна частоте развертки монитора. Если будешь обновлять чаще, то между соседними кадрами, отображаемыми монитором, будет иногда попадать разное число обновлений картинки (будет периодическое подергивание). Если будешь обновлять реже, то движение будет не на каждом кадре монитора.


Показать сообщения за:  Поле сортировки  
Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 17 
-

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти:  

Лаборатория














Новости

Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB | Kolobok smiles © Aiwan