[РЕШЕНО] Приложение с Open GL отнимает 50% ЦП. Как забороть?
Модератор: Модераторы
[РЕШЕНО] Приложение с Open GL отнимает 50% ЦП. Как забороть?
Добрый день всем.
Столкнулся с проблемой, что приложение с Open GL отнимает 50% ЦП.
На "служебных" проектах - не критично, а если мини-игрушку сделать - то уже хочется "полегче".
Версия: 0.9.28.2
FPC: 2.2.4
Посмотрел пример из папки примеров - то же самое, также "загружает" проц. С чего бы? У меня карта не плохая (GTS-250 GeForce), для сравнения WoW ест меньше...
Столкнулся с проблемой, что приложение с Open GL отнимает 50% ЦП.
На "служебных" проектах - не критично, а если мини-игрушку сделать - то уже хочется "полегче".
Версия: 0.9.28.2
FPC: 2.2.4
Посмотрел пример из папки примеров - то же самое, также "загружает" проц. С чего бы? У меня карта не плохая (GTS-250 GeForce), для сравнения WoW ест меньше...
Последний раз редактировалось yeger 27.06.2011 17:18:03, всего редактировалось 1 раз.
А сколько fps? Возможно видео карта так быстро справляется что процессору приходится на половине своей мощности давать ей новое задание(или на полной мощности одного из двух ядер). Если очень большое количество кадров на секунду и нужно экономить процессор - можно просто ограничить их. (если вы дадите большую нагрузку на видео карту, а на процессор нет - процессор станет более свободным)
Fps смотрел в примере - 51.
В своем приложении не смотрел, так как грузят одинаково, от 35 до 50%, думаю fps около того же.
Поискал как ограничить fps (думаю 30 хватит вполне) не нашел, подскажите, как менять?
В своем приложении не смотрел, так как грузят одинаково, от 35 до 50%, думаю fps около того же.
Поискал как ограничить fps (думаю 30 хватит вполне) не нашел, подскажите, как менять?
Скорее всего у вас двухядерный процессор? А тестовое OpenGL приложение осуществляет рендеринг прямо в цикле обработки сообщений, или же постоянно после отрисовки шлёт своему окну сообщение "перерисоваться", что полностью занимает работой одно ядро процессора. Для мультимедийных приложений это норма, но чтобы не перегревать проц, не разряжать аккумулятор в ноутбуке и просто не делать дармовую работу используют вертикальную синхронизацию. Это позволяет запретить приложению делать лишние прорисовки в внеэкранном буфере, до тех пор пока этот буфер не отобразиться на экране. Насколько помню в OpenGL эта функциональность доступна только в виде платформозависимых расширений, под Windows это расширение WGL_EXT_swap_control и функция wglSwapIntervalEXT . Как подключать и использовать расширения смотрите в документации по OpenGL. В примерах конечно же этого не используют.
Прямо в цикле обработки сообщений, да, "перекинуто" по примеру "Application.AddOnIdleHandler(@OnAppIdle)" и соответственно "OnAppIdle" переписана.
wglSwapIntervalEXT(0); Вызывает ошибку при выполнении, т.к. видимо при создании контекста надо вызывать. А у меня просто выведен компонент "TOpenGLControl".
Печально.
wglSwapIntervalEXT(0); Вызывает ошибку при выполнении, т.к. видимо при создании контекста надо вызывать. А у меня просто выведен компонент "TOpenGLControl".
Печально.
>wglSwapIntervalEXT(0); Вызывает ошибку при выполнении
а вы проинициализировали расширение? насколько помню функцию wglSwapIntervalEXT можно вызывать когда угодно
а вы проинициализировали расширение? насколько помню функцию wglSwapIntervalEXT можно вызывать когда угодно
wglSwapIntervalEXT описаный в TOpenGLControl не работает, т.к. инициализируется TOpenGLControl`ом без созданого и текущего контекста OpenGL, его необходимо повторно проинициализировать когда контекст создан и назначен текущим:
Код: Выделить всё
Pointer(@wglSwapIntervalEXT) := wglGetProcAddress('wglSwapIntervalEXT');
if @wglSwapIntervalEXT<>nil then
wglSwapIntervalEXT(0);Код: Выделить всё
Pointer(wglSwapIntervalEXT) := wglGetProcAddress('wglSwapIntervalEXT');
if @wglSwapIntervalEXT<>nil then wglSwapIntervalEXT(0);
Помогло не намного. Было около 50-55%, стало 40-45%, рассчитывал на 10-15...
Но, уже какой-то результат. Спасибо.
А нужна ли постоянная перерисовка? тотально разгрузить проц поможет перерисовка только тогда когда "надо"
Не очень иллюстративно...
Например, убрал перерисовку из OnAppIdle, сделал только при изменении размера и нажатии чего-то на мыши. Сравнение до- после ничего не дало.
Например, убрал перерисовку из OnAppIdle, сделал только при изменении размера и нажатии чего-то на мыши. Сравнение до- после ничего не дало.
>>Сравнение до- после ничего не дало.
значит чтото неправильно делаете не в отрисовке, например забыт done:=true в обработчике Idle. приложите код.
значит чтото неправильно делаете не в отрисовке, например забыт done:=true в обработчике Idle. приложите код.
"забыт done:=true в обработчике Idle" - совершенно верно. 
Все заработало лучше чем ожидалось. Теперь загрузка процессора, что называется "скачет" 0-45%, что вполне меня устраивает.
Спасибо за ответы.
Все заработало лучше чем ожидалось. Теперь загрузка процессора, что называется "скачет" 0-45%, что вполне меня устраивает.
Спасибо за ответы.
- jhonyxakep
- новенький
- Сообщения: 24
- Зарегистрирован: 23.08.2010 14:45:35
Совет на будущее - делайте отрисовку по таймеру. Сам недавно столкнулся с проблемой нагрузки на процессор.
