|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/* File name: TASK00.C * OpenGL/Glut example. * For lessons purpose. * Sample # 00: simple pattern. * Written by Vitaly A. Galinsky. */ /*** * Макет типичной программы, использующей GLUT * Все прикладные переменные и функции, для однозначности, * начинаются с префикса 'TSK_' ***/ /* Включение файла-заголовка библиотеки GLUT */ #include <glut.h> /* Включение файла-заголовка функций Windows */ #include <windows.h> /* Включение файла-заголовка стандартных функций ввода-вывода */ #include <stdio.h> /* Включение файла-заголовка стандартных функций (для 'exit') */ #include <stdlib.h> /* Включение файла-заголовка стандартных математических функций */ #include <math.h> /* Включение файла-заголовка стандартных функций работы со временем */ #include <time.h> /* Переменная, хранящая время в секундах с момента старта программы */ double TSK_SyncTime; /* Переменная, хранящая количество отрисованных кадров для подсчета FPS - frames-per-second */ long TSK_FrameCount; /* Переменные для запоминания размеров окна */ int TSK_Width, TSK_Height; /* Переменные для запоминания позиции мышки */ double TSK_MX, TSK_MY; /* Переменная для запоминания нажатия кнопок мышки */ int TSK_MButtons; /* Заголовок окна */ char TSK_Title[] = "GLUT sample. Task 00."; /* Стандартная функция, вызываемая при изменении размера окна */ void Reshape( int Width, int Height ) { /* Устанавливаем область просмотра - все окно и запоминаем размеры окна вывода */ glViewport(0, 0, TSK_Width = Width, TSK_Height = Height); /* Устанавливаем систему координат "камеры" - для просмотра 2-мерных изображений */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (Width > Height) gluOrtho2D(-100 * (double)Width / Height, 100 * (double)Width / Height, -100, 100); else gluOrtho2D(-100, 100, -100 * (double)Height / Width, 100 * (double)Height / Width); /* Устанавливаем "мировую" систему координат в состояние без преобразований */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /* End of 'Reshape' function */ /* Стандартная функция, вызываемая при перерисовке окна */ void Display( void ) { /* Очищаем цветовой буфер для создания нового изображения */ glClear(GL_COLOR_BUFFER_BIT); /* Рисуем "фигуру" */ glPushMatrix(); glColor3d(1, 1, 1); glRotated(30 * sin(3 * TSK_SyncTime), 0, 0, 1); glTranslated(0, -50, 0); glRectd(-50, -50, 50, 50); glPopMatrix(); /* Рисуем "точку" с мышкой */ if (TSK_MButtons == 1) glColor3d(1, 0, 0); else glColor3d(0, 1, 1); glBegin(GL_LINES); glVertex2d(TSK_MX - 10, TSK_MY - 10); glVertex2d(TSK_MX + 10, TSK_MY + 10); glVertex2d(TSK_MX - 10, TSK_MY + 10); glVertex2d(TSK_MX + 10, TSK_MY - 10); glEnd(); /* Отрисовываем накопившиеся в очереди операции и копируем вторичный буфер в окно */ glFlush(); glutSwapBuffers(); TSK_FrameCount++; } /* End of 'Display' function */ /* Стандартная функция, вызываемая при "простое" процессора */ void Idle( void ) { long Time; static long OldTime = -1, StartTime; static char Buf[100]; if (OldTime == -1) StartTime = OldTime = clock(); else { Time = clock(); TSK_SyncTime = (double)(Time - StartTime) / CLOCKS_PER_SEC; Time = Time - OldTime; if (Time > CLOCKS_PER_SEC) { OldTime = clock(); sprintf(Buf, "%s FPS: %.3f", TSK_Title, TSK_FrameCount / ((double)Time / CLOCKS_PER_SEC)); TSK_FrameCount = 0; glutSetWindowTitle(Buf); } } /* Вызываем функцию обновления кадра */ glutPostRedisplay(); } /* End of 'Idle' function */ /* Стандартная функция, вызываемая при нажатии клавиш на клавиатуре */ void Keyboard( unsigned char Key, int MouseX, int MouseY ) { /* 'Key' принимает значение нажатой клавиши ('A', 'e' и т.п.), * код клавиши 'ESC' (escape) - 27 * 'MouseX' и 'MouseY' - значение координат мышки во время нажатия */ if (Key == 27) exit(0); /* Выход по клавише 'Escape' - стандартной функцией 'exit'*/ } /* End of 'Keyboard' function */ /* Стандартная функция, вызываемая при нажатии специальных клавиш на клавиатуре */ void SpecialKeyboard( int Key, int MouseX, int MouseY ) { static int IsFullScreen = 0, SaveW, SaveH; /* 'Key' принимает значение нажатой специальных клавиш: * GLUT_KEY_F1, ...F12 - функциональные клавиши, а также * GLUT_KEY_LEFT, GLUT_KEY_UP, GLUT_KEY_RIGHT, GLUT_KEY_DOWN, * GLUT_KEY_PAGE_UP, GLUT_KEY_PAGE_DOWN, GLUT_KEY_HOME, * GLUT_KEY_END, GLUT_KEY_INSERT * 'MouseX' и 'MouseY' - значение координат мышки во время нажатия */ if (Key == GLUT_KEY_F1) MessageBox(NULL, "Пример использования библиотеки OpenGL/GLUT\n\n" "Для выхода из программы - нажмите <ESCAPE>\n" "Для переключения полноэкранного режима - нажмите F2", "ПОМОЩЬ", MB_ICONINFORMATION | MB_OK); else if (Key == GLUT_KEY_F2) { if (IsFullScreen) /* Восстанавливаем размеры окна */ glutReshapeWindow(SaveW, SaveH); else { SaveW = TSK_Width; SaveH = TSK_Height; /* Переходим в полноэкранный режим */ glutFullScreen(); } IsFullScreen = !IsFullScreen; } } /* End of 'SpecialKeyboard' function */ /* Стандартная функция, вызываемая при нажатии кнопки мышки */ void Mouse( int Button, int State, int MouseX, int MouseY ) { /* 'Button' принимает значения: * GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, GLUT_RIGHT_BUTTON * 'State' принимает значения: * GLUT_DOWN, GLUT_UP * 'MouseX' и 'MouseY' - координаты курсора мышки относительно * левого-верхнего угла окна */ if (Button == GLUT_LEFT_BUTTON) { if (State == GLUT_DOWN) TSK_MButtons = 1; else TSK_MButtons = 0; } } /* End of 'Mouse' function */ /* Стандартная функция, вызываемая при перемещении мышки */ void Motion( int MouseX, int MouseY ) { double wz; int Viewport[4]; static double ModelMatrix[16], ProjectMatrix[16]; /* 'MouseX' и 'MouseY' - координаты курсора мышки относительно * левого-верхнего угла окна */ printf("Mouse coordinates: X %4i Y %4i\r", MouseX, MouseY); /* Получаем марицы преобразований и область просмотра */ glGetDoublev(GL_MODELVIEW_MATRIX, ModelMatrix); glGetDoublev(GL_PROJECTION_MATRIX, ProjectMatrix); glGetIntegerv(GL_VIEWPORT, Viewport); /* Преобразуем координаты мышки в "мировые" коорлдинаты */ gluUnProject(MouseX, TSK_Height - 1 - MouseY, 0, ModelMatrix, ProjectMatrix, Viewport, &TSK_MX, &TSK_MY, &wz); } /* End of 'Motion' function */ /* Вспомогательная функция инициализации, сюда помещаем все предварительные * установки построения изображений */ void Init( void ) { /* Устанавливаем цвет закраски фона в черный */ glClearColor(0, 0, 0, 0); } /* End of 'Init' function */ /* Главная функция программы */ void main( void ) { /* Изменение заголовка консоли (убрать консоль: 'FreeConsole();' */ SetConsoleTitle(TSK_Title); /* Инициализация библиотеки: * параметр - комбинация значений (с помощью побитовой операции или '|'): * GLUT_DOUBLE - двойная буферизация (альтернатива - GLUT_SINGLE - рисуем прямо в окно) * GLUT_RGB - режим задания цвета по значениям красно, зеленой и синей компонент * GLUT_ALPHA - включение возможности использования буфера прозрачности * GLUT_DEPTH - включение буфера глубины - для удаления невидимых поверхностей */ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); /* Задаем размеры и позицию окна */ glutInitWindowSize(TSK_Width = 400, TSK_Height = 400); glutInitWindowPosition(0, 0); /* Создаем окно */ glutCreateWindow(TSK_Title); /* Инициализация собственных параметров отображения */ Init(); /* Установка функций 'обратного вызова' */ glutReshapeFunc(Reshape); glutDisplayFunc(Display); glutIdleFunc(Idle); glutKeyboardFunc(Keyboard); glutSpecialFunc(SpecialKeyboard); glutMouseFunc(Mouse); glutMotionFunc(Motion); /* перемещение с любой нажатой клавишей */ glutPassiveMotionFunc(Motion); /* перемещение с ненажатыми клавишами */ /* Запускаем основной цикл построения */ glutMainLoop(); } /* End of 'main' function */ /* END OF 'TASK00.C' FILE */ /* GLUT pre-built models sub-API (glut.h) */ /* void glutWireSphere( double radius, int slices, int stacks ); void glutSolidSphere( double radius, int slices, int stacks ); void glutWireCone( double base, double height, int slices, int stacks ); void glutSolidCone( double base, double height, int slices, int stacks ); void glutWireCube( double size ); void glutSolidCube( double size ); void glutWireTorus( double innerRadius, double outerRadius, int sides, int rings ); void glutSolidTorus( double innerRadius, double outerRadius, int sides, int rings ); void glutWireDodecahedron( void ); void glutSolidDodecahedron( void ); void glutWireTeapot( double size ); void glutSolidTeapot( double size ); void glutWireOctahedron( void ); void glutSolidOctahedron( void ); void glutWireTetrahedron( void ); void glutSolidTetrahedron( void ); void glutWireIcosahedron( void ); void glutSolidIcosahedron( void ); */ |
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|