Комплексной целью модуля является изучение следующих элементов OpenGL
-
Примитив "прямая линия".
-
Типы примитивов, состоящих из прямых линий – отдельные отрезки прямых, отрезки прямых, соединенные своими концами, замкнутые фигуры из отрезков прямых линий.
-
Атрибуты прямых линий. Подобно точкам прямые линии обладают шириной, сглаживаемостью, цветом. Кроме того прямые линии могут быть прерывистыми.
1.0 Примитив LINES
Примитив LINES позволяет изображать отдельные отрезки прямых линий, концы которых определены вершинами, перечисленными между вызовами методов Begin/End. Отрезки прямых линий могут иметь разную толщину, цвет, сглаживаемость, быть сплошными или прерывистыми.
Первый примитив, имеющий отношение к прямым линиям, представляет собой отдельные отрезки прямых, заданные своими граничными вершинами. Перечисление вершин проводится внутри пары
gl.Begin(gl.LINES);
gl.End();
Константа LINES уже описана в классе gl метода GL
///
/// Рассматривает каждую пару вершин как независимый отрезок прямой.
/// Вершины 2n - 1 и 2n определяют прямую n.
/// Изображается N/2 прямых, где N - полное число вершин.
///
public const int LINES = 0x0001;
Атрибутами прямых линий управляют методы, которые рассмотрены в следующих разделах.
Метод LineWidth
Ширина линии определяется методом LineWidth
///
/// Устанавливает ширину линии width
///
[DllImport("OPENGL32.DLL", EntryPoint = "glLineWidth")]
public static extern void LineWidth(float width);
При сохранении атрибутов прямой линии в стеке следует использовать метод PushAttrib с константой
///
/// Маска атрибутов прямой.
///
public const int LINE_BIT = 0x00000004;
Для определения текущих значений ширины линии, ее минимального, максимального значений и шага, с которым ширина линии меняется, следует использовать метод Get в форме
// Минимальная ширина линии
gl.Get(gl.LINE_WIDTH_RANGE, 2)[0];
// Максимальная ширина линии
gl.Get(gl.LINE_WIDTH_RANGE, 2)[1];
// Шаг изменения ширины линии
gl.Get(gl.LINE_WIDTH_GRANULARITY, 1)[0];
// Текущая ширина линии
gl.Get(gl.LINE_WIDTH, 1)[0];
Константы, используемые здесь, имеют значения
///
/// Аргумент Get требует возврата значения двух параметров -
/// минимально и максимально возможной ширины прямой линии.
///
public const int LINE_WIDTH_RANGE = 0x0B22;
///
/// Аргумент Get требует возврата значения одного параметра -
/// раличия в значениях ширины линии, которые учитываются в изображении.
///
public const int LINE_WIDTH_GRANULARITY = 0x0B23;
///
/// Аргумент Get требует возврата значения одного параметра -
/// текущей ширины линии.
///
public const int LINE_WIDTH = 0x0B21;
Сглаживаемость линии
Подобно точке изображение линии может регулировать эффект сглаживаемости. Этот эффект управляется методом Enable с параметром
///
/// Параметр сглаживания изображения линии.
/// Используется методами Get, Enable, IsEnabled и Disable.
///
public const int LINE_SMOOTH = 0x0B20;
Узнать текущее состояние активности сглаживания линии можно либо методом Get, либо методом IsEnable с тем же параметром.
Примечание
Активизация сглаживаемости в случае прямой линии может быть не эффективна, если толщина линии достаточно велика. Поэтому использование этого атрибута лучше ограничить только малыми толщинами.
Метод LineStipple
Линии можно изображать пунктиром произвольного формата. Формат пунктира определяется параметрами метода LineStipple
///
/// Определяет шаблон пунктира при изображении прямой линии
///
///
/// Число повторов каждого бита шаблона при изображении пунктира.
/// принимает значения от 1 до 256. По умолчанию равен 1.
///
///
/// 16-битовый шаблон пунктира. Те части линии, где в бите шаблона находится 1,
/// будут выводиться на экран, остальные нет.
/// По умолчанию все биты равны единице, и шаблон равен 65535 - сплошная линия.
///
[DllImport("OPENGL32.DLL", EntryPoint = "glLineStipple")]
public static extern void LineStipple(int factor, ushort pattern);
Текущее состояние параметров factor и pattern определяется методом Get в следующей форме
// Текущее значение фактора прерывистости
(int)gl.Get(gl.LINE_STIPPLE_REPEAT, 1)[0]
// Текущее значение маски прерывистости
(int)gl.Get(gl.LINE_STIPPLE_PATTERN, 1)[0]
Использованные здесь константы равны
///
/// Аргумент Get требует возврата значения одного параметра -
/// фактора прерывистости прямой линии.
///
public const int LINE_STIPPLE_REPEAT = 0x0B26;
///
/// Аргумент Get требует возврата значения одного параметра -
/// шаблона прерывистости прямой линии.
///
public const int LINE_STIPPLE_PATTERN = 0x0B25;
Метод LineStipple эффективен лишь в том случае, если активировано пунктирное изображение. Активация проводится методом Enable с параметром
///
/// Параметр активации пунктирного изображения прямой линии
///
public const int LINE_STIPPLE = 0x0B24;
Определение текущей активности пунктирного изображения проводится либо методом Get, либо методом IsEnable с тем же параметром.
Используйте описанные методы в своем приложении. Посмотрите иллюстрацию использования этих методов в авторском приложении. Код этой части авторского приложения можно найти по ссылке.
Тест рубежного контроля
-
Какой метод устанавливает ширину линии?
-
Как получить текущие значения ширины линии, ее минимального значения, максимального значения и шага изменения?
-
Что делает метод LineStipple?
-
Как получить текущие значения параметров метода LineStipple?
-
Как сохранить текущие атрибуты линии в стеке?
-
Как активировать прерывистость линии?
Проектные задания
-
Напишите алгоритм, который позволит изобразить оси объектной системы координат с метками в виде букв X, Y, Z у положительных окончаний соответствующих осей тех же цветов, используя символы в форме битовых карт.
-
Создайте дисплейный список команд, включив в него команды созданного алгоритма.
-
Изобразите метки осей в форме букв контурного шрифта (третий способ) так, чтобы символы имели цвет оси, находились на конце оси и лежали в плоскости перпендикулярной оси.
Указание: используйте методы PushMatrix, PopMatrix, Translate, Rotate, Scale с каждым из символов.
Второй примитив прямых линий LINE_STRIP определяет последовательность связанных друг с другом отрезков прямых
///
/// Изображает связанную группу отрезков прямых от первой до последней вершины.
/// Вершины n и n+1 определяют прямую n. Изображается N - 1 прямая, где N - полное число вершин.
///
public const int LINE_STRIP = 0x0003;
Вершины указываются между методами
gl.Begin(gl.LINE_STRIP);
gl.End();
Каждой вершине может соответствовать свой цвет, как и в случае отдельных отрезков прямых линий.
Третий примитив линии LINE_LOOP изображает замкнутую фигуру из отрезков прямых.
///
/// Изображает связанную группу отрезков прямых от первой до последней вершины,
/// затем назад - к первой вершине.
/// Вершины n и n+1 определяют прямую n. Последняя прямая определяется вершинами N и 1.
/// Изображается N прямых, где N - полное число вершин.
///
public const int LINE_LOOP = 0x0002;
Достаточно заменить в предыдущем фрагменте кода параметр gl.LINE_STRIP в методе gl.Begin значением gl.LINE_LOOP. Конец последнего отрезка прямой будет совпадать с началом первого – фигура образует многоугольник.
Посмотрите иллюстрацию использования этих методов в авторском приложении. Код этой части авторского приложения можно найти по ссылке.
Вопрос для самоконтроля
Чем отличаются примитивы LINE_STRIP и LINE_LOOP?
Проектные задания
-
Сделайте надпись "LINE LOOP" с помощью контурного шрифта в плоскости треугольника из отрезков прямых.
-
Постройте окружность единичного радиуса из отрезков прямых линий, лежащую в плоскости XY, используя примитив LINE_LOOP.
-
С помощью символов контурного шрифта изобразите циферблат.
-
Изобразите минутную и секундную стрелки на циферблате и, используя системный таймер, заставьте часы идти.
Достарыңызбен бөлісу: |