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 таким образом, чтобы она управлялась нажатием клавиши мыши - при нажатии левой клавиши- квадрат вращается, при нажатии правой клавиши- вращение прекращается.


 

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

46234. Основные системные группировки лексики в языке. Критерии классификации 14.36 KB
  функциональнограмматическая на основе частей речи 2. по стилистической характеристике – нейтральная межстилевая и стилистически маркированной высокой официальной научной – книжной речи разговорной и просторечной – устной речи. Общенародные слова – общеупотребительная лексика для всех говорящих на русском языке основная масса таких слов устойчива и употребительна во всех стилях речи.
46235. Понятие операции. Особенности конкретных операций 14.36 KB
  Понятие операции. На определенном этапе развития обобщенные схемы действий превращаются в операции операторные структуры поэтому концепция Пиаже называется операциональной. Операции это интериоризированные внутренние предметные действия ставшие обратимыми и сгруппированными в системы. Посредством обратной операции мысль может вернуться к начальному исходному моменту рассуждений.
46236. Исследование языковой семантики. Ономасиологический и семасиологический подходы 14.32 KB
  Таковы споры о происхождении значений слов и их отношений к бытию и мышлению ведущиеся аналогистами и аномалистами в древности и номиналистами реалистами концептуалистами в Средние века; Ономасиология отрасль семантики изучающая наименования использование языковых средств для обозначения внеязыковых объектов. основывается на движении от обозначаемого предмета к средствам его обозначения шире от содержания к форме. лингвистическом направлении слова и вещи прежде всего на материале романской диалектологии исследовавшей способы...
46237. Ж. Пиаже. «Комментарии к критическим замечаниям Л.С. Выготского на книги «Речь и мышление ребенка» и «Суждения и рассуждения ребенка» 14.27 KB
  Пиаже. Выготского на книги Речь и мышление ребенка и Суждения и рассуждения ребенка Пиаже обнаруживает через 25 лет после опубликования работу коллеги который уже умер. а те из работ Пиаже которые он обсуждает относятся к 1923 и 1924. Пиаже постарался увидеть оправдываются ли критические замечания Выготского в свете его позднейших работ.
46238. Грамматика как научная дисциплина. Основные подходы к изучению языковой грамматики. Виды и уровни языковой грамматики 14.26 KB
  Грамматический строй языка имеет свои категории и единицы словоформы и словообразовательные модели словосочетания и предложения. В русской грамматике выделяются именные морфологические категории рода одушевлённости неодушевлённости числа падежа степени сравнения; глагольные категории вида залога наклонения времени и лица; грамматическая форма внешнее языковое выражение грамматического значения в каждом конкретном случае употребления слова. Синтаксические категории = тип предложения – специфическая характеристика присущая только...
46239. НОИСТРУНТОРСНИЕ, ИЗМЕРИТЕЛЬНЫЕ И ТЕХНОЛОГИЯ ЕС HUE ВАЗЫ 14.23 KB
  Конструкторская база это база используемая для определения положения детали или сборочной единицы в изделии ГОСТ 21495 76. В обычной практике конструкторской работы конструкторской базой называется поверхность линия или точка детали по отношению к которым определяются на чертеже расчетные положения других деталей или сборочных единиц изделия^ а также других поверхностей и геометрических элементов данной детали. Основной называется конструкторская база принадлежащая дайной детали или сборочной единице...
46240. Структура лексического значения. Функциональный статус составляющих лексическое значение компонентов (денотативное и сигнификативное содержание значения) 14.17 KB
  Прямое значение слова – это непосредственная связь между звуковым комплексом и явлением действительности. Ядро лексического значения – концептуальное значение: а денотативный аспект выражает отношение содержания слова к предмету который оно означает. б сигнификативный аспект выражает отношение слова к понятию которое стоит за этим словом. г лингвистический аспект определяет место данного слова среди других единиц языка.
46241. Структуры. Действия со структурами. Передача структур в функции 14.1 KB
  Объявление структуры следует рассматривать как объявление типа. В C структуры заключают в себе не только данные но и код и относятся к средствам объектноориентированного программирования. Объявление структуры которая хранит сведения о журнале: название год номер.mgzinmg = { Nture 3 1995;Доступ к элементам структуры осуществляется по составному имени:имя_структуры.
46242. Проявление категории вежливости в русском языке. О социальных аспектах культуры речи 14.09 KB
  Проявление категории вежливости в русском языке. Принципу вежливости и его использованию в речи посвящено немало работ. Например Лакофф формулирует принцип вежливости в виде трех правил: не навязывай своего мнения предоставляй собеседнику возможность выбора будь доброжелательным Цель принципа вежливости – поддерживать социальное равновесие и такие социальноречевые отношения которые позволят результативно общаться При выражении вежливости большое значение играет взгляд. Средством выражения вежливости являются также модуляции голоса.