Программирование графики: Рисование линий
Xakep, номер #046, стр. 046-075-1 Horrific aka Фленов Михаил smirnandr@mail.ru www.cydsoft.com/vr-online Начиная с этого номера, я хотел начать знакомить тебя с разными графическими алгоритмами. Почему я сказал "хотел"? Мне трудно это сказать, но, возможно, это последняя статья по графике в ][. Скоро грядут большие перемены, и я надеюсь, что они будут только к лучшему. Но все же я дам один алгоритм, хотя и простой, но все же интересный. В этой статье я постараюсь тебе показать, как можно быстро нарисовать линию. В DirectDraw нет функций для рисования примитивов, как в WinAPI и ее библиотеке GDI. Если при программировании с помощью GDI у тебя есть все необходимое для рисования линий, прямоугольников и кругов, то в DirectDraw ничего подобного не заложено. Ты, конечно, можешь получить контекст рисования DirectDraw поверхности и использовать стандартный WinAPI набор функций, но от этого скорость вывода только замедлится. Именно поэтому программерам графики приходится выпендриваться и делать все возможное, только чтобы нарисовать одну полоску. Но не так страшен черт, как Билл Гейтс :). Сегодня я покажу, как простейшим, а главное очень быстрым способом вывести на поверхность линию. Раз линия должна выводиться очень быстро, то для этого я буду использовать прямой доступ к памяти. В принципе, это единственный способ нарисовать что-либо на экране, не считая копирования в поверхность подготовленной картинки. Но так как линии бывают разные и заранее подготовить изображения всех возможных вариантов - нереально, то придется поработать ручками. Законы Для начала давай определимся, что линию всегда будем рисовать сверху вниз. В этом случае нам нужно будет всегда увеличивать координату Y (или оставлять неизменной, если линия расположена горизонтально). Это немного упростит задачу, но для универсальности кода придется вначале проверять координаты, и если X1 больше Х2, то менять координаты местами. Теперь давай будем смотреть на код, и постепенно я буду все подробно описывать. Пример будет на Delphi, но я постараюсь дать подробные объяснения, чтобы ты смог повторить то же самое на любом языке. Переменные Для начала определимся с переменными, которые нам понадобятся: X1, Y1, X2, Y2 - все это целые числа, в которых хранятся координаты двух точек (начало и конец линии). DX, DY - длинна отрезка по оси Х и Y. Offset - здесь мы будем хранить указатель на точку в видеопамяти, куда мы будем выводить следующую точку. NS - одну из координат мы будем увеличивать постоянно, а вторую только тогда, когда этот счетчик будет меньше нуля. i - при выводе будет использоваться цикл for..to..do, так что это, как всегда, счетчик для этого цикла. Подготовка Для примера я взял код из прошлой статьи, где мы случайным образом засыпали экран белыми точками. Открой тот пример и найди код, где мы блокировали поверхность для получения к ней прямого доступа: ZeroMemory (@desc, SizeOf(desc)); desc.dwSize := SizeOf(desc); hRet:=FImageSurface.Lock(nil, desc, DDLOCK_WAIT, 0); Этот код оставляем без изменений и после этого пишем: //Указываю координаты начала и конца линии (10, 10) и (220, 12) |