Опубликован: 02.12.2011 | Доступ: свободный | Студентов: 980 / 117 | Оценка: 5.00 / 4.00 | Длительность: 09:26:00
Специальности: Программист
Теги: .net, open source, opengl
Лекция 11:

Интерактивные приложения OpenGL

< Лекция 10 || Лекция 11: 123 || Лекция 12 >

Определение области выбора объектов

Обычно область, в которой необходимо определить наличие объектов (область выбора объектов), определяется как фрагмент проекции сцены. Например, пользователь на изображении проекции выделяет с помощью манипулятора (например, указателя типа "мышь") прямоугольную область или просто щелкает кнопкой "мыши", определяя, таким образом, область выбора.

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

Для определения трехмерной области выбора на основании прямоугольного фрагмента проекции сцены необходима информация о матрице проекции. Для этого можно использовать некоторые функции из библиотеки GLUT, которая является надстройкой над библиотекой OpenGL и предоставляет ряд дополнительных возможностей.

В библиотеке OpenTK функции библиотеки GLUT находятся в классе Glu в пространстве имен Tao.OpenGL (C#). В Object Pascal все функции и процедуры библиотеки GLUT имеют префикс "glu", что позволяет их отличать от процедур и функций OpenGL.

Для формирования матрицы проекции на основе выбранного фрагмента проекции сцены можно использовать команду PickMatrix библиотеки GLUT:

C#:
  void gluPickMatrix(double x, double y, double width, double height, int[] viewport);
Object Pascal:
  procedure gluPickMatrix(x,y,width,height: GLdouble; viewport: PGLint);

Команда PickMatrix библиотеки GLUT изменяет текущую матрицу таким образом, чтобы размер области сцены соответствовал области выбора, определённой в координатах проекции этой сцены. Команды имеет следующие параметры:

  • x, y – горизонтальная и вертикальная координаты области выбора в координатах окна, в котором отображается проекция трехмерной сцены.
  • width, height – ширина и высота выбранной прямоугольной области проекции трехмерной сцены в координатах окна.
  • viewport – массив четырех целочисленных элементов. В C# передается непосредственно массив в качестве параметра, в Object Pascal в качестве параметра передаётся указатель на массив. Массив определяет область вывода проекции трехмерной сцены. Значения массива должны соответствовать координатам области вывода, определённым с помощью команды ViewPort. Элементы этого массива должны иметь следующие значения: 1й и 2й элементы – координаты x и у левого верхнего угла выделенной области в координатах экрана, 3 и 4 элементы – ширина и высота этой области.

Команда должна быть выполнена перед выполнением команд Ortho или Frushtum, с помощью которых формируется матрица проекции.

Перевод библиотеки OpenGL в режим выбора

Для перевода библиотеки в режим выбора используется команда RenderMode:

C#:
  int RenderMode(RenderingMode mode);
Object Pascal:
  function glRenderMode(mode: GLenum): GLint;

Параметр mode определяет режим работы библиотеки OpenGL и может принимать одно из трех значений:

Таблица 10.1. Возможные значения параметра mode команды RenderMode
Описание Значение
Библиотека OpenTK, C# Object Pascal
Режим выбора, данное значение используется для перевода библиотеки в режим выбора. RenderingMode.Select GL_SELECT
Режим формирования изображения сцены. Этот режим используется по умолчанию после инициализации библиотеки OpenGL. Именно в этом режиме выполняется формирование изображения библиотекой OpenGL. RenderingMode.Render GL_RENDER
Режим обратной связи. RenderingMode.Feedback GL_FEEDBACK

После переключения в режим выбора библиотека OpenGL не формирует изображение до тех пор, пока режим не будет изменен на режим формирования изображения сцены с помощью команды RenderMode со значением параметра RenderingMode.Render на C# и GL_RENDER на Object Pascal.

Именование и формирование объектов сцены

Как уже обсуждалось выше, в режиме выбора изображение не формируется. Команды формирования изображения в этом режиме используются для определения объектов, попадающих в область выбора.

Так как объекты, с которыми работает пользователь, обычно формируются из множества различных примитивов, то для определения выбранного объекта используется стек имен. Имена представляют собой целочисленные значения. Перед началом вывода очередного объекта в стек имен помещается имя (номер) этого объекта. Если при формировании объекта библиотека обнаруживает, что примитивы этого объекта попадают в область выбора, то содержание стека имен копируется в буфер выбора (вместе с некоторой дополнительной информацией), инициализированного с помощью команды SelectBuffer. При попадании в область сцены примитивов другого именованного объекта, содержание стека имен так же будет скопировано в буфер выбора. Таким образом, могут быть получены имена (номера) объектов, которые полностью или частично попали в область выбора. Необходимо учитывать, что для корректного определения выбранных объектов необходимо, чтобы координатные преобразования объектов, совпадали с теми, которые выполнялись при формировании изображения сцены.

Для работы со стеком имен используются несколько команд. Очистка стека имён выполняется с помощью команды InitNames:

C#:
  void InitNames();
Object Pascal:
  procedure glInitNames;

Помещение имени в стек выполняется с помощью команды PushName:

C#:
  void PushName(uint name);
Object Pascal:
  procedure glPushName(name: GLuint);

Имя передается в качестве параметра команды.

Удаление последнего имени из стека выполняется с помощью команды PopName:

C#:
  void PopName();
Object Pascal:
  procedure glPopName

Для замены последнего имени в стеке используется команда LoadName:

C#:
  void LoadName(uint name);
Object Pascal:
  procedure glLoadName(name: GLuint);

Новое имя передаётся команде в качестве параметра.

В режиме выбора при попадании примитива в сцену весь стек имен копируется в буфер выбора. Если сцена не очень сложная, то обычно в стеке имен располагают одно имя, соответствующее объекту. Если же сцена сложная, или необходимо отслеживать иерархические связи между объектами, то для обозначения объектов может использоваться несколько имен. Например, для автомобиля: колесо-болт-гайка. Ниже будет рассмотрен простой вариант, в котором для определения выбранного объекта используется только один элемент в стеке имен.

Перед использованием стека имен он должен быть инициализирован с помощью команды InitNames. Затем в стек необходимо поместить один элемент с помощью команды PushName. Перед формированием каждого из объектов единственный элемент стека имен будет заменяться на имя формируемого объекта с помощью команды LoadName. Процедура заменяет последний элемент в стеке имен на заданный в качестве параметра. Таким образом, инициализация и использование стека имен схематически можно представить следующим образом:

InitNames; 
PushName(0);
…
LoadName(1);
//формирование объекта № 1
LoadName(2);
//формирование объекта № 2
LoadName(3);
//формирование объекта № 3
//и т.д.
Листинг 10.7. Схема использования стека имен для выбора объектов
< Лекция 10 || Лекция 11: 123 || Лекция 12 >
Владислав Нагорный
Владислав Нагорный

Подскажите, пожалуйста, планируете ли вы возобновление программ высшего образования? Если да, есть ли какие-то примерные сроки?

Спасибо!

Лариса Парфенова
Лариса Парфенова

1) Можно ли экстерном получить второе высшее образование "Программная инженерия" ?

2) Трудоустраиваете ли Вы выпускников?

3) Можно ли с Вашим дипломом поступить в аспирантуру?