Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.05.23;
Скачать: CL | DM;

Вниз

Опять 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.027 c
4-1080997615
Swimmer
2004-04-03 17:06
2004.05.23
Загрузка bmp-ресурса в массив


3-1083132235
Volodya_
2004-04-28 10:03
2004.05.23
Синхронизация данных


1-1084258074
Masatek
2004-05-11 10:47
2004.05.23
Работа с текстовыми блоками...


3-1083040503
AntonVS
2004-04-27 08:35
2004.05.23
кирилица в FB


1-1084075854
glGLU
2004-05-09 08:10
2004.05.23
ListBox &amp; Message