Всего на сайте:
303 тыс. 117 статей

Главная | Информатика

Библиотека PyOpenGL  Просмотрен 60

Библиотека PyOpenGL – модуль, позволяющий работать с функциями OpenGL, GLU и GLUT, а также с рядом расширений OpenGL в программах на языке Python.

К характерным особенностям OpenGL, можно отнести:

· Стабильность. Изменения в стандарте реализуются специально так, чтобы сохранить уже имеющуюся совместимость с программным обеспечением, разработанным ранее.

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

· Легкость применения. Стандарт OpenGL имеет продуманную структуру и интуитивно понятный интерфейс. Это позволяет создавать довольно эффективные приложения. А необходимые функции для обеспечения совместимости с различным оборудованием реализованы на уровне библиотеки и значительно упрощают разработку приложений такого вида.

На рисунке схематически представлена организация системы библиотек в версии, работающей под управлением системы Windows. Аналогичная организация используется и в других версиях OpenGL.

В GLU вошла реализация некоторых функций, таких как геометрические примитивы (например, куб, шар, цилиндр, диск), операции над матрицами и т.п.

Однако OpenGL не включает специальных команд для работы с окнами или для ввода пользователем информации. Поэтому были созданы специальные переносимые библиотеки для часто используемых функций взаимодействия с пользователем и для отображения информации с помощью оконной подсистемы. Например библиотека GLUT (GL Utility Toolkit).

GL обрабатывает и рисует в буфере кадра графические примитивы с учетом выбранных режимов. Примитив – это точка, отрезок, многоугольник и т.д. Режим может быть изменен независимо от других. Определение примитивов, выбор режимов и другие операции описываются с помощью команд в форме вызовов функций прикладной библиотеки. Примитивы определяются набором из одной или более вершин (vertex). Вершина определяет точку, конец отрезка или угол многоугольника.

Вершина определяется некоторыми атрибутами (координаты, цвет, нормаль, текстурные координаты и т.д.).

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

Для работы с OpenGL нужно загрузить пакеты из сети Интернет, после чего распаковать и установить.

Для обеспечения интуитивно понятных названий в библиотеке PyOpenGL полное имя команды имеет вид:

Type glCommand_name[1 2 3 4][b s i f d ub us ui][v](type1 arg1,…,typeN argN)

Таким образом, имя состоит из нескольких частей:

gl – это имя библиотеки, в которой описана эта функция: для базовых функций OpenGL, функций из библиотек GLU, GLUT, GLAUX это gl, glu, glut, aux соответственно.

Command_name – имя команды.

[1 2 3 4] – число аргументов команды.

[b s i f d ub us ui ] – тип аргумента (прототипы привычных нам b – Glbyte, f – Glfloat и т.д.)

[v] - наличие этого символа показывает, что в качестве параметров функции используется указатель на массив значений.

Рассмотрим некоторые особенности синтаксиса модуля PyOpenGL. Начнём с особенностей GLUT.

Функции GLUT можно разделить на несколько групп по своему назначению, а именно:

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

Инициализация производится с помощью функции glutInit(), выполняющая начальные действия для построения окна приложения. Несколько следующих функций GLUT могут вызваться до нее:

glutInitWindowPosition(int x, int y) – определение позиции верхнего левого края экрана окна приложения;

glutInitWindowSize(int width, int height) – определение высоты и ширины окна приложения;

glutInitDisplayMode(unsigned int mode) – определяет различные режимы отображения информации.

Некоторые варианты режимов отображения:

GLUT_RGBA – режим RGBA, используемый по умолчанию, который может быть заменен на GLUT_INDEX.

GLUT_INDEX– режим индексированных цветов (использование палитры). Отменяет GLUT_RGBA.

GLUT_SINGLE – окно с одиночным буфером, используемый по умолчанию.

GLUT_DOUBLE– окно с двойным буфером. Отменяет GLUT_SINGLE. Обычно используется для анимации, сначала рисуют что-нибудь в одном буфере, а затем меняют их местами, что позволяет избежать мерцания.

