Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Chast_II_Osn_progr_trekhmernoy_grafiki.doc
Скачиваний:
2
Добавлен:
01.05.2025
Размер:
1.83 Mб
Скачать

2.1 Пример обработки события от мыши: изменение цвета вращающегося объекта по нажатию левой кнопки мыши

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

  1. Надо добавить в программу описание глобальной переменной, в который будет храниться порядковый номер текущего цвета (0/1/2/3 – желтый/красный/зеленый/синий):

int clr_number = 0;

  1. Значение переменной clr_number надо учесть в функции рисования трехмерной сцены, чтобы перед рисованием чайника устанавливался соответствующий цвет:

switch ( clr_number )

  {

  case 0 : glColor3f( 0.5, 0.5, 0 ); break;

  case 1 : glColor3f( 1, 0, 0 ); break;

  case 2 : glColor3f( 0, 1, 0 ); break;

  case 3 : glColor3f( 0, 0, 1 ); break;

  default : glColor3f( 1, 1, 1 ); break;

  }

  1. В раздел прототипов надо внести прототип обработчика события от мыши:

void CALLBACK mouse_leftbtn( AUX_EVENTREC* event );

  1. В функции-обработчике выполняется изменение номера текущего цвета:

void CALLBACK mouse_leftbtn( AUX_EVENTREC* event )

{

  if ( ++clr_number == 3 )

    clr_number = 0;

}

  1. Перед входом в главный цикл GLAUX надо зарегистрировать обработчик события "нажатие левой кнопки мыши":

auxMouseFunc( AUX_LEFTBUTTON, AUX_MOUSEDOWN, mouse_leftbtn );

3. Композиция нескольких преобразований

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

3.1 Модель солнечной системы

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

Оба тела рисуются в виде каркасных сфер, для отображения сцены применяется перспективная проекция (функция gluPerspective()).

Угловое движение планеты по орбите и вокруг собственной оси учитывается с помощью функции glRotated(). Для размещения планеты на орбите применяется функция glTranslated().

Центр сферы, изображающей солнце, находится в начале координат. Вращение солнца вокруг собственной оси не показывается (хотя это легко сделать с помощью функции glRotated()). Для рисования планеты, обращающейся вокруг солнца (рис. 2.1), требуется выполнить несколько модельных преобразований.

Рис. 2.1. Движение планеты по орбите и вокруг своей оси.

Для определения порядка модельных преобразований надо представить, что должно происходить с модельной системой координат. Сначала модельная система координат совпадает с мировой. В этом состоянии надо функцией glRotated() повернуть модельную систему координат относительно мировой системы на угол, соответствующий текущему положению планеты на орбите. Затем glTranslated() выполняет перенос модельной системы координат по радиусу орбиты. После этого выполняется еще один вызов glRotated(), поворачивающий модельную систему координат вокруг оси вращения планеты в соответствии с временем суток на планете. После выполнения всех трех преобразований, можно нарисовать планету.

Описанные преобразования выполняются в программе 2.2. Фоновой функции в этой программе нет, поэтому изменение времени производится клавишами курсора: увеличение/уменьшение времени суток с помощью стрелок вверх/вниз (на 1 час), дней – с помощью стрелок вправо/влево (на 1 день).

#include <windows.h>

#include <GL/gl.h>

#include <GL/glu.h>

#include <GL/glaux.h>

void CALLBACK resize( int width, int height );

void CALLBACK display();

void CALLBACK dayAdd();

void CALLBACK daySubtract();

void CALLBACK hourAdd();

void CALLBACK hourSubtract();

// Счетчики дней и часов

int day_cnt = 0, hour_cnt = 0;

void main()

{

  // Создание экранного окна

  auxInitDisplayMode( AUX_RGBA | AUX_DEPTH | AUX_DOUBLE );

  auxInitPosition( 50, 10, 400, 400);

  auxInitWindow( "Лекция 2, Программа 2.2" );

  // Включение ряда параметров OpenGL

  glEnable( GL_ALPHA_TEST ); // Учет прозрачности

  glEnable( GL_DEPTH_TEST ); // Удаление невидимых поверхностей

  glEnable( GL_COLOR_MATERIAL );

  glEnable( GL_BLEND ); // Разрешение смешения цветов

  glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

  glEnable( GL_LIGHTING ); // Учет освещения

  glEnable( GL_LIGHT0 ); // Включение нулевого источника света

  // Задание положения и направления нулевого источника света

  float pos[4] = { 5, 5, 5, 1 };

  float dir[3] = { -1, -1, -1 };

  glLightfv( GL_LIGHT0, GL_POSITION, pos );

  glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, dir );

  // Регистрация обработчиков событий

  auxReshapeFunc( resize );

  auxKeyFunc( AUX_LEFT, daySubtract );

  auxKeyFunc( AUX_RIGHT, dayAdd );

  auxKeyFunc( AUX_UP, hourAdd );

  auxKeyFunc( AUX_DOWN, hourSubtract );

  // Вход в главный цикл GLAUX

  auxMainLoop( display );

}

void CALLBACK resize( int width, int height )

{

  glViewport( 0, 0, width, height );

  glMatrixMode( GL_PROJECTION );

  glLoadIdentity();

  gluPerspective( 60.0, (float)width/(float)height, 1.0, 20.0 );

  gluLookAt( 0,0,5, 0,0,0, 0,1,0 );

  glMatrixMode( GL_MODELVIEW );

  glLoadIdentity();

}

void CALLBACK display(void)

{

  // Очистка буфера кадра

  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

  glColor3f( 1.0, 1.0, 1.0 );

  glPushMatrix();

    auxWireSphere( 1.0 ); // Солнце

    glRotated( (double)day_cnt*360.0/365.0, 0.0, 1.0, 0.0 );

    glTranslated( 2.0, 0.0, 0.0 );

    glRotated( (double)hour_cnt*360.0/24.0, 0.0, 1.0, 0.0 );

    auxWireSphere( 0.2 ); // Планета

  glPopMatrix();

  // Копирование содержимого буфера кадра на экран

  glFlush();

  auxSwapBuffers();

}

void CALLBACK dayAdd()

{

  day_cnt = (day_cnt + 1) % 360;

}

void CALLBACK daySubtract()

{

  day_cnt = (day_cnt - 1) % 360;

}

void CALLBACK hourAdd()

{

  hour_cnt = (hour_cnt + 1) % 24;

}

void CALLBACK hourSubtract()

{

  hour_cnt = (hour_cnt - 1) % 24;

}

Программа 2.2. Модель солнечной системы.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]