Добавил:
nyan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:ИГС / IGS_2014-2015 / Lab_04 / glopen08 / glopen08
.cpp
#define STRICT
#include <windows.h>
#include <windowsx.h>
#include <gl\gl.h>
#include <gl\glu.h>
//имя класса главного окна программы
char const szClassName[] = "OpenGL";
//заголовок окна
char const szWindowTitle[] = "Korneev V. Graphics by OpenGL";
//прототипы функций
BOOL RegisterApp(HINSTANCE);
HWND CreateApp(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void DestroyOpenGL();
void DrawOpenGL(HWND);
//главная функция
int PASCAL WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpszCmdParam,
int nCmdShow)
{
MSG msg; //структура для работы с сообщениями
//регистрация класса главного окна программы
if(!RegisterApp(hInstance))
return FALSE;
//создание главного окна программы
if(!CreateApp(hInstance,nCmdShow))
return FALSE;
//цикл обработки сообщений
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
//регистрация класса главного окна программы
BOOL RegisterApp(HINSTANCE hInstance)
{
WNDCLASS wc; //структура для регистрации класса главного окна программы
wc.style = CS_HREDRAW | CS_VREDRAW; //стиль окна
wc.lpfnWndProc = WndProc; //имя оконной процедуры
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance; //дескриптор программы
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = GetStockBrush(LTGRAY_BRUSH);
wc.lpszMenuName = "GLMENU"; //имя меню главного окна программы
wc.lpszClassName = szClassName; //имя класса главного окна программы
return RegisterClass(&wc);
}
//создание главного окна программы
HWND CreateApp(HINSTANCE hInstance, int nCmdShow)
{
HWND hwnd; //дескриптор главного окна программы
hwnd = CreateWindow(szClassName, //имя класса окна
szWindowTitle, //заголовок окна
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN
| WS_CLIPSIBLINGS, //стиль окна
CW_USEDEFAULT, //положение и размеры окна
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
NULL,
NULL,
hInstance,
NULL);
if(hwnd == NULL)
return hwnd;
//рисуем окно
ShowWindow(hwnd,nCmdShow);
//обновляем окно
UpdateWindow(hwnd);
return hwnd;
}
//оконная функция, обрабатывающая сообщения
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_COMMAND: //сообщение для работы с меню
switch(wParam)
{
case 200:
InvalidateRect(hwnd,NULL,TRUE); //очищаем окно
break;
case 202:
DrawOpenGL(hwnd); //рисуем графические объекты
break;
case 201:
DestroyWindow(hwnd); //завершает работу окна
break;
}
break;
case WM_DESTROY:
DestroyOpenGL();
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
return 0L;
}
//завершение работы программы
void DestroyOpenGL()
{
PostQuitMessage(0); //окончание цикла сообщений
}
//рисуем графические объекты
void DrawOpenGL(HWND hwnd)
{
HDC hdc = GetDC(hwnd); //получаем контест окна
//структура описания формата пикселя
PIXELFORMATDESCRIPTOR pfd;
//зануляем все поля структуры pfd
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
//заполняем некоторые поля структуры
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 32;
//выбираем наиболее подходящий формат пикселей
int iPixelFormat = ChoosePixelFormat(hdc, &pfd);
//устанавливаем найденный формат пикселей в контектсте окна
SetPixelFormat(hdc, iPixelFormat, &pfd);
//получаем контекст отображения OpenGL
HGLRC hglrc = wglCreateContext(hdc);
//устанавливаем текущий контекст отображения OpenGL
wglMakeCurrent(hdc, hglrc);
//включаем механизм z-буфура
glClearColor(1.0f,1.0f,1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearDepth(1.0);
glEnable(GL_DEPTH_TEST);
RECT rc;
//коодинаты окна отправляетс в струткуру rc
GetClientRect(hwnd, &rc);
//установка матрицы перспективной проекции
// gluPerspective(f,a,zN,zF) f-угол просмотра, a- коэффициент
//пропорциональности, zN- расстояние до ближней плоскости отсечения
// zF- расстояние до дальней плоскости отсечения
gluPerspective(50, (double)rc.right/rc.bottom, 1, 40);
//умножение текущей матрицы на матрицу переноса
glTranslatef(0, 0, -10);
//умножение текущей матрицы на матрицу пповорота
glRotatef(27, 1, 0, 0);
glRotatef(-19, 0, 1, 0);
GLfloat lightpos[4] = {3,3,5.5,1};
GLfloat lightdirection[3] = {-0.5f,-0.6f,-0.7f};
glLightfv(GL_LIGHT0,GL_POSITION,lightpos);
glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightdirection);
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,1);
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,60);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
//передняя грань пирамиды
glColor3f(1, 1, 0);
glBegin(GL_TRIANGLES);
glVertex3f(0, 4, 0);
glVertex3f(-2.0f, 0.7f, 2.0f);
glVertex3f(2.0f, 0.7f, 2.0f);
glEnd();
//задняя грань
glColor3f(0.8f, 0.8f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(0, 4, 0);
glVertex3f(-2.0f, 0.7f, -2.0f);
glVertex3f(2.0f, 0.7f, -2.0f);
glEnd();
//правая грань
glColor3f(0.5f, 0.5f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex3f(0, 4, 0);
glVertex3f(2.0f, 0.7f, 2.0f);
glVertex3f(2.0f, 0.7f, -2.0f);
glEnd();
//левая грань
glBegin(GL_TRIANGLES);
glVertex3f(0, 4, 0);
glVertex3f(-2.0f, 0.7f, 2.0f);
glVertex3f(-2.0f, 0.7f, -2.0f);
glEnd();
//основание пирамиды
glColor3f(0.8f, 0.8f, 0.0f);
glBegin(GL_QUADS);
glVertex3f(-2.0f, 0.7f, -2.0f);
glVertex3f(2.0f, 0.7f, -2.0f);
glVertex3f(2.0f, 0.7f, 2.0f);
glVertex3f(-2.0f, 0.7f, 2.0f);
glEnd();
//Шахматное поле
for(int j=-5; j <5; j++)
for(int i=-5; i<5; i++)
{
if((abs(i+j)%2) == 0)
glColor3f(1, 0, 0);
else
glColor3f(0.8f, 0.8f, 0.8f);
glBegin(GL_QUADS);
glVertex3f((float)i, 0, (float)j);
glVertex3f((float)(i+1), 0, (float)j);
glVertex3f((float)(i+1), 0, (float)(j+1));
glVertex3f((float)i, 0, (float)(j+1));
glEnd();
}
//завершаем работу с текущим контекстом отображения
wglMakeCurrent(NULL, NULL);
//освобождаем контекст отображения OpenGL
wglDeleteContext(hglrc);
//освобождаем контекст окна
ReleaseDC(hwnd,hdc);
}