Знакомство с рисованием с помощью WinApi. Рисование дома, дерева, Солнца и озера

Эта тема аналогична теме

Рисунок будет приблизительно тот же:
Дом, озеро, солнце, WinApi, C++
Полностью всего она не раскроет, но, возможно, поможет сделать какой-то старт в рисовании. Несколько раз ко мне обращались по теме графики, часто на форумах ищут возможности работы с graphics.h, вот небольшой бонус нуждающимся.

Для тех, кто хочет научится работать с графикой, полезны любые приёмы работы. К сожалению, в C++ нет встроенных инструментов для работы с графикой, а есть отдельные библиотеки. Графические библиотеки дают много возможностей и каждая из них по своему удобна. Из-за различий в операционных системах и некоторого рода задач требуется выбор той или иной графической библиотеки. Так, например, изначально в C++ была библиотека graphics.h, замечательный инструмент своего времени, до сих пор можно использовать для обучения каким-то примитивным, но необходимым вещам. Время прошло, компиляторы, использующие такую библиотеку устарели, появились другие средства для работы: OpenGL, sfml, DirectX, WinApi… В зависимости от задачи и средств для решения, выбор самого решения может варьироваться:
— Надо сдать зачёт. Примут что угодно, достаточно написать. Пишем в VisualStudio, надо нарисовать какой-то простой рисунок. — Подойдёт WinApi. Не надо ломать голову над тем, как заставить сработаться компилятор с графическими библиотеками, много лишней головной боли избегается.

Но если надо написать какую-то игру, где важна скорость анимации, плавность, чтоб всё не дёргалось, то WinApi уже совсем не подойдёт, в этом случае стоит использовать более мощные инструменты: SFML, OpenGL, DirectX и подобные.

— Также у кого-то может быть Linux установлен, а не Windows, то опять же WinApi уже как-то не подходит. WinApi — это для Windows.

Отмечу, что при работе с графикой, для рисования используются одни и те же алгоритмы, которые никак не зависят от того WinAPi это или DirectX какой. Если надо вращать какую-то фигуру в пространстве, то в любом случае вращать её можно одинаковым образом в любом из выбранных инструментов.

Так как сегодня Windows весьма и весьма распространённая операционная система, я покажу пример рисования дома, дерева, озера, солнца с помощью WinApi.

Что нужно усвоить для рисования:

В этом примере ничего не происходит, но легко увидеть важные моменты. Объявляются переменные. Это своеобразная инициализация, где мы выбираем холст для рисования и инструменты. Контуры рисуются пером, а способ закрашивания определяется кистью.

Возможно важный для кого-то момент, ширина и высота холста. Иногда нужно знать эти значения. Первым делом на любом рисунке рисуется фон. Для рисования фона мной будет использован обычный закрашенный прямоугольник.

  • Как и setfillstyle() в MS-DOS, кисть закрашивает какую-то область в какой-то цвет. В зависимости от кисти, она может делать это в полосочку, в клеточку, по диагонали…
    Есть два способа объявить кисть. Первый — задать сплошную заливку, второй — указать стиль. Для этого существуют функции: CreateSolidBrush() и CreateHatchBrush()

Для рисования фона будем использовать стилевую кисть.

Сейчас не будет ничего нарисовано. Это только выбор инструмента для рисования. Сейчас всё готово, чтобы нарисовать какую-то закрашенную фигуру. Так как выбрана только кисть, то будет нарисована та часть фигуры, которая закрашивается. Чтобы нарисовать фон, нужно закрасить всё окно. Чтобы закрасить всё окно, имеет смысл узнать ширину окна и высоту окна.

  • Чтобы нарисовать прямоугольник с помощью WinApi, используется функция Rectangle(…)

Вообще, когда рисуете с помощью WinApi, во многих функциях нужно указать прицепленное окно. У нас консольное окно прицеплено в переменную dc, вот такая переменная "Прицепленное окно" и уходит первым параметром вовнутрь функции, рисующей какой-то примитивный объект. Дальше всё зависит от того, какой объект выбран. Так, для прямоугольника нужно указать четыре координаты. Верхний угол и нижний угол (координаты начала и конца его диагонали).