GLUT_DEPTH – окно с буфером глубины или z-буфером, удаляющий невидимые линии и поверхности.

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

glutDisplayFunc() – задается функция рисования для окна приложения, вызвающая создание или восстановление изображения.

glutReshapeFunc () – функция изменяющая размер окна пользователем.

glutMouseFunc () – определяет обработчика команд от мыши.

glutIdleFunc() – вызывается каждый раз, когда нет событий от пользователя.

Контроль всех событий происходит внутри бесконечного цикла в функции glutMainLoop(), которая, как правило, вызывается в конце любой программы, использующей GLUT.

В библиотеке PyOpenGL под вершиной понимается точка в трехмерном пространстве, координаты которой можно задавать с помощью следующей функции: glVertex[2 3 4][s i f d] (type coords).

Координаты точки задаются максимум четырьмя значениями: x, y, z, w, при этом можно указывать два (x,y) или три (x,y,z) значения, а для остальных переменных в этих случаях используются значения по умолчанию: z=0, w=1. Как уже было сказано выше, число в названии команды соответствует числу явно задаваемых значений, а последующий символ – их типу.

Координатные оси расположены таким образом, что точка (0,0) лежит в левом нижнем углу экрана, ось x направлена влево, ось y – вверх, ось z – из экрана.

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

glBegin(GLenum mode) glEnd()

Параметр mode определяет тип примитива, который задается внутри и может принимать следующие значения:

GL_POINTS – каждая вершина задает координаты некоторой точки.

GL_LINES – каждая отдельная пара вершин определяет отрезок, при этом если задано нечетное число вершин, то последняя вершина будет игнорироваться.

GL_LINE_STRIP – каждая следующая вершина задает отрезок вместе с предыдущей.

GL_LINE_LOOP – каждая следующая вершина задает отрезок вместе с предыдущей и последний отрезок определяется последней и первой вершиной, образуя замкнутую ломаную.

GL_TRIANGLES – каждая отдельная тройка вершин определяет треугольник, и если задано не кратное трём число вершин, то последние вершины будут игнорироваться.

GL_TRIANGLE_STRIP – каждая следующая вершина задает треугольник вместе с двумя предыдущими.

GL_QUADS – каждая отдельная четверка вершин определяет четырехугольник, при этом если задано не кратное четырем число вершин, то последние вершины будут игнорироваться.

GL_POLYGON – последовательно задаются вершины выпуклого многоугольника.

Для задания цвета вершины используются команда glColor[3 4][b s i f] (GLtype components), где первые три параметра задают R, G, B компоненты цвета, а последний параметр определяет значение, которое задает уровень прозрачности объекта.

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

Для задания цвета фона используется команда glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha). Значения должны находиться в отрезке [0,1] и по умолчанию равны нулю.

После этого вызов команды glClear(GLbitfield mask) с параметром GL_COLOR_BUFFER_BIT устанавливает цвет фона во все буфера, доступные для записи цветов.

Кроме цвета аналогичным образом можно определить нормаль в вершине, используя команду glNormal3[b s i f d](type coords). Причём задаваемый вектор может и не иметь единичной длины, но всё же он будет нормироваться автоматически в режиме нормализации, который включается вызовом команды glEnable(GL_NORMALIZE) и отключается командой glDisable(GLenum mode).

Существуют более сложные фигуры: сфера, цилиндр, диск (в GLU) и сфера, куб, конус, тор, тетраэдр, додекаэдр, икосаэдр, октаэдр и чайник (в GLUT).

В PyOpenGL в качестве основных используются три системы координат: левосторонняя, правосторонняя и оконная. Первые две системы являются трёхмерными и отличаются друг от друга всего лишь направлением оси z, то есть в правосторонней это ось направлена из экрана, а в левосторонней – в обратную сторону. Расположение осей x и y аналогично описанному выше. Левосторонняя система используется для задания значений параметрам команды gluPerspective(), glOrtho(), а правосторонняя или мировая система координат во всех остальных случаях. Отображение трехмерной информации происходит в двумерную оконную систему координат.

