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


 

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

80987. Основні підходи до класифікації уроків історії 34.33 KB
  У цій класифікації розрізняють: уроки засвоєння нового навчального матеріалу; уроки формування і вдосконалення умінь та навичок; уроки закріплення та застосування знань умінь та навичок; уроки узагальнення та систематизації знань; уроки контролю і корекції знань вмінь та навичок; комбіновані уроки. Уроки вивчення нового навчального матеріалу. Уроки формування і вдосконалення вмінь та навичок. Уроки закріплення та застосування знань умінь та навичок передбачають наявність в учнів певної кількості попередньо засвоєних знань умінь та...
80989. Використання текстових джерел у процесі навчання 35.4 KB
  У процесі вивчення шкільного курсу історії використовуються текстові джерела. Це Історичні джерела що опрацьовуються на уроках історії. можна поділити джерела у три великі групи: речові історичні джерела або археологічні пам’ятки; писемні історичні джерела або історичні документи; візуальні історичні джерела. Речові історичні джерела або археологічні пам’ятки – матеріальні рештки діяльності людини чи змінене людською працею із слідами діяльності людини природне середовище.
80990. Навчально-виховні завдання вивчення історії в сучасних умовах розвитку середньої освіти 35.57 KB
  Вивчення історії є одним із найважливіших чинників формування національної свідомості народу. Без знання минулого неможливо точне поняття про сучасне За останні роки сформувався новий образ учителя історії. На наш погляд сучасному вчителю історії мають бути притаманні такі риси: Державницька свідомість.
80992. Поняття та сутність методики навчання історії 31.29 KB
  Метод спосіб досягнення мети розв\'язання конкретного завдання Ефективність і якість навчання історії залежить від того наскільки вчитель володіє методами навчання і застосовує їх на практиці. Початкові елементи методики навчання історії зародилися з введенням викладання предмета як відповідь на практичні питання про цілі викладання про відбір історичного матеріалу якому навчали учнів і прийоми його розкриття. Методика історії як наука пройшла складний шлях розвитку.
80993. Методика роботи з історичним документом 33.52 KB
  Як відомо, до історичних джерел належить все створене людиною, а також предмети матеріальної культури, звичаї, обряди, памятки писемності. У широкому сенсі памятки писемності в методиці називають документами.
80994. Загальна характеристика шкільної програми з історії. Принципи їх побудови 38.33 KB
  Типи навчальних програм: Навчальні програми можуть бути типовими робочі і авторськими. Типові державні навчальні програми з історії розробляються на основі державного освітнього стандарту. Тому виникає необхідність періодично оновлювати навчальні програми у відповідності з розвитком педагогічної науки і практики.
80995. Проблема інтерпретації навчальних текстів на уроках історії. Інтерпретація (лат. interpretatio) — розяснення, тлумачення — відносно історичних текстів та ін.. (наукових та літературних текстів) 34.86 KB
  Щоб запобігти некритичному сприйняттю учнями історичної інформації, недостатньо тільки навчити їх досліджувати джерела. Важливим є також розвиток вмінь аналізувати та критично оцінювати інтерпретацію минулого, що міститься в будь-якому джерелі