RGB — Это палитра цветов, где R — красный, G — зелёный, B — Синий. Для каждого из этих трёх цветов выбирается одно из 256-и значений [0..255], что влияет на яркость и цвет. В моём коде красному соответствует ноль, зеленому 255, синему 0, значит не красный и не синий, но зелёный. Можно комбинировать цифрами. Но я не буду об этом рассказывать. Сосредоточимся не на подборе цвета, а на рисовании запланированного рисунка.

Нарисуем небо.

WinApi, C++, рисование

  • Для каждого CreateObject нужно вызывать соответствующий DeleteObject, чтобы память не утекала

Какой-то одинаковый стиль может потребоваться для закрашивания/окраски разных фигур в разное время в рамках выполнения одной программы, тогда такие инструменты рисования лучше удалять не сразу, а отложить на потом. Дело в том, что CreateObject выделяет место в памяти, а операции выделения памяти и очистки памяти — это дорогостоящие операции, выполняются они долго. В нашем случае, пока мы только ознакамливаемся, поэтому этот совет проигнорируем, но забывать не станем.

Теперь рисуем солнце и озеро.

WinApi, C++, рисование

  • Для рисования окружности используют функцию Ellipse(…)

Приступим к рисованию самого сложного элемента нашего рисунка, к рисованию дерева. Для того, чтобы нарисовать несколько копий деревьев, да и для того, чтобы отделить внимание, буду использовать класс, объект которого станет рисунком. Рисование это долгое, нудное и неприятное. Я использую относительное позиционирование, где рисунок начинается от точки, но вы можете упростить себе это дело и подгонять прямо по цифрам. Это проще, но тоже очень нудно и долго. Координаты можно вписывать сразу цифрами. Но лучше позционировать относительно какой-то точки, это поможет при создании копии, в конце статьи будут созданы копии рисунков.

WinApi, C++, рисование
Если вы попробуете нарисовать что-то своё, то непременно возникнут затруднения в попадании на нужную точку. Здесь, например, очень сложно было попасть листом на ветку дерева. Но я поделюсь маленьким секретом облегчения такой задачи. Чтобы попасть в точку, имеет смысл нарисовать какую-то точку и гонять её по экрану, а после удачного попадания использовать координаты такой точки. Ориентироваться в осях X и Y всё равно придётся. На экране ось X уходит слева направо, а ось Y сверху вниз (не как в школе учили). Лучше делать не совсем обычную точку, а жирную, большую. Для этого подходит эллипс. Координаты эллипсу задаются так X1+dx1,Y1+dy1, X2+R+dx2, Y2+R+dy2. Но, догадываюсь, что вам ничего не скажет. Пример для экспериментов (игра со значениями может помочь выбирать координаты быстрее, если двигать точку и стараться попасть в нужное место, после попадания у этой точки переписываются координаты в нужное место кода):

Суть проста, но понять может быть не совсем просто. Суть: видеть точку на экране и сдвигать её до тех пор, пока она не попадёт в нужное место. После этого можно провести расчёт координат (в X+dx1 подставить значения X и dx1 и расчитать, для остальной части также).

Перейдём к рисунку. Осталась последняя часть. Надо нарисовать дом. Дом состоит из многоугольников: треугольник, параллелограмм, прямоугольники.

  • Для рисования закрашенного многоугольника с помощью WinApi можно использовать функцию Poligon(…)


WinApi, C++, рисование
Немного уныло смотрится один дом и одно дерево. Благодаря подходу, ориентированному на работу с классами, можно легко построить ещё несколько домов и посадить несколько деревьев.

WinApi, C++, рисование
Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

Один комментарий: Знакомство с рисованием с помощью WinApi. Рисование дома, дерева, Солнца и озера

Добавить комментарий

Ваш e-mail не будет опубликован.

Поиск

 
     

Случайная книга в электронном формате

Яндекс.Метрика
НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

вакансия "Программист Психологической службы" - Алё! у нас ошибко! не работает тра-ля-ля - Вы хотите об этом поговорить? )))

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок