glEnd();
}
// Рисуем открытое поле
void View::drawOpenedField(int x, int y, int minesAround)
{
drawOpenedField(x, y);
if (minesAround > 0)
{
switch (minesAround)
{
case 1:
glColor3f(0.0f, 1.0f, 0.0f);
break;
case 2:
glColor3f(0.0f, 0.0f, 1.0f);
break;
case 3:
glColor3f(1.0f, 0.0f, 0.0f);
break;
case 4:
glColor3f(0.0f, 0.7f, 0.0f);
break;
case 5:
glColor3f(0.5f, 0.4f, 0.0f);
break;
case 6:
glColor3f(0.0f, 0.8f, 0.5f);
break;
case 7:
glColor3f(0.1f, 0.1f, 0.1f);
break;
case 8:
glColor3f(0.3f, 0.3f, 0.3f);
break;
}
// Выводим надпись количества соседей - мин
glRasterPos2f(BorderSize + x * CellWidth + (30 - 8) / 2 + 1, SceneHeight - (BorderSize + (y + 1) * CellHeight - 15));
glutBitmapCharacter(GLUT_BITMAP_9_BY_15, '0' + minesAround % 10);
}
}
// Открытая ячейка
void View::drawOpenedField(int x, int y)
{
glColor3f(0.6f, 0.6f, 0.6f);
glBegin(GL_QUADS);
glVertex2f(BorderSize + x * CellWidth, SceneHeight - (BorderSize + y * CellHeight));
glVertex2f(BorderSize + (x + 1) * CellWidth, SceneHeight - (BorderSize + y * CellHeight));
glVertex2f(BorderSize + (x + 1) * CellWidth, SceneHeight - (BorderSize + (y + 1) * CellHeight));
glVertex2f(BorderSize + x * CellWidth, SceneHeight - (BorderSize + (y + 1) * CellHeight));
glColor3f(0.2f, 0.2f, 0.2f);
glEnd();
glBegin(GL_LINES);
glVertex2f(BorderSize + (x + 1) * CellWidth - 1, SceneHeight - (BorderSize + y * CellHeight));
glVertex2f(BorderSize + (x + 1) * CellWidth - 1, SceneHeight - (BorderSize + (y + 1) * CellHeight - 1));
glVertex2f(BorderSize + x * CellWidth, SceneHeight - (BorderSize + (y + 1) * CellHeight - 1));
glVertex2f(BorderSize + (x + 1) * CellWidth - 1, SceneHeight - (BorderSize + (y + 1) * CellHeight - 1));
glEnd();
}
// Рисуем флаг
void View::drawFlag(int x, int y)
{
// Установить текущий цвет (R, G,B)
glColor3f(0.8f, 0.8f, 0.8f);
glBegin(GL_QUADS);
glVertex2f(BorderSize + x * CellWidth, SceneHeight - (BorderSize + y * CellHeight));
glVertex2f(BorderSize + (x + 1) * CellWidth, SceneHeight - (BorderSize + y * CellHeight));
glVertex2f(BorderSize + (x + 1) * CellWidth, SceneHeight - (BorderSize + (y + 1) * CellHeight));
glVertex2f(BorderSize + x * CellWidth, SceneHeight - (BorderSize + (y + 1) * CellHeight));
glEnd();
// Установить текущий цвет (R, G,B)
glColor3f(0.0f, 0.0f, 0.0f);
glBegin(GL_LINES);
glVertex2f(BorderSize + x * CellWidth + CellWidth / 2, SceneHeight - (BorderSize + y * CellHeight + 3));
glVertex2f(BorderSize + x * CellWidth + CellWidth / 2, SceneHeight - (BorderSize + (y + 1) * CellHeight - 3));
glEnd();
//Установить текущий цвет (R, G,B)
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_TRIANGLES);
glVertex2f(BorderSize + x * CellWidth + CellWidth / 2, SceneHeight - (BorderSize + y * CellHeight + 3));
glVertex2f(BorderSize + x * CellWidth + CellWidth / 2 - 3, SceneHeight - (BorderSize + y * CellHeight + 3 + 3));
glVertex2f(BorderSize + x * CellWidth + CellWidth / 2, SceneHeight - (BorderSize + y * CellHeight + 3 + 3 + 3));
glEnd();
}
// Рисуем мину
void View::drawMine(int x, int y)
{
drawOpenedField(x, y);
glColor3f(0.0f, 0.0f, 0.0f);
glPointSize(10);
glBegin(GL_POINTS);
glVertex2f(BorderSize + x * CellWidth + CellWidth / 2.0f, SceneHeight - (BorderSize + y * CellHeight + CellHeight / 2.0f));
glEnd();
}
// Получить координаты в система OpenGL
POINT View::GetOGLPos(int x, int y)
{
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );
winX = (float)x;
winY = (float)viewport[3] - (float)y;
glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
POINT p;
p. x = posX;
p. y = posY;
return p;
}
// Получить индекс ячейки в матрице модели по координатам позиции мышки
POINT View::GetCellIndex(POINT point)
{
// Calc index
POINT p;
p. x = -1;
p. y = -1;
// Проверяем установлена ли модель
if(model == NULL)
return p;
// Если установлена - определем "X" координату
for(int x = 0; x < model->Width && p. x == -1; x++)
{
double x1 = BorderSize + x * CellWidth;
double x2 = BorderSize + (x + 1) * CellWidth;
if(point. x > x1 && point. x < x2)
p. x = x;
}
// Определем "Y" координату
for(int y = 0; y < model->Height && p. y == -1; y++)
{
double y1 = SceneHeight - (BorderSize + y * CellHeight);
double y2 = SceneHeight - (BorderSize + (y + 1) * CellHeight);
if(point. y < y1 && point. y > y2)
p. y = y;
}
// Возвращаем координаты
return p;
}
// Построение битмап шрифта
GLvoid View::BuildFont(GLvoid)
{
HFONT font; // Идентификатор шрифта
HFONT oldfont;
base = glGenLists(96); // Список из 96 символов
font = CreateFont( -12, // Высота
0, // Ширина
0,
0, // Угол ориентации
FW_BOLD, // Жирный или нет
FALSE, // Наклонный
FALSE, // Подчеркивание
FALSE,
ANSI_CHARSET,
OUT_TT_PRECIS,
CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY, // Качество
FF_DONTCARE|DEFAULT_PITCH,
L"Courier New"); // Название шрифта
oldfont = (HFONT)SelectObject(hDC, font);
// Построение шрифта из 96 символов
wglUseFontBitmaps(hDC, 32, 96, base);
// Выбираем наш шрифт
SelectObject(hDC, oldfont);
// Удаляем шрифт
DeleteObject(font);
}
// Очистка ресурсов шрифта
GLvoid View::KillFont(GLvoid)
{
glDeleteLists(base, 96);
}
// Функция вывода шрифта
GLvoid View::glPrint(const char *fmt, ...)
{
// Буффер для текста
char text[256];
// Указатель на список аргументов
va_list ap;
// Если нет текста - ничего не делаем
if (fmt == NULL)
return;
// Разбираем список аргументов
va_start(ap, fmt);
vsprintf(text, fmt, ap);
va_end(ap);
// Сохраняем список
glPushAttrib(GL_LIST_BIT);
glListBase(base - 32);
// Рисуем список
glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
glPopAttrib();
}
// Построение окна
BOOL View::CreateGLWindow(WNDPROC WndProc, LPCWSTR title, int bits)
{
// Хранит результат после поиска
GLuint PixelFormat;
// Структура окна
WNDCLASS wc;
// Расширенный стиль окна
DWORD dwExStyle;
// Обычный стиль окна
DWORD dwStyle;
// Параметры окна
RECT WindowRect;
// Установить левую составляющую в 0
WindowRect. left = (long)0;
// Установить правую составляющую в Width
WindowRect. right = (long)SceneWidth;
// Установить верхнюю составляющую в 0
WindowRect. top = (long)0;
// Установить нижнюю составляющую в Height
WindowRect. bottom = (long)SceneHeight;
// Получаем дескриптор приложения
hInstance = GetModuleHandle(NULL);
// Заполняем поля стуктуры
// Перерисуем при перемещении и создаём скрытый DC
wc. style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
// Процедура обработки сообщений
wc. lpfnWndProc = (WNDPROC)WndProc;
// Нет дополнительной информации для окна
wc. cbClsExtra = 0;
// Нет дополнительной информации для окна
wc. cbWndExtra = 0;
// Устанавливаем дескриптор
wc. hInstance = hInstance;
// Загружаем иконку по умолчанию
wc. hIcon = LoadIcon(NULL, IDI_WINLOGO);
// Загружаем указатель мышки
wc. hCursor = LoadCursor(NULL, IDC_ARROW);
// Фон не требуется для GL
wc. hbrBackground = NULL;
// Меню в окне не будет
wc. lpszMenuName = NULL;
// Устанавливаем имя классу
wc. lpszClassName = L"Saper OpenGL Window Class";
// Пытаемся зарегистрировать класс окна
if(!RegisterClass(&wc))
{
// Неудачная попытка зарегистрировать класс
MessageBox( NULL, L"Failed To Register The Window Class.", L"ERROR", MB_OK | MB_ICONEXCLAMATION );
// Выход и возвращение функцией значения false
return false;
}
// Расширенный стиль окна
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
// Обычный стиль окна
dwStyle = WS_DLGFRAME;
// Подбирает окну подходящие размеры
AdjustWindowRectEx( &WindowRect, dwStyle, false, dwExStyle );
if(!( hWnd = CreateWindowEx(dwExStyle, // Расширенный стиль для окна
L"Saper OpenGL Window Class", // Имя класса
title, // Заголовок окна
WS_CLIPSIBLINGS | // Требуемый стиль для окна
WS_CLIPCHILDREN | // Требуемый стиль для окна
dwStyle, // Выбираемые стили для окна
0, 0, // Позиция окна
WindowRect. right - WindowRect. left, // Вычисление подходящей ширины
WindowRect. bottom - WindowRect. top, // Вычисление подходящей высоты
NULL, // Нет родительского
NULL, // Нет меню
hInstance, // Дескриптор приложения
NULL))) // Не передаём ничего до WM_CREATE
{
// Восстановить экран
KillGLWindow();
MessageBox( NULL, L"Window Creation Error.", L"ERROR", MB_OK | MB_ICONEXCLAMATION );
// Ошибка создания окна
return false;
}
HMENU hMenu = CreateMenu();
HMENU hPopMenuFile = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hPopMenuFile, L"Игра");
AppendMenu(hPopMenuFile, MF_STRING, 1021, L"Старт");
AppendMenu(hPopMenuFile, MF_STRING, 1022, L"Статистика");
AppendMenu(hPopMenuFile, MF_STRING, 1023, L"Выход");
SetMenu(hWnd, hMenu);
SetMenu(hWnd, hPopMenuFile);
static PIXELFORMATDESCRIPTOR pfd = // pfd сообщает Windows каким будет вывод на экран каждого пикселя
{
sizeof(PIXELFORMATDESCRIPTOR), // Размер дескриптора данного формата пикселей
1, // Номер версии
PFD_DRAW_TO_WINDOW | // Формат для Окна
PFD_SUPPORT_OPENGL | // Формат для OpenGL
PFD_DOUBLEBUFFER, // Формат для двойного буфера
PFD_TYPE_RGBA, // Требуется RGBA формат
bits, // Выбирается бит глубины цвета
0, 0, 0, 0, 0, 0, // Игнорирование цветовых битов
0, // Нет буфера прозрачности
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 |
Основные порталы (построено редакторами)

