You are on page 1of 9

Цель работы:

1. Исходный текст программы с комментариями:


//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

//Инициализация
#include <vcl.h>
#include <GL/gl.h>
#include <GL/glu.h> // gl.h и glu.h содержат прототипы основных функций
OpenGL определённых в opengl32.dll и glu32.dll.

#pragma hdrstop

#include "MainUnit.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TMainForm *MainForm;

BOOL bSetupPixelFormat(HDC hdc)


{
PIXELFORMATDESCRIPTOR pfd, *ppfd;
int pixelformat;

ppfd = &pfd;

ppfd->nSize = sizeof(PIXELFORMATDESCRIPTOR);
ppfd->nVersion = 1;
ppfd->dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
ppfd->dwLayerMask = PFD_MAIN_PLANE;
ppfd->iPixelType = PFD_TYPE_RGBA;// iPixelType – формат указания цвета -
цвет указывается четырьмя параметрами RGBA - красный, зленный, синий и альфа
ppfd->cColorBits = 16; // cColorBits – глубина цвета
ppfd->cDepthBits = 16; // cDepthBits – размер буфера глубины (Z-Buffer)

ppfd->cAccumBits = 0;
ppfd->cStencilBits = 16; // cStencilBits – размер буфера трафарета

// ChoosePixelFormat подбирает формат пикселей, максимально удовлетворяющий


нашим требованиям
if ((pixelformat = ChoosePixelFormat(hdc, ppfd)) == 0)
{
MessageBox(NULL, "ChoosePixelFormat failed", "Error",MB_OK);
return FALSE;
}
// SetPixelFormat устанавливает его в контексте устройства (dc)
if (SetPixelFormat(hdc, pixelformat, ppfd) == FALSE)
{
MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
return FALSE;
}
return TRUE;
}

//---------------------------------------------------------------------------
__fastcall TMainForm::TMainForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormCreate(TObject *Sender)
{

//hRC – указатель на контекст воспроизведения (Rendering Context)


//ghDC – дескриптор устройства , просто указатель на окно)
ghDC = GetDC(Handle);
if (!bSetupPixelFormat(ghDC)) Close();
ghRC = wglCreateContext(ghDC);
wglMakeCurrent(ghDC, ghRC);

glClearColor(1.0, 1.0, 1.0, 1.0); // glClearColor устанавливает цвет (в


нашем случае белый), которым будет заполняться экран при очищении.

FormResize(Sender);

glEnable(GL_COLOR_MATERIAL);// разрешили давать нашим объектам какой-то


цвет
glEnable(GL_DEPTH_TEST); // разрешили тест глубины, чтобы изображение было
объёмным
glShadeModel(GL_SMOOTH); // сглаживать углы между смежными полигонами

glEnable(GL_LIGHTING);// разрешили освещение


glEnable(GL_LIGHT0);// включили «лампочку №0»

// glLightfv устанавливает свойства «лампочек»:


float p[4] = {1, 11, 1, 1},
d[3] = {1, 1, 1};
glLightfv(GL_LIGHT0, GL_POSITION, p);// позицию
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, d); // и направление света.

}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormResize(TObject *Sender)
{
glViewport(0, 0, Width, Height);// glViewport устанавливает область
вывода – область, в которую OpenGL будет выводить изображение.

glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // glLoadIdentity заменяет текущую матрицу видового
преобразования на единичную (матрицу идентичности), т.е. просто сбрасывает
изменения.
glOrtho(-5, 5, -5, 5, 2, 12);// // glOrtho устанавливает режим
ортогонального (прямоугольного) проецирования.
gluLookAt(0, 0, 5, 0, 0, 0, 0, 1, 0);// gluLookAt устанавливает параметры
камеры: первая тройка – её координаты, вторая – вектор направления, третья –
направление оси Y

glMatrixMode(GL_MODELVIEW); // glMatrixMode устанавливает режим матрицы


видового преобразования.

}
//---------------------------------------------------------------------------
void __fastcall TMainForm::FormClose(TObject *Sender, TCloseAction &Action)
{
gluDeleteQuadric(quadObj); // освободить память, занимаемую под nquadObj .

if(ghRC)
{
wglMakeCurrent(ghDC,0);// освободить контекст
wglDeleteContext(ghRC); // разрушить его
}
if(ghDC) ReleaseDC(Handle, ghDC);
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::TimerTimer(TObject *Sender)
{
Draw();
}
//---------------------------------------------------------------------------
void __fastcall TMainForm::Draw()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
// glClear сбрасывает значения всего перечисленного в качестве параметров

GLUquadricObj *quadObj;
quadObj = gluNewQuadric();

glEnable(GL_STENCIL_TEST); // // Включим тест буфера трафарета


glStencilFunc(GL_ALWAYS, 1, 0); // сообщает OpenGL тип проверки,
производимой для каждого пикселя выводимого на экран объекта: GL_ALWAYS -
тест работает все время, второй параметр – это значение ссылки, которое мы
проверяем в третьей строке, и третий параметр – это маска. Маска – это
значение, поразрядно умножаемое операцией AND (логическое умножение из
булевой алгебры – прим.перев.) на значение ссылки и сохраняемое в буфере
шаблона в конце обработки
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); // какие изменения нужно
проводить в буфере трафарета. Первыйи второй параметры означают, что нужно
оставить прежнюю переменную в случае неудачи stencil test'a или depth test'a
ссответственно, третий - что если оба теста не пройдены - задать переменную
как в +glStencilFunc

