Пятница, 29 Марта 2024, 02:43

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » C/C++ » Ошибка в ограничителе кадров
Ошибка в ограничителе кадров
Xe[N]oДата: Пятница, 04 Мая 2012, 10:09 | Сообщение # 1
частый гость
Сейчас нет на сайте
Всем привет. Тут у меня проблема... Вроде как формулу просчитал, должно в идеале считать сколько миллисекунд прошло. Но при этом, Реддинга вообще не происходит не разу. Будто, в переменной, в которой хранится количество прошедших миллисекунд, вообще не меняется значение.

В первый раз, миллисекунды замеряю в после создания окна.

Code
GetSystemTime(&CTime);
   int lDrawTimer = CTime.wMilliseconds;

   if(lDrawTimer > StartUpTime)
   {
   DrawTimer=(lDrawTimer-StartUpTime)+DrawTimer;
   StartUpTime=lDrawTimer;
   }
     
   if(lDrawTimer < StartUpTime)
   {
   DrawTimer=1000-StartUpTime+lDrawTimer+DrawTimer;
   StartUpTime=lDrawTimer;
   }

   if(DrawTimer >= 40)
   {
   draw();
   SwapBuffers(dc);
   DrawTimer=0;
   }


Подскажите, где я ошибся. И скажите, данным методом брать время для ограничителя кадров, это вообще нормально? smile

Добавлено (04.05.2012, 10:09)
---------------------------------------------
Не хочу показаться не вежливым, но парни, у меня разработка стоит...

Сообщение отредактировал Xe[N]o - Четверг, 03 Мая 2012, 10:28
nilremДата: Пятница, 04 Мая 2012, 13:13 | Сообщение # 2
Просветленный разум
Сейчас нет на сайте
Значение в CTime.wMilliseconds обнуляется каждую секунду.
Используй timeGetTime, которая возвращает значение в милисекундах с момента старта виндовз.

Для ограничения кадров лучше всего усыплять программу функцией sleep(). Зачем тебе просчитывать что-то, если оно при этом не отображается.
Как я понял:

Code
if(DrawTimer >= 40)

здесь 40 - константа, время в милисекундах, по истечении которого рисуется кадр.
лучше уж вызвать sleep(40 - время, потраченное на рисование предыдущего кадра).


Windmill 2

WindMill 2D Game Engine
Xe[N]oДата: Пятница, 04 Мая 2012, 16:06 | Сообщение # 3
частый гость
Сейчас нет на сайте
Quote
Значение в CTime.wMilliseconds обнуляется каждую секунду.

Для этого и была написано второе условие. В случае, если ново-взятое время меньше чем было взято в прошлый раз, то высчитываем по другому, сколько же прошло времени, с учетом уже прошедшего обнуления.)
Quote
Для ограничения кадров лучше всего усыплять программу функцией sleep(). Зачем тебе просчитывать что-то, если оно при этом не отображается.

Хочу тут уточнить. Вроде как, sleep останавливает данный поток, и передает работу другому, так? Просто я пока пишу одно поточную программу, но мало ли, в будущем пригодится.)

Добавлено (04.05.2012, 16:06)
---------------------------------------------
Я сглупил. Мне этот вариант 100% не подходит. Все дело в том, что пока процесс "спит", он перестает отлавливать системные сообщения. Более того, я не могу в это время делать расчеты. Если бы это было бы, простое C++ видео, то этот вариант более-менее прокатил бы. Но с учетом того, что мне придется просчитывать абсолютно все, за это время, то мои FPS будут считаться как 25/c, но на самом деле, будет меньше (ибо после того как 40мс проходят, еще идут вычисления).

nilremДата: Пятница, 04 Мая 2012, 18:24 | Сообщение # 4
Просветленный разум
Сейчас нет на сайте
Quote (Xe|N|o)
Более того, я не могу в это время делать расчеты.

А что ты собираешься в это время считать?


Windmill 2

