Опубликован: 13.07.2010 | Доступ: свободный | Студентов: 890 / 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 >

