Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Игры";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];

Вниз

Опять fps...   Найти похожие ветки 

 
Zak3D[@Tm] ©   (2004-01-15 22:46) [0]

Привет всем, я уже создавал ветку про создание счётчика fps, но это вызвало только новые вопросы. Здесь я предлагаю написать(всем кто знает как это делается) все  известные способы создания счётчиков(ну конечно не один человек все, а кто сколько знает и сколько захочет писать) и если можно объяснит, почему именно этот счётчик fps, а не другой.
Всем спасибо.
ЗЫ:пожалуйста не обходите эту тему стороной, ведь таких как я(новичков) много, и способы подсчёта fps для нас играют не маловажную роль, а один раз создав такую тему и "заполнив" её, такие как я больше не будут мучить вас детскими вопросами, ещё раз спасибо.


 
Guest   (2004-01-16 03:03) [1]

Самый простой счётчик
В функции прорисовки кадра пишешь:
Count:=Count+1;
Ставишь таймер на 1000ms и в его обработчике:
Canvas.TextOut(10,10,IntToStr(Count));
count:=0;


 
Zak3D[@Tm] ©   (2004-01-16 09:31) [2]

Спасибо Guest, уже проверил, работает. А что больше никто не знает как fps высчитывать?


 
NailMan ©   (2004-01-16 10:21) [3]

Guest
Canvas.TextOut(10,10,IntToStr(Count));
Ага и на следующем обновлении кадра твоя строка сотрется изображением.

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

Собсно в той ветке я как раз такой обработчик о описал.

Zak3D[@Tm]©
Вообще-то типов счетчиков может быть всего один. Суть его собсно и есть отсчет вывов Scene.Render(условно) в какой-то промежуток времени.

Я выбрал 1000мс только из-за соображений скорости - все таки создание строки из integer довольно долгая операция и если она будет вызываться(в обработчике) более часто - это несколько снизит производительность. Принципиально можно обрабатыватьсоздавать строку с FPS) 2 или 3 раза в сек и вычислять моментальный средний ФПС(т.е. дробный). Но это лишь только понты. Обычного счетчика ФПС, который обновляется 1 раз в сек вполне достаточно для оценки общей скорости приложения.

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


 
Zak3D[@Tm] ©   (2004-01-16 11:07) [4]

Я помню, NailMan ты писал так.

-NailMan    
///////////////////////////////////////////////
А я не парюсь и считаю фактическое число ФПС:

var Frames, minfps, maxfps:Integer;
        avrgfps:Single

Создается обработчик таймера, который будет нам обрабатывать счетчик фпс.

Procedure TimerFPSHandler;
begin
FPSString:=inttostr(frames);        //Создаем строчку для рисования на экране
if frames<minfps then minfps:=frames;  //определяем минимальный фпс
if frames> maxfps then maxfps:=frames; //определяем максимальный фпс
avrgfps:=(avrgfps + frames);  //считаем сумму для среднего
inc(secs); //прибавляем секунды прошедшие с начала отсета времени
frames:=0; //зануляем счетчик
end;

Далее при создании сцены или приложения(но тогда надо обнулить перед созданием сцены avrgfps,frames,maxfps,minfps(=maxint)) мы создаем виндовый таймер(при выходе убиваем).

Procedure  SetTimers(onn:boolean);
begin
if onn then
begin
  SetTimer(Handle,1,1000,@TimerFPSHandler);
end else
begin
 KillTimer(Handle,1);
end;
end;

В методе сцены Render, в самом конце мы делаем Inc(Frames);

На выходе из приложния делаем avrgfps:=avrgfps / Secs; и получаем средний фпс за все время работы приложения.

Таким образом считаются фактическое число кадров которое было на прошедшей секунде. Надежно и просто.
////////////////////////////////////////

Но и здесь у меня есть пара вопросов:
1 я так понял, здесь мы создаём свои процедуры, но не понял куда их так сказать подключать, в какие обработчики добавлять?
2 FPSString-это что? При компиляции выделяет как ошибку или его в глобальные пременные добавить FPSString:String, надо?
Вобщем-то больше вопросов нет.


 
Guest   (2004-01-16 14:33) [5]

2NailMan
Ага и на следующем обновлении кадра твоя строка сотрется изображением.
Я рисую прямо на канвасе, и всё изображение не перерисовываю. Перерисовываю только те участки где были изменения, так что такой проблемы не было!

2Zak3D[@Tm]
1 я так понял, здесь мы создаём свои процедуры, но не понял куда их так сказать подключать, в какие обработчики добавлять?
Мы их не создаём, а вызываем! Это типа мультимедийный таймер компа, который более точен и позволяет задавать любые интервалы времени от 1ms, в отличии от стандартного.
NailMan поделись, как ты его вызываешь(я делаю по другому и у меня всё более громоздко получается)

ЗЫ 2NailMan
Кстати как лучше - перерисовывать всю сцену, или как я, только маленькие участки?


 
NailMan ©   (2004-01-16 16:03) [6]

