Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Синхронизация по времени


Страницы:   1 2

Juster~ ©   (2003-02-11 17:29:00) 

Здравствуйте! Мне нужно чтобы скорость анимации в OGL программе не зависела от FPS. А то у меня если 1 обьект на экране, то FPS=~90 и все двигается быстро, а если 10 обьектов, то FPS снижается и соответственно снижается скорость. Это все потому, что я пользую обычный цикл прорисовки (как у Jan Horn"a). А нужно чтоб все по атомным часам шло :) Кто знает?


Juster~   (2003-02-19 21:36:00) [1]

Кстати, если обработчики таймера будут выстраиваться в очередь, то флаг canDraw не поможет, т.к. следующая процедура запуститься после окончания предыдущей (и флаг здесь будет всегда true)


pasha676   (2003-02-19 10:19:00) [2]

Можно и так. Просто хотелось бы по максимуму распаралелить это дело. Ведь если у тебя долго рендериться - то не факт что будут обновляться данные (что сработает таймер, ты ведь фактически еще находишься в обработке таймера в этом примере).А по мессаге вроде будут (хотя не факт, не факт что лучше - это больше размышления).
Может быть опять же будут лучше два таймера поставить. Просто как следует поработать над разрулением их с целью предотвращения конфликтов.
Просто вариант с мессагой и таймером (у меня был эвент по приемке данных) я пробывал на практике. Нормально получалось. Считывал примерно 512 байт с порта со скоростью 57000 и обновлял все это дело на экране. Вроде получалось.


Juster~   (2003-02-18 18:37:00) [3]

А обязательно делать через посылку мессаги, можно сделать так?
procedure Update_timer(...); - обработчик события таймера
begin
update_vars; //Обновляем переменные
if canRender then RenderScene; //Попытка рендеринга
end;

procedure RenderScene;
begin
canRender := false;
//отрисовка всего
canRender := true;
end;

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


pasha676   (2003-02-18 18:04:00) [4]

Тут от постановки задачи зависит. Надо так надо. А почему вывод на экран обязательно делать по таймеру?
Может сделать так:

Таймер на 10 мс. Обновляет данные. Если данные изменились по сравнению с последним состоянием, то проверяем флаг "могу рисовать". Если рисовать могу - то посылает мессагу на отрисовку.

Обработчик мессаги. На входе выставляет флаг "не могу рисовать".
После рендинга и вывода на экран "могу рисовать".


Juster~   (2003-02-18 16:53:00) [5]

По-моему, флаг запрета обновления переменных вводить не стоит. Так-ведь скорость игры меняться будет, а мне постоянная нужна, т.е. чтобы, к примеру, обьект прошел 10 едениц за секунду на любом компьютере, независимо от fps


pasha676   (2003-02-18 09:06:00) [6]

Да надо ставить флаги "запрет вывода" и "запрет обновления данных". Чтоб разрулить это дело. Возможно можно использовать не таймеры, а потоки (или таймер и поток(и)). И пользоваться семафорами.

В принципе как то делал так - идет поток обновляет данные с устройств. Если данные обновлены, то посылается мессага на рендеринг и вывод. Все на фиг посыпалось и затормозилось, когда один из датчиков начал постоянно прыгать. Видать очередь образуется. Перешел на таймеры.


cyborg   (2003-02-18 01:51:00) [7]

Поправка, если слишком маленький интервал поставить, всё будет ужасно тормозить :), сейчас проверил, видимо как сказал pasha676 (17.02.03 15:11) там образуется очередь. Используй флаги как я сказал выше.


cyborg   (2003-02-18 01:35:00) [8]

Зависания не будет, пробовал я так рендерить, всё как обычно, хотя что происходит там незнаю. Введи флаг, при начале рендеринга устанавливай его, при окончании сбрасывай. И перед рендерингом смотри, если флаг сброшен, тогда рендерить, если занято, тогда естественно не рендерить :).

Несколько таймеров мешать друг другу не должны.


Juster~   (2003-02-17 19:16:00) [9]

Дело в том, что мне нужно обновление переменных независимое от рендеринга.


pasha676   (2003-02-17 15:11:00) [10]


> Кстати: допустим я установил мультимедиа таймер с интервалом
> 1мс, в on_timer процедуре я рисую сцену, но пока она рендерится,
> подошло время следующего тика таймера. Что произойдет?

Да я тоже не знаю, что произойдет (скорее всего будет очередь, и вполне возможно торможение и зависание, если очередь будет очень медленно рассасываться). На всякий случай в ДельфиХ я вставлял if CanDraw. Тогда ничего страшного не происходило.


