Создание часов
#define _USE_MATH_DEFINES
#include <cmath>
#include <Windows.h>
#include "glut.h"
float xmax = 10;
float xmin = -10;
float ymax = 10;
float ymin = -10;
char buffer[10];
SYSTEMTIME localtime;
void drawString (char *s)
{
for (int i = 0; i < strlen (s); i++)
glutBitmapCharacter (GLUT_BITMAP_HELVETICA_10, s[i]);
}
void init()
{
glClearColor(1.0, 1.0, 1.0, 0.0);
gluOrtho2D(xmin, xmax, ymin, ymax);
}
void Circle(float r,float x=0, float y=0)
{
glPushMatrix();//запомнили систему координат
glBegin(GL_TRIANGLE_FAN);
glVertex2f(x, y);
for (float alfa=0;alfa<=2*M_PI;alfa+=2*M_PI/72)
glVertex2f(r*sin(alfa), r*cos(alfa));
glEnd();
glPopMatrix();//восстановили первоначальную систему
}
void Clock(SYSTEMTIME ltime)
{
glColor3f(0,0,0);
Circle(8,0,0);
//милисекунды
glPushMatrix();
glTranslatef(0,5,0);
glColor3f(0.9, 0.9, 0.9);
Circle(1,0,0);
glColor3f(1,0,0);
Circle(0.1, sin(M_PI*ltime.wMilliseconds/500), cos(M_PI*ltime.wMilliseconds/500));
glColor3f(0,0,0);
glBegin(GL_LINES);
for (float alfa=0;alfa<=2*M_PI;alfa+=2*M_PI/60)
{
glVertex2f(sin(alfa), cos(alfa));
glVertex2f(0.8*sin(alfa), 0.8*cos(alfa));
}
glEnd();
glPopMatrix();
//date
glPushMatrix();
glTranslatef(6,0,0);
glColor3f(1,1,1);
Circle(0.5,0,0);
glColor3f(0,0,0);
glRasterPos2f(-0.25, 0.1);
int dayweek = (int)(ltime.wDayOfWeek);
char* day = "SN";
if (dayweek==0) day="SN";
else if (dayweek==1) day="MN";
else if (dayweek==2) day="TU";
else if (dayweek==3) day="WN";
else if (dayweek==4) day="TH";
else if (dayweek==5) day="FR";
else if (dayweek==6) day="ST";
drawString(day);
glRasterPos2f(-0.1, -0.25);
drawString(gcvt ( (int)ltime.wDay, 2, buffer) );
glPopMatrix();
//
//часовая стрелка
glColor3f(1,0,0);
float h = (ltime.wSecond/60.+ltime.wMinute)/60.+ltime.wHour;
Circle(0.25, 4*sin(M_PI*h/6), 4*cos(M_PI*h/6));
glColor3f(1,1,1);
Circle(0.15, 4*sin(M_PI*h/6), 4*cos(M_PI*h/6));
//минутная стрелка
glColor3f(1,0,0);
Circle(0.2,6*sin(M_PI*ltime.wMinute/30), 6*cos(M_PI*ltime.wMinute/30));
glColor3f(1,1,1);
Circle(0.1,6*sin(M_PI*ltime.wMinute/30), 6*cos(M_PI*ltime.wMinute/30));
//секундная стрелка
glColor3f(1,0,0);
Circle(0.1,8*sin(M_PI*ltime.wSecond/30), 8*cos(M_PI*ltime.wSecond/30));
//центральная точка
glPointSize(8);
glColor3f(0,1,0);
glBegin(GL_POINTS);
glVertex2f(0, 0);
glEnd();
glPointSize(1);
glColor3f(1,1,1);
glBegin(GL_LINES);
for (float alfa=0;alfa<=2*M_PI;alfa+=2*M_PI/60)
{
glVertex2f(7.8*sin(alfa), 7.8*cos(alfa));
glVertex2f(7.3*sin(alfa), 7.3*cos(alfa));
}
glEnd();
glColor3f(0,1,0);
glBegin(GL_LINES);
for (float alfa=0;alfa<=2*M_PI;alfa+=2*M_PI/12)
{
glVertex2f(7.8*sin(alfa), 7.8*cos(alfa));
glVertex2f(7.3*sin(alfa), 7.3*cos(alfa));
}
glEnd();
}
void draw()
{
// очистка экрана цветом из буфера
glClear(GL_COLOR_BUFFER_BIT);
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
double aspectRatio = w / h;
//перед изменением размера окна необходимо сохранить систему координат
glLoadIdentity();
//расширяем картинку с учетом соотношения высоты экрана и ширины
gluOrtho2D( xmin*aspectRatio, xmax*aspectRatio, ymin, ymax);
//горизонтальная сетка
glColor3f(0.0, 1.0, 0.0);
glBegin(GL_LINES);
for (float x=xmin*aspectRatio;x<=xmax*aspectRatio;x+=xmax/10)
{
glVertex2f(x, ymax);
glVertex2f(x, ymin);
}
//вертикальная сетка
for (float y=ymin;y<=ymax;y+=ymax/10)
{
glVertex2f(xmax*aspectRatio, y);
glVertex2f(xmin*aspectRatio, y);
}
glEnd();
Clock(localtime);
glFlush();//нарисовать кадр
glutSwapBuffers();//смена буфера с кадром для плавной анимации
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
case VK_ESCAPE: exit(0);
}
void animate()
{
GetLocalTime(&localtime);
glutPostRedisplay();//перерисовать текущее окно
}
void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE);
glutInitWindowPosition(150, 50);
glutInitWindowSize(600,600);
glutCreateWindow("Clock easy");
init();
glutDisplayFunc(draw);
glutIdleFunc(animate);
glutKeyboardFunc(keyboard);
#ifdef SCREENSAVER
glutFullScreen();
#endif
glutMainLoop();
}
Дополнительные настройки проекта (Alt+F7)
Изменяем в Linker->Advanced строку Entry Pont и записываем mainCRTStartup,
чтобы скрыть окно консоли программы в конфигурации Release.
Изменяем в Linker->System строку SubSystem и выбираем Windows
Добавляем параметр с именем SCREENSAVER в разделе С/С++
Preprocessor->Preprocessor Definitions
Для самостоятельной работы:
1. Создайте часы с оригинальным дизайном;
2. Создайте электронные часы;
3. Создайте часы с видимым внутренним механизмом - скелетон;
4. Создайте часы с отображением фазы Луны.