Zak3D[@Tm] ©
Я их нигде не вызываю, так как:
- в начале приложения мы вызываем вышеприведенну процедуру SetTimers(true) и в ней наш обработчик TimerFPSHandler(нельзя использовать метод класса для этого обработчика) устанавливается в систему(в Windows) и начинает обрабатываться автономно от нас, т.е. процедура сама вызывается раз в секунду и изменяет параметры.
- в конце мы убиваем наш таймер вызвав SetTimers(false)

2 FPSString-это что? При компиляции выделяет как ошибку или его в глобальные пременные добавить FPSString:String, надо?
Да, просто глобальная переменная типа строки. Главное назначение - избавиться лишних трат процессорного времени при рендере сцены. Типа от вот такого(пример): DFont.DrawText(inttostr(Frames),ля-ля-ля).
Так как в этом случае будет каждый кадр вызываться совершено лишняя и медленная inttostr - это будет плохо.

2NailMan
Я рисую прямо на канвасе, и всё изображение не перерисовываю. Перерисовываю только те участки где были изменения, так что такой проблемы не было!
...
Кстати как лучше - перерисовывать всю сцену, или как я, только маленькие участки?

А как ты анализируешь отличия? Если даблбуфферинг на форме включен, то имеет смысл просто перерисовывать весь экран каждый фрейм и не заморачиваться.

Мы их не создаём, а вызываем! Это типа мультимедийный таймер компа, который более точен и позволяет задавать любые интервалы времени от 1ms, в отличии от стандартного.
Вот как раз здесь и стандартный таймер юзается(виндой), а не мультимедийный. Он с менее ~20мс интервалом вообще срабатывать не будет.


 
Guest   (2004-01-16 16:43) [7]

2NailMan
А как ты анализируешь отличия?
Я брал кусочек, сохранял во временный bitmap, выводил в это место другой bitmap, потом загружал временный bitmap, сдвигал его, сохранял, сдвигал и выводил другой bitmap и тд
Вобщем это было тупо!

Если даблбуфферинг на форме включен, то имеет смысл просто перерисовывать весь экран каждый фрейм и не заморачиваться.
Я и в правду ступил, думал может быстрее будет кусочки перерисовывать, но из-за этого код стал совсем непонятный, буду переделывать!

Вот как раз здесь и стандартный таймер юзается(виндой)
Что-то я спутал. Но пользуюсь мультимедийным!


 
Zak3D[@Tm] ©   (2004-01-16 17:00) [8]

Присвоил FPSString:string  и Secs:integer, всё равно не компилируется, теперь делает так- в SetTimer(Handle,1,1000,@TimerFPSHandler); выделяет Handle? Что за ерунда? Так хочется виндовый таймер поюзать, а не как не получается ;(


 
NailMan ©   (2004-01-16 17:32) [9]

Вот что есть в Windows Help по этой функции
UINT SetTimer(

   HWND hWnd, // handle of window for timer messages
   UINT nIDEvent, // timer identifier
   UINT uElapse, // time-out value
   TIMERPROC lpTimerFunc  // address of timer procedure
  );


Тоесть словами Дельфи:
Function SetTimer(hWnd:HWND,nIDEvent:integer,uElapse:integer;lpTimerFunc:Pointer):integer;

Пихаем ему следующее
hWnd - хэндл окна нашей формы или просто хэндл окна(если окно создавали сами ручками)
nIDEvent - номер таймера(типа он у нас первый и единственный
uElapse - время срабатывания(период ожидания)
lpTimerFunc - нашего обработчика-процедуры

Если результат SetTimer=0 то таймер не создался(уже существует?), если нуль то все пучком.

Грубо говоря она нашему окну(форме) прилинковывает таймер. Это кстате более низкий вариант стандартного компонента TTimer, который является надстройкой над SetTimer/KillTimer.


 
pavel_k   (2004-01-17 14:59) [10]

>SetTimer(Handle,1,1000,@TimerFPSHandler);
Если SetTimer не метод класса, то видимо надо написать Form1.Handle вместо Handle.


 
Zak3D[@Tm] ©   (2004-01-17 16:26) [11]

Как таким способом выводить фпс на например форму?


 
NailMan ©   (2004-01-19 09:34) [12]

Ну дык проще простого - вместо FPSString используешь Caption своей формы.



Страницы: 1 вся ветка

Форум: "Игры";
Текущий архив: 2004.05.23;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.036 c
1-1083741016
atmospheric
2004-05-05 11:10
2004.05.23
Application.Run ?


14-1083670900
TUser
2004-05-04 15:41
2004.05.23
Паскаль жив!


7-1081946450
Shurik_212
2004-04-14 16:40
2004.05.23
Событие появления файла на диске


3-1083064833
}|{yk
2004-04-27 15:20
2004.05.23
Функции...Оракл


14-1083515369
ЧупаЧупс
2004-05-02 20:29
2004.05.23
Треугольник и центр





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский