Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Object Pascal: кроссплатформенные технологии > Работа с Графикой


Автор: nighthare 15.2.2006, 22:00
Собственно вопрос такой. Если перерисовывать в паскале путем очистки экрана, то возникает не приятное моргание. Как можно работать с буфером видеокарты, чтобы дальше выводить обновленный экран? можно ли сделать например так, делаем 2-мерный массив, туда заносим нужные точки, потом передаем его видеокарте, она его отрисовывает? Интересует в первую очередь как это правильно реализовать в среде Pascal ( с примерам(и) ) (так же интересно как это сделать на .net, но это немного не в тот раздел smile )

Автор: remax 15.2.2006, 22:22
В досе была возможность работы с виртуальными экранами. Один активен - на другом подготавливаем картинку. Затем меняем местами. Однако, из под Win многие досовские возможности режутся. Поэтому, надо определиться - под что писать прогу.

Автор: nighthare 15.2.2006, 22:30
как ты сказал, очень классный вариант, но программа будет запускаться именно из Win...

Автор: karataev 15.2.2006, 23:30
Я предлагаю просто зарисовывать уже отработанные пиксели цветом фона, поэтому будет обновляться не весь экран, а только ненужные пиксели. Как раз можно сделать и с двухмерным массивом это.

Автор: nighthare 16.2.2006, 15:47
Думаю это не подходит по 2 причинам 1) либо это очень сложно просчитать математически и понять какие все-таки пиксели надо менять а какие нет 2) либо если я буду удалять отработанные и рисовать свои, то возникнет эффект моргания (весь монитор не будет моргать,а что я конкретно буду перерисовывать - будет, если фон и обьект контрастный, а если еще и фона как такового и нет...) Мой вопрос больше ориентирован на то, чтобы все это запихнуть по ближе к буферу видеокарты, чтоб я рисовал только следующий кадр(измененный)... я могу в терминологии (про буфер и т.д.) ошибаться, потому что не знаю как это идет на аппаратном уровне.

Автор: Ozzя 16.2.2006, 16:14
Цитата

делаем 2-мерный массив, туда заносим нужные точки, потом передаем его видеокарте, она его отрисовывает

Тупиковый вариант, однозначно.

Цитата

из Win...


ТО есть нужен 32-х разрядный компилятор под win32

Цитата

работы с виртуальными экранами

Модуль Graph TMT Pascal'я 4 все это поддерживает.

