Шаг 17 - Вывод примитивов на экран

Экран у нас теперь готов, научимся выводить примитивы на этот экран. Самым "примитивным" из примитивов является точка или пиксел, как кто хочет. Если Вы никогда не занимались графикой, то Вам вероятно будет сложно сообразить, что значит вывести точку.

Видео память в PC-совместимых системах линейна, если не считать древних режимов EGA или CGA. Поэтому для того, чтобы вывести точку на экран достаточно просто записать байт-цвет в соответствующую ячейку в памяти. "Линейная память" надо понимать так: каждая последующая строка пикселов размещается в памяти точно за предыдущей строчкой. Небольшой пример:

RRRGGGGBBB
GGGBBBRRRB
..........

Допустим это картинка на экране, тут буквы RBG это какие-то цвета. Так вот в нашей линейной памяти эти строчки будут располагаться так:

RRRGGGGBBBGGGBBBRRRB..........

Думаю Вам уже должна быть понятна следующая формула: адрес_ячейки=Y_точки * Ширину_Экрана + Х_точки. Именно по ней мы будем вычислять адрес пиксела в памяти. Так вот давайте напишем процедуру вывода этого пиксела:

int CGIScreen::PutPixel(int x,int y,char color)
{
	if ((x<0)||(x>=width)||(y<0)||(y>=width))
		return -1;
	*(scr+y*width+x)=color;
};

Естественно надо не забывать, что точка может заходить за границы экрана, поэтому ее надо проверять. Это делает оператор if (...). Теперь Вы можете выводить точку в любое место и все, что надо будет отображаться.

Дальнейней процедурой должна быть линия. Алгоритмов вычерчивания линии насколько я знаю есть предостаточно, но повсюду используется один - это алгоритм Брезенхейма. Объяснить по нормальному это дело я Вам сейчас без подготовки не смогу, да и не та у нас тут тематика, по этому просто принимаем "as is" :-)

int  CGIScreen::Line(int x1,int y1,int x2,int y2, unsigned char Color)
{
  int dx=abs(x2-x1);
  int dy=abs(y2-y1);
  int sx=x2 >= x1 ? 1:-1;
  int sy=y2 >= y1 ? 1:-1;
  int d,d1,d2,x,y,i;
  if (dy<=dx)
  { d=(dy << 1)-dx;
    d1=dy << 1;
    d2=(dy - dx) << 1;
    PutPixel(x1,y1,Color);
    for (x=x1+sx,y=y1,i=1;i<=dx;i++,x+=sx)
    {
      if (d>0){d+=d2;y+=sy;}
      else d+=d1;
      PutPixel(x,y,Color);
    }
  }
  else
  {
    d=(dx << 1) - dy;
    d1=dx << 1;
    d2=(dx - dy) << 1;
    PutPixel(x1,y1,Color);
    for (x=x1,y=y1+sy,i=1;i<=dy;i++,y+=sy)
    {
      if (d>0){d+=d2; x+=sx;}
      else d+=d1;
      PutPixel(x,y,Color);
    }
  }
  return 0;
};/*Line*/

Вычерчивание линии происходит по точкам, а значит будет действовать наш механизм "отсечки" ненужных пикселов.

Помоему уже не плохо. Самые главные можно сказать примитивы мы научились строить. Дело за немногим, использовать их для создания более сложных объектов.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Кузин Андрей - 06.05.2000