| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Программирование игр, графики и искусственного интеллекта > Подергивание изображения при смещении на канве |
| Автор: NightWishMaster 18.6.2006, 19:46 | ||||||||
| Пускай на форме имеется кнопка, таймер и прямо на канве отображен рисунок. При нажатии на кнопку включается таймер, который с интервалом времени скажем 20 мс начинает сдвигать рисунок с помощью функции CopyRect или какой-нибудь другой (на самом деле здесь не суть важно) в какую-либо сторону, например влево на 5 пикселов. При этом четко видно, что изображение подергивается, при чем период таких подергиваний намного больше 20 мс, да и «размах» тоже. То есть это явно не из-за «грубости» смещений изображения. Этот эффект «рывков» возникает далеко не только при смещении изображения. Он, например, так же имеет место при последовательном рисовании квадрата с помощью функции FillRect с изменением во времени его координат и т.д. Пикантности ситуации придает еще и тот факт, что эти подергивания видны только если смотреть непосредственно на перемещающееся изображение. Если же смотреть не на него, а на неподвижный объект (например, курсор мышки), то боковое зрение не замечает этих рывков. Создается впечатление, что эффект имеет психофизический оттенок. Насколько я понял, этот эффект возникает не из-за ошибок в программе или тормозов системы (специально я проверял на простейших примерах, в чем вы сможете убедиться сами), а из-за соотношений частоты перерисовки изображения с частотой перерисовки всего экрана монитора. В идеале, конечно же, перерисовка изображения должна совпадать с перерисовкой всего экрана монитора и тогда этих подергиваний, скорее всего, видно не будет. Я думаю, что я не первый натолкнулся на эту проблему и кто-нибудь да поймет, о чем я тут говорю, и возможно знает, как от этого избавиться. Вот примеры, с которыми можно при желании поработать, посмотреть, в чем проблема и попробовать ее исправить. 1. На форме лежат Button1, Button2 и Timer1 с периодом 20. При нажатии на Button1 на форме рисуется импровизированный рисунок, а при нажатии на Button2 запускается таймер и изображение начинает смещаться, при чем видны те подергивания, про которые я говорил выше. Кнопки должны быть в нижней части экрана. Заголовочный файл
Файл реализации:
2. На форме лежит Panel1 с Align = alTop, под панелькой лежит Button1. На панели лежит Image1 с Align = alClient, кроме того, на форме присутствует Timer1 с периодом 25. При нажатии на Button1на Image1 начинает двигаться график, на котором тоже легко усмотреть упомянутые подергивания. В отличии от первого примера, здесь все реализовано на функциях WinApi. Этот код взят с http://borland.xportal.ru/forum/viewtopic.php?t=5183&start=0&postdays=0&postorder=asc&highlight . Заголовочный файл:
Файл реализации:
Похожая проблема обсуждалась тут: http://www.wasm.ru/forum/index.php?action=vtopic&forum=11 Обсуждение свелось к использованию функций DirectX для отслеживания «обратного хода луча» и синхронизации перерисовки формы с перерисовкой всего экрана. Я в DirectX к сожалению не силен. В своей програме я использовал лишь функции Buider’a и WinApi. Неужели все действительно так сложно и плавно сдвигать рисунок на фоне невозможно без использования DirectX и упомянутой синхронизации?! Надеюсь, что кто-нибудь сможет что-то подсказать толковое. Заранее благодарен. |
| Автор: DragonFire 20.6.2006, 13:48 | ||
| Так, я код не смотрел - времени нету, но из твоих слов понял, что ты не используешь двойную буферизацию... А это очень полезная штука и ее пожно сделать русками с момощью двсего лишь двух имайджей и нескольких строк)) У меня есть проект на эту тему, но к сожалению не знаю как его тебе передать, напиши чтоли мыло свое... вот из него юнит, может разберешся так... В проекте мяч летает по форме и крутится...
Добавлено @ 13:51 Короче мысль двойной буферезации - ты берешь и все действия, все элементы рисуешь на невидимый имайдж, а потом в конце копируешь с невидимого на видимый - мерцания не будет, все круто. Если мнтересно читай 2 главу книги М. Мозгового "Занимательное программирование"... |
| Автор: arilou 20.6.2006, 23:39 | ||
NightWishMaster
|
| Автор: DragonFire 21.6.2006, 08:12 |
| Ой, на Си написаною. я и не заметил... Но я думаю, что там ничего сложного нет - разберешся и в коде на паскале... Суть то я объснил... |
| Автор: NightWishMaster 21.6.2006, 11:31 |
| DragonFire Благодарю, хотя в коде в своей программе (не в этих примерах, так как причина действительно не в этом) я использую двойную буферизацию. То есть я создаю Битмап, рисую все в нем, в том числе и копирую, и уже потом все это копирую на канву. Насколько я понимаю, то двойная буферизация направлена против мерцания (когда, грубо говоря, фон канвы "промигивает" сквозь изображение), у меня же рисунок при перемещении не мерцает, а подергивается. Это разные эффекты. Вышли мне, пожалуйста, свой проект на volkovych(собака)gmail.com. Буду благодарен! |
| Автор: Romikgy 21.6.2006, 12:50 |
| NightWishMaster, почитай мож поможет http://forum.vingrad.ru/index.php?showtopic=101260&unread=1&st |
| Автор: DragonFire 21.6.2006, 13:28 |
| Отправил, если возникнут вопросы - пиши, но вроде бы двойная буферизация должна решать все проблемы с дрожанием, подергиванием и т.д.... |
| Автор: NightWishMaster 22.6.2006, 10:53 |
| DragonFire, спасибо, сегодня достану Делфи и тогда посмотрю. Хотя я уже по-немножку начал и в DirectX ковыряться.... на всякий случай |
| Автор: DragonFire 22.6.2006, 14:26 |
| Директа - это вещь... А в делфи все просто, паскаль же - учебный язык (наверняка с ним сталкивался)... |