WindMill 2D Game Engine
Xe[N]oДата: Воскресенье, 06 Мая 2012, 21:55 | Сообщение # 5
частый гость
Сейчас нет на сайте
Как минимум ловить системные сообщения, просчитывать нажатия клавиш, высчитывать AI.

Добавлено (06.05.2012, 21:55)
---------------------------------------------
Народ? Неужели, никто не знает ответа? Бред.

KpoJIukДата: Воскресенье, 06 Мая 2012, 22:39 | Сообщение # 6
In C++ We Trust
Сейчас нет на сайте
Xe[N]o, Алгоритм должен быть примерно таким:
1. Смотришь текущее время.
2. Выполняешь свой код.
3. Ждешь (delay()\sleep() или что-то более точное), пока разница между текущим временем и временем из 1. не будет >= нужному тебе для одного кадра.
4. Начинаешь сначала.
Или как вариант:
1. Смотришь текущее время.
2. Если разница между текущим временем и временем из 1. <= нужному, то выполняешь свой код один раз. если >, то идешь в 1.
Вообще, если тебе просто нужна ограничивалка fps, то почему бы не посмотреть, как это делается в грамотных движках с открытым кодом, вроде HGE или Sapphire?
з.ы.: С алгоритмами мог немного напутать. Для замерения времени погугли высокоточные таймеры или хотя бы просто работу со временем в си.
DemeronДата: Воскресенье, 06 Мая 2012, 23:25 | Сообщение # 7
User created in C++
Сейчас нет на сайте
Code

float dt_need; // какая должна быть задержка (1/количество кадров)
float dt_now; // текущая задержка (время между кадрами)

...

if (dt_now<dt_need) sleep(dt_need-dt_now);

Xe[N]oДата: Понедельник, 07 Мая 2012, 08:00 | Сообщение # 8
частый гость
Сейчас нет на сайте
Quote
Вообще, если тебе просто нужна ограничивалка fps, то почему бы не посмотреть, как это делается в грамотных движках с открытым кодом, вроде HGE или Sapphire?

Своими руками, всегда приятней. Даже если с помощью.)

На самом деле, 1 алгоритм достаточно хорош, и я над ним подумаю. Но мне все равно хочется знать, почему мой способ замера времени не работает. Мне же в любом случаи время замерять надо будет.
luissДата: Понедельник, 07 Мая 2012, 12:56 | Сообщение # 9
был не раз
Сейчас нет на сайте
del
Xe[N]oДата: Вторник, 08 Мая 2012, 10:29 | Сообщение # 10
частый гость
Сейчас нет на сайте
Мне кажется, или мне отвечают только тогда, когда я сам снова этого прошу?)
Народ, я уже 4 дня стою на месте, а все в основном из-за того, что все дают мне советы, говорят о других алгоритмах. Но вот никто еще даже не задел тему, по поводу того, почему у мой замер времени не работает.
Nilrem посоветовал мне использовать timeGetTime, ибо в моем методе, количество миллисекунд будет сбрасываться каждую секунду (что кстати, крайне логично). Но и этот способ, рано или поздно тоже сбросит значение переменной до нуля, и если ошибка в моей формуле, где-то спрятана, то я в конечном итоге получу тоже самое.
Народ, мне серьезно нужна ваша помощь, только не говорите, что тут все программисты почти не знают языка, раз на простой вопрос, ответить не могу. Я знаю что здесь достаточно крутые играделы, так почему никто не может ответить?
BASSДата: Вторник, 08 Мая 2012, 10:36 | Сообщение # 11
independent developer
Сейчас нет на сайте
Xe[N]o, попробуйте записывать значение нужной переменной в лог-файл. Тогда Вы точно будете знать, есть ошибка или нет.

Будь подобен лезвию бритвы: ярким, блестящим, отточенным, но холодным и не показывающим своего истинного цвета.
TikaraДата: Вторник, 08 Мая 2012, 12:17 | Сообщение # 12
частый гость
Сейчас нет на сайте
Давайте попробуем разобраться

