14572

Ввод и взаимодействие с пользователем и анимация Взаимодействие с пользователем в OpenGL

Лабораторная работа

Информатика, кибернетика и программирование

Лабораторная работа №3 Ввод и взаимодействие с пользователем и анимация Взаимодействие с пользователем в OpenGL Функции библиотеки GLUT реализуют так называемый событийноуправляемый механизм. Это означает что есть некоторый внутренний цикл который запускается

Русский

2013-06-08

50.5 KB

15 чел.

Лабораторная работа №3

Ввод и взаимодействие с пользователем и анимация

Взаимодействие с пользователем в OpenGL

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

void glutDisplayFunc (void (*func) (void))

void glutReshapeFunc (void (*func) (int width, int height))

void glutMouseFunc (void (*func) (int button, int state, int x, int y))

void glutIdleFunc (void (*func) (void))

void glutKeyboardFunc(void (*func)(unsigned int key, int x, int y)

void glutMotionFunc(void (*func)(int x, int y));

void glutKeyboardFunc(void (*func)(unsigned int key, int x, int y);

 Определяет функцию (func), которая вызывается, когда нажата клавиша на клавиатуре. Возвращаемые параметры:

 key - сгенерированный клавиатурой ASCII код;

x,y – лоординаты положения мыши в координатах отображаемого окна, в момент, когда была нажата кнопка на клавиатуре.

void glutMouseFunc(void (*func)(int button, int state, int x, int y));

Определяет функцию, func, которая вызывается, когда кнопка мыши нажата или отпущена. Возвращаемый функцией параметр button может принимать значения GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, или GLUT_RIGHT_BUTTON. Значение параметра  state есть GLUT_UP или GLUT_DOWN в зависимости от того была ли кнопка мыши нажата или отпущена,  x and y параметры указывают на координаты в текущем окне, где находилась мышь в момент нажатия или отпускания кнопки.

void glutMotionFunc(void (*func)(int x, int y));

Определяет функцию, func, которая вызывается, когда указатель мыши перемещается в пределах окна принажатой одной или более кнопки, x and y параметры указывают на координаты в текущем окне, где находилась мышь в момент  начала события

void glutPostRedisplay(void);

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

void glutIdleFunc (void (*func) (void))

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

Видовое преобразование

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

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

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

void glTranslate[f d](GLtype x, GLtype y, GLtype z)

void glRotate[f d](GLtype angle, GLtype x, GLtype y, GLtype z)

void glScale[f d](GLtype x, GLtype y, GLtype z)

glTranlsate..() производит перенос объекта, прибавляя к координатам его вершин значения своих параметров.

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

glScale..() производит масштабирование объекта (сжатие или растяжение), домножая соответствующие координаты его вершин на значения своих параметров.

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

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

void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz)

где точка ( eyex,eyey,eyez ) определяет точку наблюдения, ( centerx, centery, centerz )задает центр сцены, который будет проектироваться в центр области вывода, а вектор ( upx,upy,upz ) задает положительное направление оси у, определяя поворот камеры. Если, например, камеру не надо поворачивать, то задается значение (0,1,0), а со значением (0,-1,0) сцена будет перевернута.

Фактически, эта команда совершает перенос и поворот объектов сцены, но в таком виде задавать параметры бывает удобнее.

Анимация

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

Эту проблему можно решить с использованием двойной буферизации- стандартной технологии организации компьютерной анимации. В этом случае в нашем распоряжении имеется два буфера кадра, которые принято называть рабочим и фоновым. Рабочий буфер- это тот, из которого выполняется регенерация изображения на экране, а в фоновом буфере изображение формируется программой. По командам из прикладной программы можно переключать функции буферов: сделать рабочим тот, который ранее был фоновым, а фоновым- тот, который ранее был рабочим. Механизм двойной буферизации устанавливается в процессе инициализации аргументом функции glutInitDisplayMode(). Вместо константы GLUT_SINGLE нужно задать константу GLUT_DOUBLE. Переключение буферов выполняется функцией glutSwapBuffers(). Все операторы формирования изображения включатся в функцию display(), но при использовании этой двойной буферизации в этой функции сначала нужно очистить рабочий буфер, вызвав команду glClear(), а последним оператором вызвать функцию переключения буферов glutSwapBuffers().

Структура приложения, использующего анимацию, будет следующей:

#include <GL/glut.h>
void MyIdle(void){
//--Код, который меняет переменные, определяющие следующий кадр--//
....
};
void
display(void){
//--Код OpenGL, который отображает кадр --//
....
//-- После рисования переставляем буфера --//
glutSwapBuffers();
};
void main(int argcp, char **argv){
//-- Инициализация GLUT --//
glutInit(&argcp, argv);
glutInitWindowSize(640, 480);
glutInitWindowPosition(0, 0);
//--Открытие окна--//
glutCreateWindow("My OpenGL Application");
//-- Выбор режима:Двойной буфер и RGBA цвета --//
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
//-- Регистрация вызываемых функций --//
glutDisplayFunc(
display);
glutIdleFunc(MyIdle);
//-- Запуск механизма обработки событий --//
glutMainLoop();

}

Программа рисования вращающегося квадрата

#include <GL/glut.h>

#include <stdlib.h>

static GLfloat spin = 0.0;

void spinDisplay(void)

{

   spin = spin + 2.0;

  if (spin > 360.0)

     spin = spin - 360.0;

  glutPostRedisplay();

}

void display(void)

{

  glClear(GL_COLOR_BUFFER_BIT);

  glPushMatrix();

  glRotatef(spin, 0.0, 0.0, 1.0);

  glColor3f(1.0, 1.0, 1.0);

  glBegin(GL_POLYGON);

glVertex2f(-25.0,-25.0);

glVertex2f(25.0,-25.0);

glVertex2f(25.0,25.0);

glVertex2f(-25.0,25.0);

glEnd( );

  glPopMatrix();

  glutSwapBuffers();

}

void init(void)

{

  glClearColor (0.0, 0.0, 0.0, 0.0);

  glShadeModel (GL_FLAT);

}

void reshape(int w, int h)

{

  glViewport (0, 0, (GLsizei) w, (GLsizei) h);

  glMatrixMode(GL_PROJECTION);

  glLoadIdentity();

  glOrtho(-50.0, 50.0, -50.0, 50.0, -1.0, 1.0);

  glMatrixMode(GL_MODELVIEW);

  glLoadIdentity();

}

int main(int argc, char** argv)

{

  glutInit(&argc, argv);

  glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);

  glutInitWindowSize (250, 250);

  glutInitWindowPosition (100, 100);

  glutCreateWindow (argv[0]);

  init ();

  glutDisplayFunc(display);

  glutReshapeFunc(reshape);

  glutIdleFunc(spinDisplay);

  glutMainLoop();

  return 0;   /* ANSI C requires main to return int. */

}