Автор: nighthare 16.2.2006, 16:23
Все пишется на Borland Turbo Pascal 7.0 ( это что-то вроде некого задания на семестр, я ищу подходу к этой теме, хочется сделать по красивее) запускается все это дело через виндовский эмулятор доса ( насколько я понимаю ) smile (если у кого есть примеры на эту тему для Borland C (C++) или под .NET (C#) , поделитесь smile )

Автор: Ozzя 16.2.2006, 17:09
nighthare,
Тогда какие проблемы?
Режим EgaHi - 640X350
Две страницы аппаратных.
Нарисовали , поменяли страницу, Нарисовали

Автор: volvo877 16.2.2006, 17:13
Цитата(nighthare @ 16.2.2006, 15:23 Найти цитируемый пост)
Все пишется на Borland Turbo Pascal 7.0


В таком случае копай в сторону процедур:
SetActivePage/SetVisualPage... И делай, как посоветовал remax, пока один экран ВИДИМ, другой устанавливаем АКТИВНЫМ, и готовим картинку. Как только подготовили - SetVisualPage на эту страницу - картинка появляется за 1 проход луча по монитору...


Автор: nighthare 16.2.2006, 17:20
Спасибо, буду копать.

Автор: nighthare 17.2.2006, 22:48
делаю так :
Код

{процедура}
cleardevice;
setactivepage(1);
{Здесь ставлю точки}
setvisualpage(1);

эффект моргания не пропал, но вроде стал меньше... есть еще какие-нибудь способы? (полный пример выложу в раздел помощи)

Автор: Ozzя 18.2.2006, 11:09
refresh отслеживай

Автор: nighthare 18.2.2006, 16:33
Простите за глупый вопрос, но как его отслеживать? Вместо cleardevice впихнул закраску всего экрана черным цветом(после setactivepage(1); перед setvisualpage(1);) получил ужасное моргание smile . В хэлпе вдобавок написано, что это работает толька на плате Hercules... Что я не правильно делаю?

Автор: cardinal 19.2.2006, 15:56
Посмотри про двойную буфферизацию в инете. Именно это вариант решения проблемы моргания, при передвижении объектов. Но не уверен, что в данной ситуации подходящий. Но я бы капнул в эту сторону...

Автор: Ozzя 20.2.2006, 11:20
Цитата(nighthare @ 18.2.2006, 16:33)
Простите за глупый вопрос, но как его отслеживать?

Ждем обратного хода луча
Код

Procedure WaitRetrace;Assembler; 
Asm 
 mov dx,$3DA 
 @lp: 
  in al,dx 
  and al,$08 
 jz @lp 
End; 

Автор: nighthare 20.2.2006, 15:01
Ozzя, т.е. мы отрисовываем в setactivepage, после этого вставляем эту процедуру, потом setvisualpage? если не сложно, можешь прокоментировать в коде каждую строчку после Asm и до End; .
Added @ 15:12
Ozzя Он не моргает!!!!! просто супер!!!!!!!! большое спасибо!!! только обьясни пожалуйста что делают эти ассемблерные команды и как они работают....

Автор: Romikgy 20.2.2006, 15:14
nighthare, а какой ф-цией ты рисуешь точки?

Автор: nighthare 20.2.2006, 15:27
Romikgy, putpixel...
Код

procedure T3d.draw(n:byte);
  var
   i,midx,midy:integer;
  begin
   setactivepage(0);
   cleardevice;
   midx:=round(getmaxx/2);
   midy:=round(getmaxy/2);
   for i:=1 to amount do
   begin
    putpixel(round(dp_dyn^[i].x)+midx,round(dp_dyn^[i].y)+midy,white);
   end;
   WaitRetrace;
   setvisualpage(0);
  end;

Автор: Romikgy 20.2.2006, 15:35
nighthare, сиба
smile

Автор: Ozzя 20.2.2006, 15:41
nighthare,

Код

Procedure WaitRetrace;  {ожидание вертикального обратного хода луча} 
Begin 
   While(Port[$3DA]and $08)=0 do; 
End; 


Дополнительно читать тут
http://emanual.ru/download/7045.html

Автор: Romikgy 20.2.2006, 16:05
nighthare, а не проще ли будет взять адресс буфера видеостраницы и копировать массивами туда, а не
Цитата(nighthare @ 20.2.2006, 14:27 Найти цитируемый пост)
putpixel

?

Автор: nighthare 20.2.2006, 16:23
Romikgy, думаю проще, а как найти этот адрес, и как его взять в Pascal'e ? smile

Автор: Ozzя 20.2.2006, 16:46
A000 - Для граф. режима ega/vva
Добавлено @ 17:00
Move( $a000,$a800,$800); - копирование
Как-то так.
1-я страница лежит по адресу $a000, вторая - начинается с $a800.
Фишка в том, что в режиме 640X350 копируются сразу все 4 плоскости (latches). Надо установить регистр контроллера. Какой - не помню.
Почитай Фроловых по ссылке. Там есть пример копирования.

Автор: Romikgy 20.2.2006, 17:02
обращение к памяти в паскале , на сколько помнится mem[seg:off]

Автор: nighthare 20.2.2006, 17:06
Ozzя, а там едет так? я записываю точку с координатами 0,0 , увеличиваю адрес, записываю 0,1 ... 0,640 -> 1,0 и так далее? и как туда писать цвет точки( т.е. там усроено что либо true либо false, или либо false либо номер цвета? ) или можно как-то создать огромный массив и потом его целиком пихать в этот буфер?? smile

Added @ 17:09 буду читать и разбираться...

Автор: Romikgy 20.2.2006, 17:11
это масссив точек заданый цветом каждой точки

Автор: Ozzя 20.2.2006, 17:16
Нет, режим 640Х350 сложнее.
Цитата

Режим 10h
Графический цветной режим с разрешением 640х350 пикселов. Данный режим поддерживают только видеоадаптеры EGA и VGA.

Для хранения видеоданных используются четыре цветовых слоя. Каждому пикселу соответствует по одному биту из каждого цветового слоя. Четыре бита на пиксел позволяют отображать 16 различных цветов. Запись в каждый из этих черырех слоев можно разрешить или запретить при помощи регистра разрешения записи цветового слоя.


Цитата

Рисунок 6.12 Структура видеопамяти режима 10h.

Если вы хотите выводить информацию на экран дисплея непосредственно через видеопамять, то необходимо уметь определять биты, которые управляют каждым пикселом изображения. Следующие формулы позволяют определить смещение байта от начала станицы видеопамяти и номер бита в нем, управляющего пикселом с координатами (x,y):

Смещение байта = 50h*y+x/8

Номер бита = 7-mod(x/8)

Автор: Romikgy 20.2.2006, 17:29
Ozzя, более точнее ответил smile

Автор: nighthare 20.2.2006, 18:05
тогда вопрос, этот способ эффективнее чем putpixel? (если не считать что с его помошью наверное можно сделать двойную буферизацию) если да, то действительно будет работать заметно быстрее?

Автор: Ozzя 20.2.2006, 18:14
В принципе, bgi-графика достаточно быстра, за исключением заливки.
Никто не мешает рисовать во 2-й странице, и затем перебрасывать на 1-ю.

Автор: nighthare 20.2.2006, 18:35
Ozzя,
Цитата(Ozzя @ 20.2.2006, 18:14 Найти цитируемый пост)
Никто не мешает рисовать во 2-й странице, и затем перебрасывать на 1-ю.
а как это правильно реализавать? в моем примере(выше) когда я очищаю память, рисую на странице, а потом ее отображаю(по идее это так должно быть), это не приводит к требуемуму результату (а если правильно делать рефреш то и без visual/active page все прекрасно работает (за исключением если рисовать что-то не putpixel'oм, тогда опять появляется моргание))

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)