Опубликован: 13.07.2010 | Доступ: свободный | Студентов: 891 / 20 | Оценка: 4.40 / 4.20 | Длительность: 77:34:00
Тема: Программирование
Специальности: Программист, Архитектор программного обеспечения
Теги:
Самостоятельная работа 22:
Свет и материалы в OpenGL
< Самостоятельная работа 21 || Самостоятельная работа 22: 123456789101112 || Самостоятельная работа 23 >
Модель самолета с зеркальным отражением (JetShiny)
Предполагается, что поверхность самолета имеет некоторые зеркальные отражательные свойства и способна генерировать блики. Пусть эти блики будут равномерно распределены по всей поверхности граней самолета. Способность зеркального отражения мы введем, задав соответствующее свойство материала.
- Добавьте к проекту новый файл с именем JetShiny.h
- С копируйте в новый файл код из файла JetLight.h и змените окончания всех функций и их прототипов с JetLight на JetShiny
- Удалите весь код, помеченный как вспомогательный, вместе с прототипами вспомогательных функций
- Добавьте в конец функции SetLightJetShiny() код установки отражательных свойств поверхности самолета
void SetLightJetShiny() { GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f };// Фоновый слабобелый GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f };// Рассеяный среднебелый GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0};// Расположение источника glShadeModel(GL_SMOOTH); GLfloat diffuseMaterial[] = {0.5, 0.5, 0.5, 1.0}; glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMaterial);// Начальное значение диффузного материала glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight); glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); // Режим согласования цветов назначаем для фонового и рассеянного glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Включаем поддержку согласования цветов glEnable(GL_COLOR_MATERIAL); // Задание свойства зеркального отражения GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glMaterialfv(GL_FRONT, GL_SPECULAR, specular); glLightfv(GL_LIGHT0, GL_SPECULAR, specular); glMateriali(GL_FRONT, GL_SHININESS, 50); }Листинг 23.26. Добавление свойства зеркального отражения в функцию SetLightJetShiny()
- Добавьте в файл LightAndMaterial.cpp код, подключающий новое упражнение
// LightAndMaterial.cpp : Defines the entry point for the console application. // //********************************************************** // Подключение стандартного файла с библиотекой OpenGL #include "stdafx.h" //********************************************************** // Прототипы функций void ExecuteMenu(int); // Контекстное меню первого уровня void TimerFunc(int); // Обработчик события таймера void SpecialKeys(int, int, int); // Обработка нажатия клавиш void RenderScene(void); // Функция рендеринга void ChangeSize(int, int); // Функция установки отсекающего объема // Глобальная переменная выбранного варианта основного меню int choice = 1; // Глобальные переменные для создания вращения // в градусах GLfloat xRot = 0.0f; GLfloat yRot = 0.0f; GLfloat zRot = 0.0f; GLint w, h; // Ширина и высота экрана //********************************************************** // Подключение файлов с упражнениями #include "ColorCube.h" // Упражнение 1: "1) Куб цвета" #include "Jet.h" // Упражнение 2: "2) Самолет без освещения" #include "LightSphere.h" // Упражнение 3: "3) Рисование освещенной сферы" #include "MultiMaterial.h" // Упражнение 4: "4) Рисование с разными материалами" #include "ColorSphere.h" // Упражнение 5: "5) Способ согласования цветов" #include "JetNight.h" // Упражнение 6: "6) Самолет с нулевым освещением" #include "JetLight.h" // Упражнение 7: "7) Самолет с равномерным освещением" #include "JetShiny.h" // Упражнение 8: "8) Самолет с зеркальным отражением" //********************************************************** // Функция обратного вызова обработки выбора пользователя void ExecuteMenu(int choice) { // Сбрасываем углы вращения прежнего варианта xRot = yRot = zRot = 0; // Выключаем освещение glDisable(GL_LIGHTING); // Выключаем режим согласования цветов glDisable(GL_COLOR_MATERIAL); // Запоминаем выбор в глобальную переменную ::choice = choice; switch(::choice) { case 1: ChangeSizeColorCube(w, h); break; case 2: ChangeSizeJet(w, h); break; case 3: ChangeSizeLightSphere(w, h); break; case 4: ChangeSizeMultiMaterial(w, h); break; case 5: ChangeSizeColorSphere(w, h); break; case 6: ChangeSizeJetNight(w, h); break; case 7: ChangeSizeJetLight(w, h); break; case 8: ChangeSizeJetShiny(w, h); break; } // Вызвать принудительно визуализацию glutPostRedisplay(); } //********************************************************** // Функция обратного вызова для рисования сцены void RenderScene(void) { // Сохранить прежние настройки OpenGL в стеке атрибутов glPushAttrib(GL_LIGHTING_BIT); switch(::choice) { case 1: RenderSceneColorCube(); break; case 2: RenderSceneJet(); break; case 3: RenderSceneLightSphere(); break; case 4: RenderSceneMultiMaterial(); break; case 5: RenderSceneColorSphere(); break; case 6: RenderSceneJetNight(); break; case 7: RenderSceneJetLight(); break; case 8: RenderSceneJetShiny(); break; } // Восстановить прежние настройки OpenGL из стека атрибутов glPopAttrib(); } //********************************************************** // Вызывается библиотекой GLUT при изменении размеров окна void ChangeSize(int width, int height) { w = width; h = height; switch(::choice) { case 1: ChangeSizeColorCube(width, height); break; case 2: ChangeSizeJet(width, height); break; case 3: ChangeSizeLightSphere(width, height); break; case 4: ChangeSizeMultiMaterial(width, height); break; case 5: ChangeSizeColorSphere(width, height); break; case 6: ChangeSizeJetNight(width, height); break; case 7: ChangeSizeJetLight(width, height); break; case 8: ChangeSizeJetShiny(width, height); break; } } //********************************************************** // Обработчик события таймера void TimerFunc(int value) { glutPostRedisplay(); // Перерисовка сцены glutTimerFunc(30, TimerFunc, 1); // Заряжаем новый таймер } //********************************************************** // Управление с клавиатуры стрелками // для задания новых значений матрицы поворота void SpecialKeys(int key, int x, int y) { if(key == GLUT_KEY_UP) // Стрелка вверх xRot -= 5.0f; if(key == GLUT_KEY_DOWN)// Стрелка вниз xRot += 5.0f; if(key == GLUT_KEY_LEFT)// Стрелка влево yRot -= 5.0f; if(key == GLUT_KEY_RIGHT)// Стрелка вправо yRot += 5.0f; xRot = (GLfloat)((const int)xRot % 360); yRot = (GLfloat)((const int)yRot % 360); // Для упражнения 5 смены материала if(key == GLUT_KEY_F1) // Меняем красный { diffuseMaterial[0] += 0.1; *diffuseMaterial = *diffuseMaterial > 1.0 ? 0.0 : *diffuseMaterial; glColor4fv(diffuseMaterial); } if(key == GLUT_KEY_F2) // Меняем зеленый { diffuseMaterial[1] += 0.1; *(diffuseMaterial + 1) = diffuseMaterial[1] > 1.0 ? 0.0 : diffuseMaterial[1]; glColor4fv(diffuseMaterial); } if(key == GLUT_KEY_F3) // Меняем синий { diffuseMaterial[2] += 0.1; *(diffuseMaterial + 2) = diffuseMaterial[2] > 1.0 ? 0.0 : diffuseMaterial[2]; glColor4fv(diffuseMaterial); } // Вызвать принудительно визуализацию с помощью RenderScene() glutPostRedisplay(); } //********************************************************** void main(int argc, char* argv[]) { glutInit(&argc, argv); // Двойная буферизация, цветовая модель RGB, буфер глубины glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(300, 300); // Начальные размеры окна glutCreateWindow("Свет и материалы"); // Заголовок окна glutDisplayFunc(RenderScene); // Обновление сцены при разрушении окна glutReshapeFunc(ChangeSize); // При изменении размера окна glutTimerFunc(100, TimerFunc, 1); // Создали таймер glutSpecialFunc(SpecialKeys); // Для управления с клавиатуры // Создание меню и добавление опций выбора glutCreateMenu(ExecuteMenu); glutAddMenuEntry("1) Куб цвета", 1); glutAddMenuEntry("2) Самолет без освещения", 2); glutAddMenuEntry("3) Рисование освещенной сферы", 3); glutAddMenuEntry("4) Рисование с разными материалами", 4); glutAddMenuEntry("5) Способ согласования цветов (F1, F2, F3)", 5); glutAddMenuEntry("6) Самолет с нулевым освещением", 6); glutAddMenuEntry("7) Самолет с равномерным освещением", 7); glutAddMenuEntry("8) Самолет с зеркальным отражением", 8); glutAttachMenu(GLUT_RIGHT_BUTTON);// Присоединяем // Конец создания меню glutMainLoop(); // Цикл сообщений графического окна }Листинг 23.27. Код подключения модели самолета с зеркальным отражением в файле LightAndMaterial.cpp
- Запустите приложение и выполните упражнение 8, результат должен быть примерно таким
< Самостоятельная работа 21 || Самостоятельная работа 22: 123456789101112 || Самостоятельная работа 23 >