Порядок выполнения лабораторной работы

  1.  Ввести и отладить программу рисования вращающегося квадрата.
  2.  Изменить программу п.1 таким образом, чтобы она управлялась нажатием клавиш на клавиатуре- при нажатии клавиши “x”, квадрат вращается, при нажатии клавиши “X”- вращение прекращается, при нажатии клавиши “Esc”- программа завершает своя работу.
  3.  Изменить программу п.1 таким образом, чтобы она управлялась нажатием клавиши мыши - при нажатии левой клавиши- квадрат вращается, при нажатии правой клавиши- вращение прекращается.


 

А также другие работы, которые могут Вас заинтересовать

23656. Семантические сети 170 KB
  Семантические сети Семантической сетью является структура данных имеющая определенный смысл как сеть. Стандартного определения семантической сети не существует но обычно под ней подразумевают следующее: Семантическая сеть это система знаний имеющая определенный смысл в виде целостного образа сети узлы которой соответствуют понятиям и объектам а дуги отношениям между объектами. Следовательно всевозможные сети можно рассматривать как сети входящие в состав семантической сети. Поэтому в контексте знакомства с СОЗ семантические сети...
23657. Продукционные модели. ЕСЛИ - ТО (явление - реакция) 166 KB
  Эти две отличительные черты и определили широкое распространение методов представления знаний правилами. Программные средства оперирующие со знаниями представленными правилами получили название продукционных систем или систем продукции и впервые были предложены Постом в 1941 году. Общим для систем продукции является то что они состоят из трех элементов: Набор правил используемых как БЗ его еще называют базой правил; Рабочая память где хранятся предпосылки касающиеся отдельных задач а также результаты выводов получаемых на основе...
