Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
Lord_of_Darkness Я тут поигрался и пришёл к выводу
Код:
uses crt, graph; VAR GRAPHDRIVER, ErrorCode, GRAPHMODE, i : INTEGER; alpha : real; procedure MyGraphInit; begin GraphDriver := Detect; InitGraph(GraphDriver, GraphMode, 'c:\bp\bgi'); ErrorCode := GraphResult; if ErrorCode <> grOk then begin writeln('InitGraph Error: ',GraphErrorMsg(ErrorCode)); Writeln('Program is aborted!'); Halt (1); end; end; begin MyGraphInit; alpha:=0; repeat; { ClearViewPort; } SetColor(15); Circle(320,240,100); line(320,240,320+trunc(100*cos(alpha)),240+trunc(100*sin(alpha))); delay(1000); SetColor(0); { Circle(320,240,100);} line(320,240,320+trunc(100*cos(alpha)),240+trunc(100*sin(alpha))); alpha:=alpha+0.1; until keypressed; CloseGraph; end.
Прикол наверное в "тяжести" функции сайкл. И ешё я не понял как работает делай(ххх) - ведь по идее 1000 соответствует 1 секунде, но то чтот происходит на экране явно быстрее.
Lord_of_Darkness Я тут поигрался и пришёл к выводу Прикол наверное в "тяжести" функции сайкл. И ешё я не понял как работает делай(ххх) - ведь по идее 1000 соответствует 1 секунде, но то чтот происходит на экране явно быстрее.
1000 - на новых процах НЕ СООТВЕТСТВУЕТ одной секунде. Дело, по-моему, в привязке к таймеру.
Задержка лишь помогает уменьшить количество мерцаний за счет уменьшения количества новых кадров в секунду. Чтобы совсем не мигало, надо успевать строить новый кадр во время обратного хода луча вертикальной развертки. Т.е. изображение на экране обновляется с некоторой частотой (например, 85Гц). После построения кадра (построчно сверху вниз) луч идет вверх для построения нового. Надо ожидать момента, когда кадр построен и луч пошел вверх - и начинать выводить картинку. Если картинка успевает построится до начала построения нового кадра - мигания нет, каждый кадр на экране будет выдаваться уже при отрисованой в видеопамяти окружности. Если нет - то будет мигание - например, один кадр отрисуется при стертой окружности, затем при нарисованной, затем опять при стертой и т.п. Или того хуже - при частично нарисованной окружности - т.е. будут мигать разные части в разное время.
Если же кадр слишком сложный и его не удается построить за время обратного хода лучам - то применяют технику двойной буферизации - т.е. строят кадр сначала в памяти компьютера или в странице видеопамяти, которая не выводится на экран - затем ждут, пока закончится генерация кадра на экране компа, и выводят подготовленый заранее кадр простым копированием в видеопамять (или просто переключают страницы видеопамяти) - это обычно делается очень быстро, при правильной реализации. Затем строят следующий кадр в памяти и так далее.
Собственно, в Винде тоже так делается - только там не нужно (а иногда и невозможно) ждать окончания построения кадра - она его сама ждет для отрисовки изменений. Достаточно применения двойной буферизации в ней. В DOS надо самому ждать.
В целом, ничего сложного в этом нет - если не лень и очень надо, поищите по докам по DOS/BIOS, по книгам о программировании графики в DOS, как ловить момент начала обратного хода луча...
Member
Статус: Не в сети Регистрация: 04.01.2004 Откуда: 31
mein Мерцания добавляет не только Circle, но и сама очистка экрана.
Lord_of_Darkness Вот еще простой вариант решения:
1. Рисуешь круг (а впрочем что угодно).
2. Делаешь GetImage на свой рисунок.
3. Очищаешь экран.
4. Запускаешь цикл
5. PutImage куда нужно.
Чтоб не заморачиваться с очисткой (если конечно фон одноцветный), то GetImage делать с небольшим запасом по краям, тогда при очередном PutImage предыдущий затирается.
Advanced member
Статус: Не в сети Регистрация: 09.03.2004 Откуда: Кишинёв
Yamamoto
Цитата:
попробуй рисовать картинку нужным цветом, а потом её же - но цветом фона, то есть как бы затирать её самой собой же.
Ну, дык, я и предложыл это дело - у меня не мигало. Но это же конечно не выход. Когдато я пытался рисовать в паскале что-то, и помница мне помогали (как S.Q.Lapp сказал) функции гет и пут-имадж.
mein Всё равно срывы картинки будут наблюдатся - когда спрайт не полностью скопирован в видеопамяти, а картинка на экран уже выводится. Хотя и не так часто, чем при обычной отрисовке, и не мерцание будет, а скорее сдвиг одной части спрайта относительно другой. Полной плавности не будет. К тому же если перемещаются несколько перекрывающихся объектов на фоне изменяющегося фона - то такой метод ничего не даст. Хотя если цель автора - только окружность подвигать - то сойдет и так, небольшие и не слишком частые срывы отрисовки спрайтов на глаза давить особенно не будут. Но в общем случае любительский это метод и несовершенный.
А то, что я описал - это правильный и универсальный метод, так обычно все игры делают (и не только в TP, а вообще - а для ТР vor указал, как в нем это нативно делается, хотя я в свое время (лет 10 назад) писал собственные библиотеки для этого - чтобы в VGA/SVGA режимах самописные игры нормально и быстро работали).
P.S. Кстати говоря, тут упоминали OGL. Для OpenGL/DirectX это тоже справедливо. Драйвера тоже ожидают начало обратного хода луча - если включена соответствующая опция в драйверах (Vertical Sync обычно называется) - синхронизация с частотой вывода кадров на экран. Если эта опция отключена - тоже возможны срывы/дергания картинки. Хотя на современных картах это очень редко происходит даже в этом случае - ибо скорость рендеринга большая + аппаратно/драйверно пытаются это дело по возможности сделать редким/незаметным + двойная/тройная буферизация очень помогает (которая используется в подовляющем большинстве случаев).
P.P.S. В общем, смотрите сами - "кто виноват" и "что делать" я вам изложил, а <b>vor</b> указал, как это в ТР делается в простейшем случае.... А далее - каждый выбирает для себя...
Всю сознательную жизнь пользовался для этих целей следующей процедуркой:
Код:
procedure sync;assembler; asm mov dx,03DAh @@wait: in al,dx test al,08h jz @@wait end;
Когда нужно что-то нарисовать, вызываешь ее, и после выхода из нее быстро-быстро рисуешь Насколько я понимаю, она ждет начала обратного хода луча, после чего завершается (соответственно, создавая некоторую задержку; если сама программа кушает много ресурсов, придется извращаться, иначе все может дико тормозить)
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения