Форум: "Игры";
Текущий архив: 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
Время: 3.537 c