23658. Представление знаний с применением фреймов 143.5 KB
  Понятие фрейма и слота В сложных семантических сетях включающих множество понятий процесс обновления узлов и контроль связей между ними становится затруднительным. В каждом узле понятия определяются набором атрибутов и их значениями которые содержатся в слотах фрейма. Слот это атрибут связанный с узлом в системе основанной на фреймах. Слот является составляющей фрейма.
23659. Стратегии поиска в СОЗ 105.5 KB
  7 Начальныесостояния Цель конечные состояния Реализует возможность выбора Выполняет шаги от начального состояния к новым более близким к цели Исходные посылки и факты Поиск Стратегия поиска B A C C A B A B C A B C C B A B C A B A C C A B A B C C A B B A C A B C A C B 8. Стратегии поиска в СОЗ 8. Поиск в СОЗ Причем поиск конечного состояния выполняется автоматически на основе реализованной в СОЗ стратегии поиска которая: реализует возможность выбора; позволяет выполнять шаги от начального...
23660. Нечеткие множества в системах основанных на знаниях 462.5 KB
  Для ее решения вводится два показателя: П АiФ = sup min фu Aiu это возможность что нечеткое множество Ф принадлежит значению Аi атрибута Ã. Рассмотрим геометрическую интерпретацию определения ПА1Ф: min фu A1u представляет собой треугольник SQR т. sup min фu A1u это точка Q т. Тогда ПА1Ф = min {max 0 min 1 1 m1 m2 1 2 max 0 min 1 1 m2 m1 2 1 }.
23661. Основы построения систем основанных на знаниях (Соз) 68 KB
  Предположим нас интересует что имеет Иван: Запрос: имеет иван Вещь Ответ: Вещь = машина Если мы заполним базу еще рядом фактов имеет петр руб.500 имеет петр телевизор цена видео 4200 цена приемник 20 цена часы 70 тогда на аналогичный запрос но только относительно Петра мы получим ответ: Запрос: имеет петр Вещь Ответ: Вещь = часы Вещь = руб 500 Вещь = телевизор Заметим что имя петр мы вводим со строчной буквы так как это атом; а Вещь является переменной и записывается с заглавной буквы. Чтобы не...
23662. Экспертные системы. Назначения ЭС и основные требования к ним 78 KB
  Экспертные системы Система основанная на знаниях система программного обеспечения основными структурными элементами которой являются базы знаний и механизм логических выводов. Основными требованиями к ЭС являются: использование знаний связанно с конкретной предметной областью; приобретение знаний от эксперта; определение реальной и достаточно сложной задачи; наделение системы способностями эксперта. которые обладают общими качествами: имеют огромный багаж знаний о конкретной предметной области; имеют большой опыт работы в этой...
23663. Приобретение и формализация Знаний 465 KB
  Одной из них является чтректура получившая название дерево решений. Вместе с тем использование дерева решений может быть эффективно там где знания представляются в виде правил. Структура дерева решений иллюстрирует отношения которые должны быть установлены между правилами в хорошо организованной БЗ. Представление знаний в виде дерева решений Базируясь на знаниях эксперта графически диаграмму всех возможных исходов данной консультации можно представить в виде рис.
23664. Представление знаний с использованием логики предикатов 337.5 KB
  S2: получает студент стипендию  сдает успешно сессию студент S3: сдает успешно сессию студент Задача которую надо решить состоит в том чтобы ответить на запрос получает ли студент стипендию Когда используется обычная система логического вывода то такой вопрос представляется в виде отрицания S:  получает студент стипендию и система должна отвергнуть это отрицание при помощи других предложений демонстрируя что данное допущение ведет к противоречию. ШАГ 1 Система на первом шаге применит правило к родительским...