glColor3d(0.43,1,0);// glColor3d устанавливает цвет фигуры


gluSphere(quadObj, 1.4,10,10); // делает из quadObj сферу. Три последних
параметра – это радиус и количество разбиений поперёк и вдоль оси Z
соответственно

glStencilFunc(GL_ALWAYS, 2, 0);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
gluCube();

// вращаем сцену
// glRotated(ф, x,y,z) – поворачивает систему координат на угол ф (в
градусах) против часовой стрелки вокруг вектора (x,y,z)
glRotated(3, 1,0,0);
glRotated(5, 0,1,0);
glRotated(7, 0,0,1);
SwapBuffers(ghDC); // вывести все на экран
}
//---------------------------------------------------------------------------
GLvoid __fastcall TMainForm::gluCube( ) // Рисование куба
{
glBegin(GL_QUADS); // Начинаем рисовать четырехугольники
// Передняя сторона
glColorMaterial(1,1);
glColor3d(0.98,1,0.07);
glNormal3f( 0.0f, 0.0f, 1.0f); // Нормаль вперед
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f); // Низ лево на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f); // Низ право на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f); // Верх право на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f); // Верх лево на текстуре и
четырехугольнике
// Задняя сторона
glNormal3f( 0.0f, 0.0f,-1.0f); // Обратная нормаль
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); // Низ право на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f); // Верх право на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f); // Верх лево на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, -1.0f); // Низ лево на текстуре и
четырехугольнике

// Верхняя грань
glNormal3f( 0.0f, 1.0f, 0.0f); // Нормаль вверх
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f); // Верх лево на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 1.0f); // Низ лево на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, 1.0f, 1.0f); // Низ право на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f); // Верх право на текстуре и
четырехугольнике

// Нижняя грань
glNormal3f( 0.0f,-1.0f, 0.0f); // Нормаль направлена вниз
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); // Верх право на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, -1.0f, -1.0f); // Верх лево на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f); // Низ лево на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f); // Низ право на текстуре и
четырехугольнике

// Правая грань
glNormal3f( 1.0f, 0.0f, 0.0f); // Нормаль направлена вправо
glTexCoord2f(1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, -1.0f); // Низ право на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, -1.0f); // Верх право на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 1.0f);
glVertex3f( 1.0f, 1.0f, 1.0f); // Верх лево на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 1.0f); // Низ лево на текстуре и
четырехугольнике

// Левая грань
glNormal3f(-1.0f, 0.0f, 0.0f); // Нормаль направлена влево
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, -1.0f); // Низ лево на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 1.0f); // Низ право на текстуре и
четырехугольнике
glTexCoord2f(1.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, 1.0f); // Верх право на текстуре и
четырехугольнике
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-1.0f, 1.0f, -1.0f); // Верх лево на текстуре и
четырехугольнике
glEnd(); // Заканчиваем рисование
четырехугольников

}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormKeyUp(TObject *Sender, WORD &Key,


TShiftState Shift)
{
switch (Key)
{
case VK_LEFT:
glPushMatrix(); // сохранение текущих координат
glTranslated(-3, 0, 0);
break;
case VK_RIGHT:
glPushMatrix();
glTranslated(3, 0, 0);
break;
case VK_UP:
glPushMatrix() ;
glTranslated(0, 3, 0);
break;
case VK_DOWN:
glPushMatrix();
glTranslated(0, -3, 0);
break;
case VK_SPACE:
glPopMatrix(); // восстановление координат
break;
case '2':
case VK_ADD:
glScalef(2,2,2); // увеличить по всем осям в 2 раза
break;
case '1':
case VK_SUBTRACT:
glScalef(0.5,0.5,0.5); // уменьшить по всем осям в 2 раза
break;
}
}
//---------------------------------------------------------------------------

void __fastcall TMainForm::FormClick(TObject *Sender)


{
glPopMatrix();
}
//---------------------------------------------------------------------------
2. Выполнение программы

Рис. 1. Исходное состояние.

Рис. 2. Уменьшили фигуру в 4 раза.


Рис. 3. Увеличили ее в 2 раза.
Рис. Сдвиг фигуры.

Вывод: Изучены и освоены