Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемы со скоростью отображения на экране 
:(
    Опции темы
iZZi
Дата 29.9.2005, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 22.5.2003

Репутация: нет
Всего: нет



Здавствуйте!
У меня есть некая программа, выводящая на экран несколько объектов с использованием DirectDraw.

В общем, суть проблемы в том, что иногда скорость (можно сказать - FPS) программы зависит от того, двигается ли мышка в данный момент или нет. Причем, если мышка двигается, то FPS увеличивается (!).

Подробнее о программе.
Программа выполняется fullscreen, поэтому постоянно приходят сообщения WM_PAINT. На каждое такое сообщение приходится один флип (то есть одно отображение вторичного буфера на первичную плоскость, если кто не знает smile ).
Перед запуском fullscreen устанавливается таймер Windows, по которому должны изменяться положения объектов. Но во время выполнения программы ни разу не приходят сообщения WM_TIMER.
Я изменил код и стал просто вызывать каждый раз в главном цикле GetTickCount() и сравнивать с предыдущим значением. Если наступает нужный момент, то выполняется перемещение объектов.
Можно включать и выключать дополнительные функции отображения(математические расчеты; не буду рассказывать, это не суть важно), при этом FPS заметно падает. Если через некоторое время это отображение выключить, то появляется этот глюк: в моменты, когда мышка перемещается, FPS увеличивается примерно на 30-50%.
Через некоторое время глюк исчезает и программа работает независимо от движения мыши.

Вот кусок кода (синтаксис паскалевский, но все должно быть понятно smile ).

repeat
CheckTimer;
if GetMessage(Msg, 0, 0, 0) then
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
until Msg.Msg = WM_QUIT;

Подскажите, может кто-то уже с этим сталкивался?

P.S. Если что, могу скинуть .exe (34K незапакованный)
PM MAIL   Вверх
_hunter
Дата 29.9.2005, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 13
Всего: 98



GetMessage() в случае отсутсвия сообщений просто _замораживается_ используй вместо нее PeekMessage()


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
iZZi
Дата 29.9.2005, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 22.5.2003

Репутация: нет
Всего: нет



_hunter
Цитата
  в случае отсутсвия сообщений

это не мой случай. сообщений хватает всегда smile .

К тому же, я пробовал и PeekMessage. Результат тот же.
Разница между GetMessage() и PeekMessage() в том, что последняя проверяет очередь сообщений, и если там что-то есть, берет оттуда сообщение. Но что важнее, PeekMessage() удаляет из очереди сообщения WM_PAINT, в отличие от GetMessage().

Может быть, стоит сделать раздельными потоки ввода и отображения? Или все, как всегда, проще? smile
PM MAIL   Вверх
Mad
Дата 29.9.2005, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Эксперт
Сообщений: 656
Регистрация: 18.10.2004
Где: Одесса

Репутация: 2
Всего: 19



iZZi
Цитата(iZZi @ 29.9.2005, 19:32)
это не мой случай. сообщений хватает всегда

Цитата(iZZi @ 29.9.2005, 19:32)
К тому же, я пробовал и PeekMessage. Результат тот же


разницы у тебя нет, потому что ты немного неправильно делаеш основной цикл программы
для DirectDraw fullscreen это должно выглядеть примерно так (извени, синтакс с++ как и раздел, но думаю поймеш smile)

Код

while(true)
{
    if (PeekMessage(...))
    {
        TranslateMessage();
        DispatchMessage();
    }
    DrawObjects(); // тут отрисовываеш все что нужно
    if (bNeedQuit) // устанавливаеться в обработчиках
        break;
}



вот так FPS будет соответствовать возможностям твоего железа


Цитата(iZZi @ 29.9.2005, 16:07)
Программа выполняется fullscreen, поэтому постоянно приходят сообщения WM_PAINT

а это не факт smile как раз совсем наоборот, так как редко происходит необходимость в обновлении окна (по мнению системы)


--------------------
user posted image
PM MAIL   Вверх
_hunter
Дата 30.9.2005, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

Репутация: 13
Всего: 98



Цитата(iZZi @ 29.9.2005, 20:32)
_hunter
Цитата
  в случае отсутсвия сообщений

это не мой случай. сообщений хватает всегда smile .

откуда инфа?

Цитата(iZZi @ 29.9.2005, 20:32)

К тому же, я пробовал и PeekMessage. Результат тот же.

видать не так пробовал...

Цитата(iZZi @ 29.9.2005, 20:32)

Разница между GetMessage() и PeekMessage() в том, что последняя проверяет очередь сообщений, и если там что-то есть, берет оттуда сообщение.

а еще разница в том ( что для тебя важнее ), что при отсутсвии оных первая замирает, а вторая продолжает работать

Цитата(iZZi @ 29.9.2005, 20:32)

Но что важнее, PeekMessage() удаляет из очереди сообщения WM_PAINT, в отличие от GetMessage().

а это, как раз ( в данном случае ) и не важно...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
iZZi
Дата 2.10.2005, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 22.5.2003

Репутация: нет
Всего: нет



_hunter
Цитата
откуда инфа?

инфа из лог-файла.
Насчет того, что WM_PAINT не приходят постоянно, я уже сам разобрался. WM_PAINT просто не удаляется из очереди. я использую PeekMessage.

Mad, синтаксис с++ каждый день в хэлпе вижу, так что, наверное, разберусь smile.
попробую твой вариант.
PM MAIL   Вверх
iZZi
Дата 5.10.2005, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 22.5.2003

Репутация: нет
Всего: нет



Товарищи!
Спешу сообщить вам, что проблема решена, причем глюк скрывался совсем не там, где я его искал (и просил вас smile ).
Точнее, не совсем не там. Проблема была в том, что у меня накапливались задержки во время отображения гравитации, и потом прога работала с нормальным (и постоянным) FPS, а при движении мышки просто быстрее обычного изменялись положения объектов.

Всем спасибо!

P.S. Люди, будьте внимательнее, не берите с меня пример smile !

P.P.S. тему можно закрывать, наверное
PM MAIL   Вверх
Romikgy
Дата 6.10.2005, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 7
Всего: 146



Цитата(iZZi @ 5.10.2005, 17:21)
при движении мышки просто быстрее обычного изменялись положения объектов.

Почему???


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
iZZi
Дата 7.10.2005, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 36
Регистрация: 22.5.2003

Репутация: нет
Всего: нет



1 - вариант без глюка:

Код

MainWndProc(...)
{
  ...
//  WM_PAINT не обрабатывается:
//  WM_PAINT:
//  {
//    return Wnd.OnWndPaint(...)
//  }
  ...
}

...

WinMain(...)
{
  ...
  do
  {
    Wnd.OnWndPaint(...);
    Wnd.CheckTimer;
    while GetMessage(...)
    {
      if (PeekMessage(Msg, 0, 0, 0, PM_REMOVE))
      {
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      }
    }
  }
  while (Wnd.bQuit != True)
  ...
}




2 - вариант с этим глюком:

Код

MainWndProc(...)
{
  ...
  WM_PAINT:
  {
    return Wnd.OnWndPaint(...)
  }
  ...
}

...

WinMain(...)
{
  ...
  do
  {
    Wnd.CheckTimer;
    while GetMessage(...)
    {
      if (PeekMessage(Msg, 0, 0, 0, PM_REMOVE))
      {
        TranslateMessage(Msg);
        DispatchMessage(Msg);
      }
    }
  }
  while (Wnd.bQuit != True)
  ...
}


За синтаксис прошу не пинать - сам пишу на delphi, никак на цпп не перейду

Если в варианте с глюком на несколько секунд включить гравитацию, а потом выключить, то при движении мышки двигаться все будет быстрее. Особенно заметно при коротких движениях мышки.

Насчет того, почему быстрее изменялись положения объектов, мои предположения не подтвердились, так что глюк исправлен, но причина не найдена :\

Вот архив с двумя версиями проги (1.121 и 1.122 - cоответственно с глюком и без него)

P.S. я пока не проверял, но может, прога и не запустится на другом компе smile

Присоединённый файл ( Кол-во скачиваний: 0 )
Присоединённый файл  ddrawprog.zip 45,47 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0971 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.