Для задания различных преобразований объектов используются операции над матрицами, при этом существуют три типа матриц: видовая матрица, матрица проекций и матрица текстуры. Каждая имеет размер 4x4. Видовая матрица определяет преобразования объекта в мировых координатах, такие как параллельный перенос, изменение масштаба и поворот. Матрица проекций задаёт, как именно будут проецироваться трёхмерные объекты на плоскость экрана (в оконные координаты), а матрица текстуры определяет наложение текстуры на объект.

Для переноса точки в новое положение необходимо добавить к ее координатам некоторые числа, которые представляют собой координаты вектора переноса:

Матрица трехмерного переноса аналогична двумерному случаю:

, при этом

.

Для точек и можно представить операцию масштабирования следующим образом:

В трех мерном случае Операция масштабирования:

Поворот точки А на угол относительно начала координат выглядит следующим образом:

При двумерном повороте в плоскости координаты остаются неизменными, то поворот вокруг оси записывается так:

.

Матрица поворота вокруг оси имеет вид:

,

и вокруг оси :

Чтобы выбрать, какую именно матрицу следует изменить, нужно использовать команду glMatrixMode(GLenum mode), вызов которой со значением параметра mode равным GL_MODELVIEW, GL_PROJECTION, GL_TEXTURE включает режим работы с видовой матрицей, матрицей проекций и матрицей текстуры соответственно. Для вызова команд, задающих матрицы того или иного типа необходимо сначала установить соответствующий режим.

Для определения элементов матрицы текущего типа вызывается команда glLoadMatrix[f d] (GLtype *m), где m указывает на массив из 16 элементов типа float или double в соответствии с названием команды, при этом сначала в нем должен быть записан первый столбец матрицы, затем второй, третий и четвертый.

Команда glLoadIdentity(void) заменяет текущую матрицу на единичную. Часто нужно сохранить содержимое текущей матрицы для дальнейшего использования, для чего используют команды glPushMatrix(void) и glPopMatrix(void). Они записывают и восстанавливают текущую матрицу из стека, причем для каждого типа матриц стек свой.

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

(x’, y’, z’, 1)T = M * (x, y, z, 1),T

где M – матрица видового преобразования. Перспективное преобразование и проектирование производится аналогично.

Сама матрица может быть создана с помощью следующих команд:

glTranslate[f d](GLtype x, GLtype y, GLtype z) – производит перенос объекта, прибавляя к координатам его вершин значения своих параметров.

glRotate[f d](GLtype angle, GLtype x, GLtype y, GLtype z) – производит поворот объекта против часовой стрелки на угол angle (измеряется в градусах) вокруг вектора ( x,y,z ).

glScale[f d](GLtype x, GLtype y, GLtype z) - производит масштабирование объекта (сжатие или растяжение), умножая соответствующие координаты его вершин на значения своих параметров.

В случае если надо, например, повернуть один объект сцены, а другой оставить неподвижным, удобно сначала сохранить текущую видовую матрицу в стеке командой glPushMatrix(), затем вызвать glRotate() с нужными параметрами, описать примитивы, из которых состоит этот объект, а затем восстановить текущую матрицу командой glPopMatrix().

В рассматриваемой библиотеке существуют ортографическая (параллельная) и перспективная проекция.

Первый тип проекции может быть задан командами:

glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far) – команда создает матрицу проекции в усеченный объем видимости (параллелограмм видимости) в левосторонней системе координат. Параметры команды задают точки (left, bottom, -near) и (right, top, -near), которые отвечают левому нижнему и правому верхнему углам окна вывода. Параметры near и far задают расстояние до ближней и дальней плоскостей отсечения по дальности от точки (0,0,0) и могут быть отрицательными.

gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top)- в этой команде, в отличие от первой, значения near и far устанавливаются равными –1 и 1 соответственно.

Перспективная проекция определяется командой:

gluPerspective(GLdouble angley, GLdouble aspect, GLdouble znear, GLdouble zfar) – она задает усеченный конус видимости в левосторонней системе координат. Параметр angley определяет угол видимости в градусах по оси у и должен находиться в диапазоне от 0 до 180. Угол видимости вдоль оси x задается параметром aspect, который, как правило, задается как отношение сторон области вывода. Два параметра zfar и znear задают расстояние от наблюдателя до плоскостей отсечения по глубине и должны быть положительными.

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

На следующем рисунке представлена слегка упрощенная схема трех моделей освещенности граней в OpenGL.

Можно рассмотреть три модели освещенности:

1. Модель, в которой используется только цвет вершины, который приписывается каждой вершине при ее создании.

2. Модель, в которой цвет вершины взаимодействует с цветом источника света.

3. Модель, в которой цвет источника света взаимодействует со свойствами материала поверхности. Цвет вершины при этом игнорируется.

Добавить источник света можно с помощью команды glLight[i f](GLenum light, GLenum pname, GLfloat param). Параметр light определяет источник и выбирается из набора специальных символических имен вида GL_LIGHTi, где i должно лежать в диапазоне от 0 до GL_MAX_LIGHT, которое не превосходит восьми.

Как правило, в библиотеке PyOpenGL используется модель освещения Фонга, согласно которой цвет точки определяется несколькими факторами: свойствами материала и текстуры, величиной нормали в этой точке, а также положением источника света и наблюдателя. Для корректного расчета освещенности в точке надо использовать единичные нормали, но всё же команды типа glScale(), могут изменять их длину. Чтобы это учитывать, используется уже упоминавшийся режим нормализации нормалей, который включается вызовом команды glEnable(GL_NORMALIZE).

Для задания глобальных параметров освещения используется команда glLightModel[i f](GLenum pname, GLenum param), где аргумент pname определяет, какой параметр модели освещения будет настраиваться.

Рассмотрим стандартные команды построения примитивов.

Для построения нужного примитива следует произвести вызов соответствующей команды.

glutSolidSphere(GLdouble radius, GLint slices, GLint stacks) – строит сферу.

glutWireSphere(GLdouble radius, GLint slices, GLint stacks) – каркас сферы радиусом radius.

glutSolidCube(GLdouble size) – строит куб.

glutWireCube(GLdouble size) – строит каркас куба с центром в начале координат и длиной ребра size.

glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks) - строит конус.

glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks) – строит каркас конуса высотой height и радиусом основания base, расположенный вдоль оси z. Основание находится в плоскости z=0.

glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings) - команда строит тор.

glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint nsides, GLint rings) – строит каркас тора в плоскости z=0. Внутренний и внешний радиусы задаются параметрами innerRadius, outerRadius. Параметр nsides задает число сторон в кольцах, составляющих ортогональное сечение тора, а rings- число радиальных разбиений тора.

glutSolidTetrahedron(void) – строит тетраэдр (правильную треугольную пирамиду).

glutWireTetrahedron(void) – строит его каркас, при этом радиус описанной сферы вокруг него равен 1.

glutSolidOctahedron(void) – команда строит октаэдр.

glutWireOctahedron(void) – его каркас, радиус описанной вокруг него сферы равен 1.

glutSolidDodecahedron(void) – строит додекаэдр.

glutWireDodecahedron(void) – его каркас, радиус описанной вокруг него сферы равен квадратному корню из трёх.

glutSolidIcosahedron(void) – строит икосаэдр.

glutWireIcosahedron(void) – его каркас, радиус описанной сферы равен 1.

Предыдущая статья:Движение мышки Следующая статья:Пример 1., importsys fromOpenGL.GLUT import* fromOpenGL.GL import* # Инициализ..
page speed (0.0329 sec, direct)