Code
    
       // Эту часть выполните перед запуском основного цикла //
       int DrawTimer;
       int StartUpTime = timeGetTime();
      //////////////////////////////////

      if((DrawTimer=timeGetTime() - StartUpTime) >= 40)    
      {    
      draw();    
      SwapBuffers(dc);    
      StartUpTime = timeGetTime();    
      }    


Хотелось бы узнать, какое значение имеет DrawTimer до первого запуска цикла?

Дописал вашу программу, если ошибка останется или алгоритм вас не устроит, хотелось бы услышать причину и в чем толк вашего алгоритма?


Сообщение отредактировал Tikara - Вторник, 08 Мая 2012, 12:40
Xe[N]oДата: Вторник, 08 Мая 2012, 13:12 | Сообщение # 13
частый гость
Сейчас нет на сайте
Quote
Xe[N]o, попробуйте записывать значение нужной переменной в лог-файл. Тогда Вы точно будете знать, есть ошибка или нет.

А вот это уже идея. Я пробовал выводить значение в консоль, выходил краш (из-за чего я и подумал, что ошибка не в формуле), а вот с логом можно попробовать.

Quote
Хотелось бы узнать, какое значение имеет DrawTimer до первого запуска цикла?

Нулю.

Quote
Дописал вашу программу, если ошибка останется или алгоритм вас не устроит, хотелось бы услышать причину и в чем толк вашего алгоритма?

Да, это конечно круто, но переменная со временем, сбрасывается раз в 49 дней, если не ошибаюсь. Приеду с работы, попробую проверить со своей формулой.
TikaraДата: Вторник, 08 Мая 2012, 13:30 | Сообщение # 14
частый гость
Сейчас нет на сайте
Quote (Xe|N|o)
Да, это конечно круто, но переменная со временем, сбрасывается раз в 49 дней, если не ошибаюсь.


Тогда такой вопрос. Вы рассчитываете на то, что найдется пользователь, запустивший вашу игру с компьютера, который работал 49 дней и хотите это предотвратить? Лично мне кажется, что такой вариант маловероятен.
Code

           // Эту часть выполните перед запуском основного цикла //       
             int DrawTimer;  
             int TimeNow;      
             int StartUpTime = timeGetTime();       
            //////////////////////////////////       

void _draw(int temp){
        if((DrawTimer=temp) >= 40)          
        {          
            draw();          
            SwapBuffers(dc);          
            StartUpTime = TimeNow;          
        }
}

           TimeNow = timeGetTime();    

           if(TimeNow < StartUpTime)    

             _draw(4294967296 - StartUpTime + TimeNow);
    
           else

            _draw(TimeNow - StartUpTime);    



Но, если вы настаиваете, осмелюсь предложить такой вариант.

Код подправил - заметил ошибочку.


Сообщение отредактировал Tikara - Вторник, 08 Мая 2012, 14:24
Xe[N]oДата: Вторник, 08 Мая 2012, 14:18 | Сообщение # 15
частый гость
Сейчас нет на сайте
Quote
Тогда такой вопрос. Вы рассчитываете на то, что найдется пользователь, запустивший вашу игру с компьютера, который работал 49 дней и хотите это предотвратить? Лично мне кажется, что такой вариант маловероятен.

Нужно предотвращать все возможные ошибки.)
Quote
Но, если вы настаиваете, осмелюсь предложить такой вариант.

Почти не отличается от моей формулы.)
Приеду с работы, попробую.
TikaraДата: Вторник, 08 Мая 2012, 14:55 | Сообщение # 16
частый гость
Сейчас нет на сайте
Не знаю кто вам посоветовал использовать CTime.wMilliseconds. Посидев и подумав над реализацией через ctime, в голове пробегали ситуации с ошибками, которых, как мне кажется, чтобы отловить потребуются костыли.
Форум игроделов » Программирование » C/C++ » Ошибка в ограничителе кадров
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг