- •Компьютерная графика
- •Лабораторная работа №1 Графические примитивы
- •Задание
- •Последовательность выполнения задания
- •Программный код
- •1.2.1 Среда программирования Microsoft Visual Studio 6. (мастер приложений AppWizard)
- •1.2.2 Среда разработки ms Visual Studio 2010
- •1. Добавим строки, сохраняющие координаты указателя мыши в момент нажатия левой кнопки мыши
- •2. Добавим в метод OnDraw() класса cPainterView строки, которые будут выполнять вывод на экран линий, соединяющих опорные точки.
- •3. Создание нового рисунка. Добавим в метод OnNewDocument() класса cPainterDoc
- •4. Сохранение рисунков в файл. Модифицируем функцию Serialize() класса cPainterDoc в файле PainterDoc.Cpp
- •Лабораторная работа №2 Фракталы
- •Лабораторная работа №3
- •Сплайны. Кривая Безье
- •Задание
- •Последовательность выполнения задания
- •Программный код
- •Лабораторная работа №4
- •Цель работы:
- •Теоретическое введение:
- •Лабораторная работа №5 «Закрашивание. Метод Фонга»
- •Контрольная работа
Лабораторная работа №5 «Закрашивание. Метод Фонга»
Метод Фонга
В этом методе интерполируются значения вектора внешней нормали, которое затем используется для вычисления интенсивности пиксела. Поэтому закраска Фонга требует заметно большего объема вычислений. Но изображение получается более близким к реалистичному.
|
Сравнение методов закраски: Слева - однотонная закраска, в центре - закраска Гуро, справа - закраска Фонга. |
Схема интерполяции, аналогична интерполяции в закраске Гуро. Для определения вектора нормали nW в точке W проводим через эту точку горизонтальную прямую и используя значения векторов nUи nV в точке пересечения U и V с ребром грани получаем
,
где
,
0 <= t <= 1.
nU=
(1-U) n v4 +
Un v1,
где
,
0 <= U <= 1.
nV=
(1-V) n v1 +
Vn v2,
где
,
0 <= V <= 1.
Вследствие значительных упрощений получаемый результат не всегда удовлетворителен. Для получения качественных изображений используются более совершенные модели и методы.
Ниже можно посмотреть текст и работу программы на языке С. (Для завершения работы программы достаточно нажать любую клавишу).
Код программы:
#include<gl\glut.h>
#include<math.h>
floatWinWid=400.0;
floatWinHei=400.0;
floatAngleX=0.0,AngleY=0.0,AngleZ=0.0, Scale=12.0;
int YGX=0,YGY=0,YGZ=0;
char PV=0;//поворот
int per=0;
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glNormal3f(1.0,1.0,1.0);
glLoadIdentity();
glPushMatrix();
glScalef(Scale, Scale, 1.0);
glRotatef(AngleX, 1.0, 0.0, 0.0); // поворот на угол X
glRotatef(AngleY, 0.0, 1.0, 0.0); // поворот на угол Y
glRotatef(AngleZ, 0.0, 0.0, 1.0); // поворот на угол Z
switch(PV)
{
case'f': glShadeModel (GL_SMOOTH);
break;
case'p': glShadeModel (GL_FLAT);
break;
}
glColor3f(0,1.0,0);
glTranslatef(0,0,per);
glColor3f(0,1.0,0);
glutSolidSphere(3,20,15);
glTranslatef(0,0,-per);
glColor3f(0.7,0.4,0.0);
glutSolidTorus(7.0, 7.0, 3, 10);
glColor3f(0.3, 0.3, 0.3);
glutSolidTorus(4.0, 10.0, 8, 10);
glPopMatrix();
glutSwapBuffers();
}
bool b=0;
int bb=-1;
void Timer(int value)
{
if(per==-20){bb=+1;}
if(per==20){bb=-1;}
per+=bb;
Draw();
glutPostRedisplay();
glutTimerFunc(10, Timer, 0);
}
void Keyboard(unsignedchar key, int x, int y)
{
switch(key)
{
case'w': AngleX+=5;
break;
case's': AngleX-=5;
break;
case'a': AngleY+=5;
break;
case'd': AngleY-=5;
break;
case'q': AngleZ+=5;
break;
case'e': AngleZ-=5;
break;
case'+': Scale++;
break;
case'-': Scale--;
break;
case'f': PV='f';
break;
case'p': PV='p';
break;
}
}
voidSKeyboard(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_LEFT: AngleX++;
break;
case GLUT_KEY_RIGHT: AngleX--;
break;
case GLUT_KEY_UP: AngleY++;
break;
case GLUT_KEY_DOWN: AngleY--;
break;
}
}
voidInitialize()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-WinWid/2, WinWid/2, -WinHei/2, WinHei/2, -200.0, 200.0);
glMatrixMode(GL_MODELVIEW);
}
float ambient[]={1.0,1.0,1.0,1.0};
float diffuse[]={1.0,1.0,1.0,1.0};
floatlpos[]={WinWid/2,WinHei/2,40.0,1.0};
float spec[]={1.0,1.0,1.0,1.0};
floatspecref[]={1.0,1.0,1.0,1.0};
float black[]={0.0,0.0,0.0,0.0};
int main(intargc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(WinWid, WinHei);
glutInitWindowPosition(100, 200);
glutCreateWindow("kub");
glutDisplayFunc(Draw);
glutTimerFunc(10, Timer, 0);
glutKeyboardFunc(Keyboard);
glutSpecialFunc(SKeyboard);
glEnable(GL_LIGHTING);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,black);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR,spec);
glLightfv(GL_LIGHT0, GL_POSITION,lpos);
glMaterialfv(GL_FRONT,GL_SPECULAR,specref);
glMateriali(GL_FRONT,GL_SHININESS,1);
glEnable(GL_COLOR_MATERIAL);
Initialize();
glutMainLoop();
return 0;
}
Пример работы программы:
Рис.49 Однотонная закраска
Рис. 50 Закраска Фонга