> И еще, я хочу сделать так: создать таймер с интервалом 10
> мс для обновления переменных (движение, поворот итд) и другой
> таймер 20 мс для рендеринга сцены. А они не будут мешать
> друг другу (задерживать или глючить)?


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


Juster~   (2003-02-17 12:27:00) [11]

То что надо! Хвала cyborg"у!
Кстати: допустим я установил мультимедиа таймер с интервалом 1мс, в on_timer процедуре я рисую сцену, но пока она рендерится, подошло время следующего тика таймера. Что произойдет? События выстроются в очередь или будут игнорироваться пока не дорендериться текущая сцена?
И еще, я хочу сделать так: создать таймер с интервалом 10 мс для обновления переменных (движение, поворот итд) и другой таймер 20 мс для рендеринга сцены. А они не будут мешать друг другу (задерживать или глючить)?


Anatoly Podgoretsky   (2003-02-17 10:15:00) [12]

SetTimer это обычный таймер, минимальный такт определеяется ОС - это или 10 мс или 55 мс, кроме того у него очень низкий приоритет.
Более высокую скорость обеспечивает мультимедиа таймер - у него такт около 1 мс, функция называется по другому timeSetEvent. Пример есть выше.


pasha676   (2003-02-17 09:57:00) [13]

2Alek Aaz
Сделать так можно. Даже наивысший приоритет наверное не нужен. Наоборот он на себя все время сожрет фиг че нарисуеш. Но таймер наверное проще.

Кстати почему SetTimer(hWnd,TIMER_ID,TIMER_RATE,nil);
Делает только 50 мс. По идеи точность должна быть гораздо выше. Даже используя таймера из DelphiX и GLScene простые сцены показывають кучу ФПС. В десятки раз больше. 1 мс конечно не добьешся, но на 3-5 я думаю можно расчитывать.
Кстати почему последний параметр nil. По идеи последний параметр должен быть ссылкой (адресом) функции, которая срабатывает на таймер.

Вообщем данная тематика меня заинтересовала. Свояю таймер этим способом. Посмотрю как он по скорости.


Alek Aaz   (2003-02-17 04:18:00) [14]

А можно сделать так? Создать поток. Ему присвоить наивысший приоритет. В потоке высчитывать время наступления события и генерить событие.
ИМХО думаю должно сработать.


cyborg   (2003-02-16 20:23:00) [15]

Подключи модуль MMSystem, или используй эти описания функций:

{$EXTERNALSYM timeKillEvent}
function timeKillEvent(uTimerID: UINT): UINT; stdcall; external "winmm.dll" name "timeKillEvent";
{$EXTERNALSYM timeSetEvent}
function timeSetEvent(uDelay, uResolution: UINT;lpFunction: TFNTimeCallBack; dwUser: DWORD; uFlags: UINT): UINT; stdcall; external "winmm.dll" name "timeSetEvent";


//Установка таймера:

VAR
MM_Timer : Cardinal=0;

//Обработчик события таймера:
procedure On_Timer(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD); stdcall;
Begin
End;

//Установка таймера:
MM_Timer:=TimeSetEvent(10, 0, On_Timer, 0, 1);
//Удаление таймера:
TimeKillEvent(MM_Timer);


TimeSetEvent:
1 параметр - интервал в миллисекундах
3 параметр - процедура обработки события
5 параметр - 0 - один раз вызвать событие, 1 - повторять постоянно


Juster~   (2003-02-16 08:07:00) [16]

С тиками я тоже делал, только по другому немного. Но из-за этого глюки возникают в движении и повороте игрока (он поворачивается с пом. мыши)


Darthman   (2003-02-16 03:22:00) [17]

Ладно, а тики процессора?


Juster~   (2003-02-14 21:17:00) [18]

-> Anatoly Podgoretsky: А ладно, не надо, спасибо...
-> Darthman: про это я знаю. Это ф-ция в лучшем случае выдает 50 милли сек. но никак не меньше, а это ~20 fps. Поэтому не годиться...


Anatoly Podgoretsky   (2003-02-14 19:17:00) [19]

Juster~ (14.02.03 14:44)
Все 200 иб?


Darthman   (2003-02-14 18:49:00) [20]

const
TIMER_RATE = 200;
TIMER_ID = 1;

SetTimer(hWnd,TIMER_ID,TIMER_RATE,nil);

Где Rate=мсек


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо