Пишу програмку для проверки инерциооности зрения, т.е. мне необходимо узнать при какой частоте кадров (fps)
человек перестает видеть различия между двумя картинками (в моем случае это черный и белый квадрат).
Я столкнулся с такой проблемой, я не смог плавно увеличивать частоту выводимых кадров. Если выводить от 1-16, то более менее плавно,
а вот от 16 изменения происходят скачками 16, 21, 32, 64, 83, 96.
Проект пишу на C#, но если будут варианты решения на др. языке, то думаю разбирусь.
Процесс перерисовки у меня весит на событии OnIdle()
while (AppStillIdle)
{
// Render a frame during idle time (no messages are waiting)
Render3DEnvironment();
}
но я так же делал зацикливание для перерисовки, не помогло.
Для задержки на кадров использую цикл, который проверяет количество пройденых тиков с финишным значением, после выхода из цикла
устанавливаю новое конечное время
while (DateTime.Now.Ticks < timeTick); // timeTick — финишное время
timeTick = DateTime.Now.Ticks + tick; // tick — сколько тиков на один кадр
Для нарисования квадрата использую VertexBuffer, который имеет 12 вершин, 6 — для белого, 6 — черного.
В методе Render() происходит выбор вершин в зависимости от условия, т.е VertexBuffer блокирую только один раз
if (isBlack)
{
device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
isBlack = false;
}
else
{
device.DrawPrimitives(PrimitiveType.TriangleList, 6, 2);
isBlack = true;
}
до этого использовал VertexBuffer с 6 вершинами, и при каждой перерисовке блокировал его и менял значения, но результат у меня
не отличается от предыдущего.
Если кто знает как это можно реализовать (плавное увелечение fps), напишите, плиз.
Re: Плавное изменение fps
От:
Аноним
Дата:
02.06.06 10:39
Оценка:
Вызывай рендер из основного цикла проги и отсчитывай кол-во отрисованных кадров, как ты и писал. Не надо вызывать рендер по событию, это так на первый взгляд. Сам пишу только такие вещи с++ и рывки по FPS случаются только по изменению кол-ва отрисованной геометрии (текстур) и кол-во проходов и др. моментов. А у тебя в принципе не должно такого быть
Tick работает только с точностью 55 миллисекунд (если не ошибаюсь )
Ниже, класс — что-то вроде таймера с точностью до одной милисекунды (не знаю уж насколько точно, но близко к этому)
internal class PreTime
{
private PreTime() {}
#region PInvoke
[DllImport("winmm.dll")]
private static extern int timeGetTime();
[DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int milliseconds);
[DllImport("winmm.dll")]
private static extern int timeEndPeriod(int milliseconds);
#endregion
Здравствуйте, Аноним, Вы писали:
А>Я столкнулся с такой проблемой, я не смог плавно увеличивать частоту выводимых кадров. Если выводить от 1-16, то более менее плавно, А>а вот от 16 изменения происходят скачками 16, 21, 32, 64, 83, 96.
Первое что приходит в голову — это из-за синхронизации с собственно кадровой разверткой монитора.
Например, у нас частота кадров на мониторе 100 Гц (100 раз в секунду изображение РЕАЛЬНО может изменяться).
Значит мы можем четко реализовать 100 fps (1:1 с частотой кадров), 50 fps (1:2, каждый кадр держится два цикла кадровой развертки) и т.д.
Сам по себе кадр отрисовывается не мнгновенно, поэтому могут быть и другие значения, но принцип тот же — влияет частота, с которой монитор обновляет изображение.
Re[2]: Плавное изменение fps
От:
Аноним
Дата:
03.07.06 20:50
Оценка:
Здравствуйте, VladSupr, Вы писали:
VS>Tick работает только с точностью 55 миллисекунд (если не ошибаюсь )
Если надо точнее, то вот (наиболее точный таймер из возможных):
public sealed class PerformanceMonitor
{
private Int64 _start;
/// <summary>
/// Начинает подсчет вермени выполнения.
/// </summary>public void Start()
{
_start = 0;
QueryPerformanceCounter(ref _start);
}
/// <summary>
/// Завершает полсчет вермени исполнения и возвращает время в секундах.
/// </summary>
/// <returns>Время в секундах потраченое на выполнение участка
/// кода. Десятичная часть отражает доли секунды.</returns>public float Finish()
{
Int64 finish = 0;
QueryPerformanceCounter(ref finish);
Int64 freq = 0;
QueryPerformanceFrequency(ref freq);
return (((float)(finish - _start) / (float)freq));
}
[DllImport("Kernel32.dll")]
static extern bool QueryPerformanceCounter(ref Int64 performanceCount);
[DllImport("Kernel32.dll")]
static extern bool QueryPerformanceFrequency(ref Int64 frequency);
}