
- •Часть II. Основы программирования
- •Введение
- •Лекция 1. Библиотека OpenGl
- •1. Назначение библиотеки OpenGl
- •2. Основные возможности OpenGl
- •3. Макет консольного приложения, использующего библиотеку glaux
- •Программа 1.1
- •4. Имена функций OpenGl
- •5. Системы координат
- •5.1 Матрицы преобразований
- •5.2 Видовые и модельные преобразования
- •5.3 Проекционное преобразование
- •5.4 Оконное преобразование
- •6. Пример выполнения модельных преобразований
- •6.1 Параллельный перенос
- •Фрагмент программы 1.2
- •6.2 Поворот
- •Фрагмент программы 1.3
- •7. Сводка результатов
- •8. Упражнения Упражнение 1
- •Упражнение 2
- •Упражнение 3
- •Упражнение 4
- •Упражнение 5
- •Упражнение 6
- •Лекция 2. Генерация движущихся изображений
- •1. Анимация с двойной буферизацией
- •2. Обработка событий клавиатуры и мыши
- •2.1 Пример обработки события от мыши: изменение цвета вращающегося объекта по нажатию левой кнопки мыши
- •3. Композиция нескольких преобразований
- •3.1 Модель солнечной системы
- •3.2 Модель манипулятора робота
- •4. Сводка результатов
- •5. Упражнения Упражнение 1
- •Упражнение 2
- •Упражнение 3
- •Упражнение 4
- •Упражнение 5
- •Лекция 3. Геометрические примитивы
- •1. Служебные графические операции
- •1.1 Очистка окна
- •1.2 Задание цвета
- •1.3 Удаление невидимых поверхностей
- •2. Описание точек, отрезков и многоугольников
- •2.1 Точки
- •2.2 Отрезки
- •2.3 Многоугольники
- •2.4 Прямоугольники
- •2.5 Кривые
- •2.6 Задание вершин
- •2.7 Геометрические примитивы OpenGl
- •3. Свойства точек, отрезков и многоугольников
- •3.1 Точки
- •3.2 Отрезки
- •3.3 Многоугольники
- •4. Сводка результатов
- •Лекция 4. Полигональная аппроксимация поверхностей
- •1. Векторы нормали
- •2. Некоторые рекомендации по построению полигональных аппроксимаций поверхностей
- •3. Пример: построение икосаэдра
- •3.1 Вычисление нормалей к граням икосаэдра
- •3.2 Повышение точности аппроксимации сферической поверхности
- •3.3 Алгоритм разбиения треугольной грани произвольной поверхности
- •4. Плоскости отсечения
- •6. Сводка результатов
- •7. Упражнения Упражнение 1
- •Упражнение 2
- •Упражнение 3
- •Упражнение 4
- •Лекция 5. Цвет и освещение
- •1. Цветовая модель rgb
- •2. Задание способа закраски
- •3. Освещение
- •4. Освещение в реальном мире и в OpenGl
- •4.1 Излучаемый, рассеянный, диффузно отраженный и зеркально отраженный свет
- •4.2 Цвет материала
- •4.3 Значения rgb для источников света и материалов
- •5. Пример: рисование освещенной сферы
- •5.1 Вектора нормали в вершинах объектов
- •5.2 Создание, расположение и включение источников света
- •5.3 Выбор модели освещения
- •5.4 Задание свойств материалов для объектов сцены
- •6. Создание источников света
- •6.1 Цвет
- •6.2 Местоположение и затухание
- •6.3 Прожекторы
- •6.4 Использование нескольких источников света
- •6.5 Изменение местоположения источников света
- •4. Сводка результатов
- •Лекция 6. Свойства материала и спецэффекты освещения
- •1. Задание свойств материала
- •1.1 Диффузное и рассеянное отражение
- •1.2 Зеркальное отражение
- •1.3 Излучаемый свет
- •1.4 Изменение свойств материала
- •1.5 Имитация реальных материалов
- •2. Смешение цветов и прозрачность
- •2.1 Множители source (исходный пиксел) и destination (результирующего пиксела)
- •2.2 Области применения смешения цветов
- •2.3 Пример использования смешения цветов
- •3. Туман
- •3.1 Использование тумана
- •4. Сводка результатов
- •5. Упражнения Упражнение 1
- •2. Назначение текстур
- •3. Создание текстуры в оперативной памяти
- •4. Автоматическое повторение текстуры на плоском многоугольнике
- •5. Наложение текстуры на произвольную поверхность
- •6. Сводка результатов
- •7. Упражнения Упражнение 1
- •Упражнение 2
- •Задание 1.1
- •2. Объемный "тетрис"
- •Задание 2.1
3.2 Модель манипулятора робота
Манипулятор робота на экране изображается в виде нескольких каркасных параллелепипедов (по одному для каждого сегмента манипулятора – "плечо", "локоть", "кисть", "пальцы"). Предполагается, что в местах соединения сегментов расположены шарниры и сегменты могут вращаться вокруг них. На рис. 2.2 и рис. 2.3 показаны манипуляторы с разным количеством сегментов.
|
|
Рис. 2.2. Двухсегментный манипулятор. |
Рис. 2.3. Манипулятор из 10 сегментов (плечо, локоть и 4 пальца). |
Перед рисованием каждого сегмента надо выполнить модельное преобразование, обеспечивающее корректную ориентацию сегмента. При рисовании параллелепипеда его центр располагается в начале модельной системы координат, поэтому предварительно надо сместить модельную систему координат на половину длины сегмента. Если этого не сделать, то сегмент будет вращаться вокруг своего центра, а не вокруг шарнира.
После вызова glTranslated(), который задает положение шарнира, надо вызвать glRotated() для поворота сегмента. После этого надо выполнить перенос в обратном направлении для правильного позиционирования центра сегмента. В целом, для рисования одного сегмента надо вызвать следующие функции:
glTranslatef( -1.0, 0.0, 0.0 );
glRotatef( (float)shoulder_angle, 0.0, 0.0, 1.0 );
glTranslatef( 1.0, 0.0, 0.0 );
auxWireBox( 2.0, 0.4, 1.0 );
Для рисования второго сегмента надо переместить модельную систему координат в позицию второго шарнира. Т.к. координатная система уже была повернута, то ось X направлена в направлении первого сегмента. Следовательно, для переноса модельной системы координат в точку второго шарнира надо произвести перенос вдоль оси X. После этого можно нарисовать второй сегмент (функциями, аналогичными использованным для рисования первого сегмента):
glTranslatef( 1.0, 0.0, 0.0 );
glRotatef( (float)elbow_angle, 0.0, 0.0, 1.0 );
glTranslatef( 1.0, 0.0, 0.0 );
auxWireBox( 2.0, 0.4, 1.0 );
Описанную процедуру можно продолжать повторять, чтобы нарисовать все сегменты манипулятора (плечо, локоть, кисть, пальцы). Рисование двух сегментов манипулятора с двумя степенями свободы показано в программе 2.3. Поворот сегментов осуществляется с помощью клавиш курсора.
#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 elbowAdd();
void CALLBACK elbowSubtract();
void CALLBACK shoulderSubtract();
void CALLBACK shoulderAdd();
// Текущие углы поворота плеча и локтя
int shoulder = 0, elbow = 0;
void main()
{
// Создание экранного окна
auxInitDisplayMode( AUX_RGBA | AUX_DEPTH | AUX_DOUBLE );
auxInitPosition( 50, 10, 400, 400);
auxInitWindow( "Лекция 2, Программа 2.3" );
// Включение ряда параметров 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 );
// Включение максимального рассеянного освещения
float ambient[4] = { 1.0, 1.0, 1.0, 1 };
glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
// Регистрация обработчиков событий
auxReshapeFunc( resize );
auxKeyFunc( AUX_LEFT, shoulderSubtract );
auxKeyFunc( AUX_RIGHT, shoulderAdd );
auxKeyFunc( AUX_UP, elbowAdd );
auxKeyFunc( AUX_DOWN, elbowSubtract );
// Вход в главный цикл 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,10, 0,0,0, 0,1,0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
void CALLBACK display()
{
// Очистка буфера кадра
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glColor3f( 1.0, 1.0, 1.0 );
glPushMatrix();
glTranslatef( -1.0, 0.0, 0.0 );
glRotatef( (float)shoulder, 0.0, 0.0, 1.0 );
glTranslatef( 1.0, 0.0, 0.0 );
auxWireBox( 2.0, 0.4, 1.0 ); // плечо
glTranslatef( 1.0, 0.0, 0.0 );
glRotatef( (float)elbow, 0.0, 0.0, 1.0 );
glTranslatef( 1.0, 0.0, 0.0 );
auxWireBox( 2.0, 0.4, 1.0 ); // локоть
glPopMatrix();
// Копирование содержимого буфера кадра на экран
glFlush();
auxSwapBuffers();
}
void CALLBACK elbowAdd()
{
elbow = (elbow + 5) % 360;
}
void CALLBACK elbowSubtract()
{
elbow = (elbow - 5) % 360;
}
void CALLBACK shoulderAdd()
{
shoulder = (shoulder + 5) % 360;
}
void CALLBACK shoulderSubtract()
{
shoulder = (shoulder - 5) % 360;
}
Программа 2.3. Модель манипулятора робота.