59 #pragma warning(push, 3) 70 #include <GLUT/glut.h> 81 static const std::string SGL_VERSION_NUMBER =
"0.9.5 (February 17, 2019)";
84 static bool glut_active =
false;
85 static bool event_loop_running =
false;
92 const int MAX_WINDOWS = 10;
94 static Window *window_list[] = {
109 static void GetOGLPos(
int x,
int y,
double *vec) {
111 GLdouble modelview[16];
112 GLdouble projection[16];
113 GLfloat winX, winY, winZ;
114 GLdouble posX, posY, posZ;
116 glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
117 glGetDoublev(GL_PROJECTION_MATRIX, projection);
118 glGetIntegerv(GL_VIEWPORT, viewport);
120 winX =
static_cast<float>(x);
121 winY =
static_cast<float>(viewport[3] - y);
122 glReadPixels(x, static_cast<int>(winY), 1, 1,
123 GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
125 gluUnProject(winX, winY, winZ, modelview, projection, viewport,
126 &posX, &posY, &posZ);
128 vec[0] = posX; vec[1] = posY; vec[2] = posZ;
131 static void convert(
int mx,
int my,
double &vx,
double &vy) {
133 double mouse_vector[3];
134 GetOGLPos(mx, my, mouse_vector);
135 vx = mouse_vector[0];
136 vy = mouse_vector[1];
152 static char *argv[] = {
const_cast<char *
>(
"sgl_program") };
153 glutInit(&argc, argv);
154 glutInitDisplayMode(mode);
158 std::cout <<
"Graphics environment already initialized\n";
201 return SGL_VERSION_NUMBER;
209 static void sgl_display() {
210 if (window_list[glutGetWindow()])
211 window_list[glutGetWindow()]->paint_all();
214 static void sgl_reshape(
int w,
int h) {
215 window_list[glutGetWindow()]->resized(w, h);
218 static void sgl_mouse_dragged(
int x,
int y) {
220 convert(x, y, vx, vy);
221 window_list[glutGetWindow()]->mouse_dragged(vx, vy);
225 static void sgl_mouse_moved(
int x,
int y) {
227 convert(x, y, vx, vy);
228 window_list[glutGetWindow()]->mouse_moved(vx, vy);
231 static void sgl_mouse_entry(
int state) {
232 if (state == GLUT_LEFT)
233 window_list[glutGetWindow()]->mouse_exited();
235 window_list[glutGetWindow()]->mouse_entered();
239 static void sgl_timer_expired(
int win_number) {
244 window_list[win_number]->timer_expired();
248 static void sgl_mouse_button(
int button,
int state,
int x,
int y) {
250 convert(x, y, vx, vy);
253 Window *win = window_list[glutGetWindow()];
257 if (state == GLUT_DOWN)
258 win->
mouse_pressed(vx, vy, static_cast<MouseButton>(button));
259 else if (state == GLUT_UP)
265 static void sgl_key_pressed(
unsigned char k,
int x,
int y) {
267 convert(x, y, vx, vy);
268 Window *win = window_list[glutGetWindow()];
273 static void sgl_special_key_pressed(
int k,
int x,
int y) {
275 convert(x, y, vx, vy);
276 Window *win = window_list[glutGetWindow()];
288 const Color RED(1.0, 0.0, 0.0);
289 const Color GREEN(0.0, 1.0, 0.0);
290 const Color BLUE(0.0, 0.0, 1.0);
291 const Color YELLOW(1.0, 1.0, 0.0);
292 const Color MAGENTA(1.0, 0.0, 1.0);
293 const Color CYAN(0.0, 1.0, 1.0);
294 const Color DARK_RED(0.75, 0.0, 0.0);
295 const Color DARK_GREEN(0.0, 0.75, 0.0);
296 const Color DARK_BLUE(0.0, 0.0, 0.75);
297 const Color LIGHT_RED(1.0, 0.75, 0.75);
298 const Color LIGHT_GREEN(0.75, 1.0, 0.75);
299 const Color LIGHT_BLUE(0.75, 0.75, 1.0);
300 const Color GRAY(0.5, 0.5, 0.5);
301 const Color LIGHT_GRAY(0.8, 0.8, 0.8);
302 const Color DARK_GRAY(0.2, 0.2, 0.2);
303 const Color WHITE(1.0, 1.0, 1.0);
312 double min_x,
double max_x,
double min_y,
double max_y) {
314 if (max_x - min_x <= 0 || max_y - min_y <= 0)
315 std::cout <<
"WARNING: Horizontal and/or vertical window dimensions " 316 <<
"zero or negative (check constructor arguments)\n";
322 glutInitWindowSize(width, height);
323 glutInitWindowPosition(left, top);
325 glutCreateWindow(title.c_str());
326 glClearColor(1.0, 1.0, 1.0, 0.0);
327 glShadeModel(GL_FLAT);
338 glutDisplayFunc(sgl_display);
339 glutReshapeFunc(sgl_reshape);
340 glutMotionFunc(sgl_mouse_dragged);
341 glutPassiveMotionFunc(sgl_mouse_moved);
342 glutMouseFunc(sgl_mouse_button);
343 glutEntryFunc(sgl_mouse_entry);
344 glutKeyboardFunc(sgl_key_pressed);
345 glutSpecialFunc(sgl_special_key_pressed);
351 window_list[glutGetWindow()] =
this;
361 Window::Window(
const std::string& title,
int left,
int top,
int width,
int height,
363 initialize(title, left, top, width, height, min_x, max_x, min_y, max_y);
367 initialize(title, 100, 100, width, height, 0.0, width, 0.0, height);
373 double width = max_x -
min_x,
374 height = max_y -
min_y;
375 int window_width, window_height;
378 if (width <= 0 || height <= 0) {
379 std::cout <<
"Window vertical or horizontal dimension zero " 380 <<
"or negative; check order of constructor arguments\n";
384 if (width > height) {
387 window_height =
static_cast<int>(600*height/width + 0.5);
392 window_width =
static_cast<int>(600*width/height + 0.5);
395 initialize(title, 100, 100, window_width, window_height,
396 min_x, max_x, min_y, max_y);
400 initialize(
"", 100, 100, 600, 600, 0.0, 0.0, 600.0, 600.0);
405 window_list[glutGetWindow()] =
nullptr;
417 glutPositionWindow(x, y);
428 glutReshapeWindow(width, height);
452 static_cast<CursorShape>(glutGet(GLUT_WINDOW_CURSOR));
453 glutSetCursor(static_cast<int>(cursor));
454 return previous_cursor;
462 return static_cast<CursorShape>(glutGet(GLUT_WINDOW_CURSOR));
467 double bottom,
double top) {
468 glMatrixMode(GL_PROJECTION);
470 gluOrtho2D(left, right, bottom, top);
474 glClearColor(static_cast<GLclampf>(color.
red),
475 static_cast<GLclampf>(color.
green),
476 static_cast<GLclampf>(color.
blue),
487 if (!event_loop_running) {
488 event_loop_running =
true;
492 std::cout <<
"Event loop already running, action ignored\n";
502 glColor3d(0.9, 0.9, 1.0);
503 for (
double x = 0 + x_inc; x <
max_x; x += x_inc)
505 for (
double y = 0 + y_inc; y <
max_y; y += y_inc)
507 for (
double x = -x_inc; x >
min_x; x -= x_inc)
509 for (
double y = -y_inc; y >
min_y; y -= y_inc)
512 glColor3d(0.0, 0.0, 0.0);
515 draw_line(min_x, 0.0, min_x + 5.0, -2.0);
517 draw_line(max_x, 0.0, max_x - 5.0, -2.0);
519 draw_line(0.0, min_y, -2.0, min_y + 5.0);
521 draw_line(0.0, max_y, -2.0, max_y - 5.0);
532 glClear(GL_COLOR_BUFFER_BIT);
536 glutSetWindowTitle(str.c_str());
550 glClear(GL_COLOR_BUFFER_BIT);
552 glColor3d(0.0, 0.2, 0.0);
564 return glutGet(GLUT_WINDOW_X);
569 return glutGet(GLUT_WINDOW_Y);
574 return glutGet(GLUT_WINDOW_WIDTH);
579 return glutGet(GLUT_WINDOW_HEIGHT);
599 glutReshapeWindow(w, h);
603 glutInitWindowSize(w, h);
604 glViewport (0, 0, static_cast<GLsizei>(w), static_cast<GLsizei>(h));
605 glMatrixMode(GL_PROJECTION);
609 glMatrixMode(GL_MODELVIEW);
642 if (key == F4_KEY && glutGetModifiers() == GLUT_ACTIVE_ALT)
677 glutTimerFunc(msec, sgl_timer_expired, glutGetWindow());
697 int width,
int height,
700 Window(title, left, top, width, height,
701 min_x, max_x, min_y, max_y),
702 active_object(nullptr) {}
705 int width,
int height):
706 Window(title, width, height),
707 active_object(nullptr) {}
712 Window(title, min_x, max_x, min_y, max_y),
713 active_object(nullptr) {}
719 window_list[glutGetWindow()] =
nullptr;
753 active_object =
hit(x, y);
754 if (prev_active != active_object) {
799 if (active_object == obj)
800 active_object =
nullptr;
811 active_object =
nullptr;
867 unsigned short Pixmap::get_short(std::ifstream& fin) {
881 ip |= ((
unsigned short)ic << 8);
893 unsigned long Pixmap::get_long(std::ifstream& fin) {
896 unsigned long ip = 0;
898 unsigned char uc = ic;
905 ip |=((
unsigned long)uc << 8);
909 ip |=((
unsigned long)uc << 16);
913 ip |=((
unsigned long)uc << 24);
925 bool Pixmap::power_of_2(
int n) {
926 return n == 1 || n == 2 || n == 4 || n == 8 || n == 16
927 || n == 32 || n ==64 || n == 128 || n == 256
928 || n == 512 || n == 1024 || n == 2048 || n == 4096
929 || n == 8192 || n == 16384 || n == 32768
930 || n == 65536 || n == 131072 || n == 262144
931 || n == 524288 || n == 1048576 || n == 2097152
932 || n == 4194304 || n == 8388608 || n == 16777216;
951 fin.open(fname, std::ios::in|std::ios::binary);
954 std::cout <<
" can't open file: " << fname <<
'\n';
964 unsigned long numCols = get_long(fin);
965 unsigned long numRows = get_long(fin);
967 unsigned short bitsPerPixel = get_short(fin);
975 if (bitsPerPixel != 24)
976 std::cout <<
"Not a 24 bit/pixelimage, or is compressed!\n";
979 if (!power_of_2(numRows) || !power_of_2(numCols))
980 std::cout <<
"Length of sides must be powers of two\n";
983 int nBytesInRow = ((3 * numCols + 3)/4) * 4,
984 numPadBytes = nBytesInRow - 3 * numCols;
991 pixel =
new RGB[nRows * nCols];
994 std::cout <<
"Out of memory!\n";
997 for (
int row = 0; row < nRows; row++) {
998 for (
int col = 0; col < nCols; col++) {
1005 pixel[count].red = r;
1006 pixel[count].green = g;
1007 pixel[count].blue = b;
1011 for(
int k = 0 ; k < numPadBytes ; k++)
1031 bool result =
false;
1034 pixel =
new RGB[3 * nRows * nCols];
1037 std::cout <<
"out of memory!\n";
1041 for (
int i = 0; i < nRows; i++) {
1042 for (
int j = 0; j < nCols; j++) {
1043 unsigned char c =
static_cast<unsigned char>((((i/8) + (j/8)) %2) * 255);
1044 pixel[count].red = c;
1045 pixel[count].green = c;
1046 pixel[count].blue = 0;
1055 void Pixmap::set_texture(GLuint textureName) {
1056 glBindTexture(GL_TEXTURE_2D, textureName);
1057 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1058 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1059 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nCols, nRows, 0, GL_RGB,
1060 GL_UNSIGNED_BYTE, pixel);
1084 glGenTextures(1, &texture_id);
1085 pix.set_texture(texture_id);
1092 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1093 glEnable(GL_TEXTURE_2D);
1094 glBindTexture(GL_TEXTURE_2D, texture_id);
1096 glTexCoord2f(0.0, 0.0); glVertex2d(
left,
bottom);
1101 glDisable(GL_TEXTURE_2D);
1119 CompositeObject::~CompositeObject() {
1147 double dx =
left - old_left, dy =
bottom - old_bottom;
1149 obj->move_to(obj->get_left() + dx, obj->get_bottom() + dy);
1179 width = (obj_right > right)? obj_right -
left : right -
left;
1180 height = (obj_top > top)? obj_top -
bottom : top -
bottom;
1206 Window(title, left, top, width, height) {}
1213 Window(title, 0.0, 0.0, 0.0, 0.0) {}
1476 double width = height/2.0,
1480 mid_left_x = x + 0.1*width,
1481 mid_right_x = x + 0.9 * width,
1482 top_left_x = x + 0.2 * width,
1483 bottom_right_x = x + 0.8 * width,
1484 offset = 0.14 * width,
1485 half_offset = 0.5 * offset,
1489 segment_a[0].x = top_left_x; segment_a[0].y =
max_y;
1490 segment_a[1].x =
max_x; segment_a[1].y =
max_y;
1491 segment_a[2].x =
max_x - offset; segment_a[2].y = max_y - offset;
1492 segment_a[3].x = top_left_x + offset; segment_a[3].y = max_y - offset;
1495 segment_b[0].x =
max_x; segment_b[0].y = max_y - inc;
1496 segment_b[1].x = mid_right_x; segment_b[1].y = mid_y + inc;
1497 segment_b[2].x = mid_right_x - offset; segment_b[2].y = mid_y + offset - inc;
1498 segment_b[3].x =
max_x - offset; segment_b[3].y = max_y - offset - inc;
1501 segment_c[0].x = mid_right_x; segment_c[0].y = mid_y - inc;
1502 segment_c[1].x = bottom_right_x; segment_c[1].y = y + inc;
1503 segment_c[2].x = bottom_right_x - offset; segment_c[2].y = y + offset + inc;
1504 segment_c[3].x = mid_right_x - offset; segment_c[3].y = mid_y - offset + inc;
1507 segment_d[0].x = x; segment_d[0].y = y;
1508 segment_d[1].x = bottom_right_x; segment_d[1].y = y;
1509 segment_d[2].x = bottom_right_x - offset; segment_d[2].y = y + offset;
1510 segment_d[3].x = x + offset; segment_d[3].y = y + offset;
1513 segment_e[0].x = x; segment_e[0].y = y + inc;
1514 segment_e[1].x = mid_left_x; segment_e[1].y = mid_y - inc;
1515 segment_e[2].x = mid_left_x + offset; segment_e[2].y = mid_y - offset + inc;
1516 segment_e[3].x = x + offset; segment_e[3].y = y + offset + inc;
1519 segment_f[0].x = mid_left_x; segment_f[0].y = mid_y + inc;
1520 segment_f[1].x = top_left_x; segment_f[1].y = max_y - inc;
1521 segment_f[2].x = top_left_x + offset; segment_f[2].y = max_y - offset - inc;
1522 segment_f[3].x = mid_left_x + offset; segment_f[3].y = mid_y + offset - inc;
1525 segment_g[0].x = mid_left_x; segment_g[0].y = mid_y;
1527 segment_g[1].x = mid_left_x + offset; segment_g[1].y = mid_y + half_offset;
1528 segment_g[2].x = mid_right_x - offset; segment_g[2].y = mid_y + half_offset;
1530 segment_g[3].x = mid_right_x; segment_g[3].y = mid_y;
1532 segment_g[4].x = mid_right_x - offset; segment_g[4].y = mid_y - half_offset;
1533 segment_g[5].x = mid_left_x + offset; segment_g[5].y = mid_y - half_offset;
1544 current_value(0), color(color), x(x), y(y), height(height) {
1802 tens(color, x, y, height),
1803 ones(color, x + height/2.0 + 2, y, height),
1804 leading_zero(true), visible(true) {
1925 leading_zeros(true),
visible(true) {
1926 double offset = height/2.0;
1927 for (
int i = 0; i < n; i++)
1956 const int divisor = 10;
1958 for (
int i = 0; i < n; i++) {
1959 digits[n - i - 1].set_value(value % divisor);
1972 for (
int i = n - 1; i >= 0; i--) {
1973 result +=
digits[i].get_value()*multiplier;
1980 void Multidigit::increment_helper(
int n) {
1984 increment_helper(n - 1);
1988 void Multidigit::decrement_helper(
int n) {
1992 decrement_helper(n - 1);
2001 increment_helper(
digits.size() - 1);
2009 decrement_helper(
digits.size() - 1);
2021 double offset =
digits[0].get_height()/2.0;
2022 for (
int i = 1; i < n; i++) {
2042 double offset =
height/2.0;
2043 for (
int i = 0; i < n; i++)
2060 double old_left =
left,
2063 double dx =
left - old_left,
2064 dy =
bottom - old_bottom;
2066 for (
int i = 0; i < n; i++)
2102 rect_width = width/8.0,
2103 x = (left_ones.
get_x() + width + right_tens.
get_x())/2.0 - rect_width/2.0;
2115 if ( hours_tens.get_value() > 0 )
2117 if (seconds >= 3600) {
2119 draw_separator(hours_ones, minutes_tens);
2122 if (seconds >= 3600 || minutes_tens.get_value() != 0)
2123 minutes_tens.paint();
2124 if (seconds >= 3600 || minutes_ones.get_value() != 0 || minutes_tens.get_value() != 0) {
2125 minutes_ones.paint();
2126 draw_separator(minutes_ones, seconds_tens);
2130 if (seconds >= 60 || seconds_tens.get_value() != 0)
2131 seconds_tens.paint();
2132 seconds_ones.paint();
2146 hours_tens(color, x, y, height),
2147 hours_ones(color, x + height/2.0, y, height),
2148 minutes_tens(color, x + 2*height/2.0 + height/4.0, y, height),
2149 minutes_ones(color, x + 3*height/2.0 + height/4.0, y, height),
2150 seconds_tens(color, x + 4*height/2.0 + 2*height/4.0, y, height),
2151 seconds_ones(color, x + 5*height/2.0 + 2*height/4.0, y, height),
2152 seconds(0), leading_units(true),
visible(true) {}
2195 sec = (sec < 0)? 0 : sec;
2339 double wd,
double ht):
2344 std::cout <<
"Making a graphical object #" <<
id <<
'\n';;
2370 std::cout <<
"Destroying graphical object #" <<
id <<
'\n';
2406 this->width =
width;
2546 unsigned GraphicalObject::id_source = 0;
2553 static PopupMenu *current_popup_menu =
nullptr;
2565 current_popup_menu =
this;
2566 glutAttachMenu(GLUT_RIGHT_BUTTON);
2572 glutAddMenuEntry(item.c_str(), items.size());
2573 items.push_back(
MenuItem(item, f));
2577 const std::string& new_name,
2580 int num_items = items.size();
2582 for (
int i = 0; i < num_items; i++)
2583 if (old_name == items[i].name) {
2584 items[i] = new_item;
2585 glutChangeToMenuEntry(i + 1, new_name.c_str(), i);
2593 std::cout <<
"remove_menu_item unimplemented at this time\n";
2602 current_popup_menu =
this;
2604 glutAttachMenu(GLUT_RIGHT_BUTTON);
2628 glLineWidth(static_cast<GLfloat>(width));
2651 return min_x_2 < max_x_1
2652 && max_x_2 > min_x_1
2653 && max_y_2 > min_y_1
2654 && min_y_2 < max_y_1;
2678 glVertex2d(pt.
x, pt.
y);
2687 glPointSize(static_cast<GLfloat>(point_size));
2695 void draw_line(
double x0,
double y0,
double x1,
double y1) {
2704 glLineStipple(1, static_cast<GLushort>(pattern));
2705 glEnable(GL_LINE_STIPPLE);
2710 glDisable(GL_LINE_STIPPLE);
2719 glBegin(GL_LINE_LOOP);
2721 glVertex2d(x + width, y);
2722 glVertex2d(x + width, y + height);
2723 glVertex2d(x, y + height);
2733 glBegin(GL_POLYGON);
2735 glVertex2d(x + width, y);
2736 glVertex2d(x + width, y + height);
2737 glVertex2d(x, y + height);
2741 static const double DEG_TO_RAD = 3.1415926/180.0;
2744 const int NUM_SEGMENTS = 360;
2745 glBegin(GL_LINE_LOOP);
2746 for (
int deg = 0; deg < NUM_SEGMENTS; deg++) {
2749 double theta = deg*DEG_TO_RAD;
2750 double edge_x = radius*cos(theta);
2751 double edge_y = radius*sin(theta);
2753 glVertex2d(x + edge_x, y + edge_y);
2761 const int NUM_SEGMENTS = 360;
2764 glBegin(GL_TRIANGLES);
2765 for(
int deg = 0; deg <= NUM_SEGMENTS; deg++) {
2766 double angle = deg*DEG_TO_RAD;
2767 double x2 = x + radius*sin(angle);
2768 double y2 = y + radius*cos(angle);
2780 glBegin(GL_LINE_LOOP);
2782 glVertex2d(p.x, p.y);
2797 glBegin(GL_LINE_LOOP);
2798 for (
int i = 0; i < n; i++)
2799 glVertex2d(pts[i].x, pts[i].y);
2807 glBegin(GL_POLYGON);
2809 glVertex2d(p.x, p.y);
2824 glBegin(GL_POLYGON);
2825 for (
int i = 0; i < n; i++)
2826 glVertex2d(pts[i].x, pts[i].y);
2830 void draw_text(
const std::string& text,
double x,
double y,
int font_size) {
2832 switch (font_size) {
2834 font = GLUT_BITMAP_HELVETICA_12;
2837 font = GLUT_BITMAP_HELVETICA_18;
2840 font = GLUT_BITMAP_9_BY_15;
2843 font = GLUT_BITMAP_8_BY_13;
2846 font = GLUT_BITMAP_HELVETICA_10;
2848 glRasterPos2d(x, y);
2849 const char *str = text.c_str();
2850 while (*str !=
'\0')
2851 glutBitmapCharacter(font, *str++);
2868 void draw_text(
const std::string& text,
double x,
double y,
double scale) {
2870 glTranslated(x, y, 0);
2871 glScaled(scale, scale, scale);
2872 const char *str = text.c_str();
2873 while (*str !=
'\0')
2874 glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, *str++);
2882 double begin_x,
double end_x,
2884 glBegin(GL_LINE_STRIP);
2885 for (
double x = begin_x; x <= end_x; x += increment)
2886 glVertex2d(x, f(x));
2902 return glutGet(GLUT_SCREEN_WIDTH);
2911 return glutGet(GLUT_SCREEN_HEIGHT);
2923 template <
typename T,
typename... Args>
2924 inline void run(Args&&... args) {
2939 template <
typename T,
typename... Args>
2941 return new T(args...);
2977 std::cout <<
"Stopwatch is not running\n";
2999 std::cout <<
"Error: Cannot reset a stopwatch that is running\n";
3007 while (clock() - start_time < msec)
3021 srand(static_cast<unsigned>(seed));
3027 int range = end - begin + 1;
3028 return rand() % range + begin;
3046 bool equals(
double d1,
double d2,
double delta) {
3047 return d1 == d2 || fabs(d1 - d2) < delta;
3087 void procedural_default_mouse_pressed_function(
double,
double,
MouseButton) {}
3088 void procedural_default_mouse_released_function(
double,
double,
MouseButton) {}
3089 void procedural_default_mouse_moved_function(
double,
double) {}
3090 void procedural_default_mouse_dragged_function(
double,
double) {}
3091 void procedural_default_key_pressed_function(
int,
double,
double) {}
3095 std::function<void()> paint_function;
3096 std::function<void(double, double, MouseButton)> mouse_pressed_function;
3097 std::function<void(double, double, MouseButton)> mouse_released_function;
3098 std::function<void(double, double)> mouse_moved_function;
3099 std::function<void(double, double)> mouse_dragged_function;
3100 std::function<void(int, double, double)> key_pressed_function;
3102 ProceduralWindow(
const std::string& title,
double x,
double y,
double width,
double height) :
3104 mouse_pressed_function(procedural_default_mouse_pressed_function),
3105 mouse_released_function(procedural_default_mouse_released_function),
3106 mouse_moved_function(procedural_default_mouse_moved_function),
3107 mouse_dragged_function(procedural_default_mouse_dragged_function),
3108 key_pressed_function(procedural_default_key_pressed_function) {}
3115 mouse_pressed_function(x, y, b);
3119 mouse_released_function(x, y, b);
3123 mouse_moved_function(x, y);
3127 mouse_dragged_function(x, y);
3131 key_pressed_function(k, x, y);
3140 static void exit_error(
const std::string& message) {
3141 std::cout << message <<
'\n';
3145 void create_window(
const std::string& title,
int x,
int y,
int width,
int height) {
3146 if (global_procedural_window)
3147 exit_error(
"An application can create only one graphics window");
3149 global_procedural_window = make_window<ProceduralWindow>(title, x, y, width, height);
3153 if (!global_procedural_window)
3154 exit_error(
"Cannot run_window: No graphics window exists (use create_window)");
3155 global_procedural_window->run();
3159 if (!global_procedural_window)
3160 exit_error(
"Cannot update_window: No graphics window exists (use create_window)");
3161 global_procedural_window->
repaint();
3165 if (!global_procedural_window)
3166 exit_error(
"Cannot set_paint_function: No graphics window exists (use create_window)");
3167 global_procedural_window->paint_function = f;
3171 if (!global_procedural_window)
3172 exit_error(
"Cannot set_mouse_pressed_function: No graphics window exists (use create_window)");
3173 global_procedural_window->mouse_pressed_function = f;
3178 if (!global_procedural_window)
3179 exit_error(
"Cannot set_mouse_released_function: No graphics window exists (use create_window)");
3180 global_procedural_window->mouse_released_function = f;
3184 if (!global_procedural_window)
3185 exit_error(
"Cannot set_mouse_moved_function: No graphics window exists (use create_window)");
3186 global_procedural_window->mouse_moved_function = f;
3190 if (!global_procedural_window)
3191 exit_error(
"Cannot set_mouse_dragged_function: No graphics window exists (use create_window)");
3192 global_procedural_window->mouse_dragged_function = f;
3196 if (!global_procedural_window)
3197 exit_error(
"Cannot set_key_pressed_function: No graphics window exists (use create_window)");
3198 global_procedural_window->key_pressed_function = f;
3202 if (!global_procedural_window)
3203 exit_error(
"Cannot set_window_background: No graphics window exists (use create_window)");
3208 if (!global_procedural_window)
3209 exit_error(
"Cannot set_window_title: No graphics window exists (use create_window)");
3210 global_procedural_window->
set_title(str);
3218 #pragma warning(pop) void remove(GraphicalObject *obj)
Definition: sgl.hpp:796
virtual void timer_expired()
Definition: sgl.hpp:681
CursorShape cursor
Definition: sgl.h:259
void mouse_dragged(double x, double y) override
Definition: sgl.hpp:768
void mouse_pressed(double x, double y, MouseButton b) override
Definition: sgl.hpp:3114
TimeDisplay(Color color, double x, double y, int height)
Definition: sgl.hpp:2144
virtual void clear()
Definition: sgl.hpp:531
KeyModifier
Definition: sgl.h:209
virtual int get_width() const
Definition: sgl.hpp:573
void draw_dashed_line(double x0, double y0, double x1, double y1, int pattern=0x00FF)
Definition: sgl.hpp:2702
SevenSegmentDigit seconds_ones
Definition: sgl.h:1950
void mouse_released(double x, double y, MouseButton button) override
Definition: sgl.hpp:742
virtual void start_timer(int msec)
Definition: sgl.hpp:676
virtual double get_min_y() const
Definition: sgl.hpp:590
void set_random_seed(int seed=-1)
Definition: sgl.hpp:3017
~OGLWindow()
Definition: sgl.hpp:1217
void prepaint() override
Definition: sgl.hpp:724
virtual void set_visible(bool visible)
Definition: sgl.hpp:438
int get_value() const
Definition: sgl.hpp:1665
int get_value() const
Definition: sgl.hpp:1968
void postpaint() override
Definition: sgl.hpp:1229
virtual void mouse_dragged(double x, double y)
Definition: sgl.hpp:2435
void move_to(double x, double y)
Definition: sgl.hpp:1703
void set_mouse_dragged_function(const std::function< void(double, double)> &f)
Definition: sgl.hpp:3189
void initialize(const std::string &title, int left, int top, int width, int height, double min_x, double max_x, double min_y, double max_y)
Definition: sgl.hpp:311
MouseButton
Definition: sgl.h:134
bool visible
Definition: sgl.h:1961
void draw_line(double x0, double y0, double x1, double y1)
Definition: sgl.hpp:2695
double min_x
Definition: sgl.h:525
void mouse_pressed(double x, double y, MouseButton button) override
Definition: sgl.hpp:734
void reset()
Definition: sgl.hpp:2995
void set_leading_zeros(bool flag)
Definition: sgl.hpp:2077
virtual CursorShape get_cursor()
Definition: sgl.hpp:461
void set_value(int value)
Definition: sgl.hpp:1738
virtual int get_x() const
Definition: sgl.hpp:563
Color color
Definition: sgl.h:1536
DoubleDigit(Color color, double x, double y, double height)
Definition: sgl.hpp:1800
virtual void draw_axes(double x_inc, double y_inc) const
Definition: sgl.hpp:500
virtual int get_y() const
Definition: sgl.hpp:568
virtual void move_to(double left, double bottom)
Definition: sgl.hpp:2441
SevenSegmentDigit minutes_ones
Definition: sgl.h:1944
ObjectWindow()
Definition: sgl.hpp:715
void paint() const
Definition: sgl.hpp:1091
void mouse_dragged(double x, double y) override
Definition: sgl.hpp:1882
virtual double get_height() const
Definition: sgl.hpp:2387
void key_pressed(int k, double x, double y) override
Definition: sgl.hpp:775
void resize(double inc)
Definition: sgl.hpp:2018
double left
Definition: sgl.h:243
virtual double get_width() const
Definition: sgl.hpp:2383
bool visible
Definition: sgl.h:1834
void mouse_dragged(double x, double y) override
Definition: sgl.hpp:1786
void increment()
Definition: sgl.hpp:2000
std::string version()
Definition: sgl.hpp:200
bool leading_zeros
Definition: sgl.h:1830
void paint() const override
Definition: sgl.hpp:1725
double max_x
Definition: sgl.h:529
void fill_circle(double x, double y, double radius)
Definition: sgl.hpp:2760
void set_window_background(const Color &c)
Definition: sgl.hpp:3201
Stopwatch()
Definition: sgl.hpp:2951
DisplayDigit(Color color, double x, double y, double height)
Definition: sgl.hpp:1719
int get_value() const
Definition: sgl.hpp:1835
~ObjectWindow()
Definition: sgl.hpp:718
void draw_rectangle(double x, double y, double width, double height)
Definition: sgl.hpp:2717
int get_value() const
Definition: sgl.hpp:2219
Window()
Definition: sgl.hpp:399
clock_t start_time
Definition: sgl.h:2431
CompositeObject()
Definition: sgl.hpp:1112
void set_value(int sec)
Definition: sgl.hpp:2192
virtual void mouse_released(double x, double y, MouseButton button)
Definition: sgl.hpp:621
virtual CursorShape set_cursor(CursorShape cursor)
Definition: sgl.hpp:2528
void move_to(double x, double y) override
Definition: sgl.hpp:2296
SevenSegmentDigit ones
Definition: sgl.h:1729
virtual Window * get_window() const
Definition: sgl.hpp:2519
virtual void mouse_moved(double x, double y)
Definition: sgl.hpp:2491
virtual void set_mouse_over(bool flag)
Definition: sgl.hpp:2446
void internal_add(GraphicalObject *obj)
Definition: sgl.hpp:785
virtual void repaint()
Definition: sgl.hpp:539
virtual void set_size(int width, int height)
Definition: sgl.hpp:427
double x
Definition: sgl.h:1539
void mouse_released(double x, double y, MouseButton b) override
Definition: sgl.hpp:3118
virtual void postpaint()
Definition: sgl.hpp:555
SevenSegmentDigit tens
Definition: sgl.h:1726
virtual double get_max_x() const
Definition: sgl.hpp:586
void set_paint_function(const std::function< void()> &f)
Definition: sgl.hpp:3164
void set_value(int value)
Definition: sgl.hpp:1955
SevenSegmentDigit minutes_tens
Definition: sgl.h:1941
void remove_all()
Definition: sgl.hpp:807
void set_window_title(const std::string &str)
Definition: sgl.hpp:3207
void update_window()
Definition: sgl.hpp:3158
void resize(double inc)
Definition: sgl.hpp:1865
std::vector< GraphicalObject * > objects
Definition: sgl.h:1309
void set_visible(bool flag)
Definition: sgl.hpp:2087
double y_hit_offset
Definition: sgl.h:239
GraphicalObject * hit(double x, double y) const
Definition: sgl.hpp:818
void move_to(double x, double y) override
Definition: sgl.hpp:1144
std::function< void()> MenuItemFunction
Definition: sgl.h:968
void draw_separator(const SevenSegmentDigit &left_ones, const SevenSegmentDigit &right_tens) const
Definition: sgl.hpp:2099
virtual double get_left() const
Definition: sgl.hpp:2375
virtual ~GraphicalObject()
Definition: sgl.hpp:2369
virtual void mouse_entered()
Definition: sgl.hpp:628
void update_segment_locations()
Definition: sgl.hpp:1475
bool leading_zero
Definition: sgl.h:1733
virtual int get_height() const
Definition: sgl.hpp:578
BitmapObject(const char *filename, double x, double y, double width, double height)
Definition: sgl.hpp:1081
void draw_function(double(*f)(double), double begin_x, double end_x, double delta)
Definition: sgl.hpp:2881
double width
Definition: sgl.h:251
void set_leading_units(bool flag)
Definition: sgl.hpp:2315
void set_line_width(double width)
Definition: sgl.hpp:2627
virtual void prepaint()
Definition: sgl.hpp:549
virtual void paint_all()
Definition: sgl.hpp:543
int random(int begin, int end)
Definition: sgl.hpp:3026
void set_visible(bool flag)
Definition: sgl.hpp:2325
void decrement()
Definition: sgl.hpp:1681
double x_hit_offset
Definition: sgl.h:235
virtual void mouse_released(double x, double y, MouseButton button)
Definition: sgl.hpp:2478
void increment()
Definition: sgl.hpp:1673
void resize(double inc)
Definition: sgl.hpp:1773
double get_x() const
Definition: sgl.hpp:1552
clock_t end_time
Definition: sgl.h:2434
void postpaint() override
Definition: sgl.hpp:728
ObjectWindow * window
Definition: sgl.h:231
void resize(double inc)
Definition: sgl.hpp:1691
virtual void set_position(int x, int y)
Definition: sgl.hpp:416
virtual void mouse_pressed(double x, double y, MouseButton button)
Definition: sgl.hpp:619
double get_height() const
Definition: sgl.hpp:1568
void set_mouse_moved_function(const std::function< void(double, double)> &f)
Definition: sgl.hpp:3183
T * make_window(Args &&... args)
Definition: sgl.hpp:2940
void stop()
Definition: sgl.hpp:2971
KeyModifier key_mods
Definition: sgl.h:545
void fill_rectangle(double x, double y, double width, double height)
Definition: sgl.hpp:2732
double height
Definition: sgl.h:1542
void paint() const override
Definition: sgl.hpp:1932
virtual void set_background_color(const Color &color)
Definition: sgl.hpp:473
std::vector< GraphicalObject * >::iterator begin()
Definition: sgl.hpp:831
void prepaint() override
Definition: sgl.hpp:1223
void procedural_default_paint_function()
Definition: sgl.hpp:3086
void set_mouse_released_function(const std::function< void(double, double, MouseButton)> &f)
Definition: sgl.hpp:3177
virtual void key_pressed(int k, double x, double y)
Definition: sgl.hpp:641
void increment()
Definition: sgl.hpp:2227
OGLWindow(const std::string &title, int left, int top, int width, int height)
Definition: sgl.hpp:1204
void mouse_moved(double x, double y) override
Definition: sgl.hpp:3122
void increment()
Definition: sgl.hpp:1755
virtual double get_bottom() const
Definition: sgl.hpp:2379
SevenSegmentDigit led
Definition: sgl.h:1656
SevenSegmentDigit hours_ones
Definition: sgl.h:1938
void paint_without_leading_units() const
Definition: sgl.hpp:2114
void create_window(const std::string &title, int x, int y, int width, int height)
Definition: sgl.hpp:3145
void internal_add(GraphicalObject *obj)
Definition: sgl.hpp:1161
virtual CursorShape set_cursor(CursorShape cursor)
Definition: sgl.hpp:450
void draw_circle(double x, double y, double radius)
Definition: sgl.hpp:2743
SevenSegmentDigit(Color color, double x, double y, double height)
Definition: sgl.hpp:1543
void increment()
Definition: sgl.hpp:1843
void set_color(const Color &color)
Definition: sgl.hpp:2619
void start()
Definition: sgl.hpp:2959
void paint() const
Definition: sgl.hpp:1575
int get_value() const
Definition: sgl.hpp:1746
virtual CursorShape get_cursor()
Definition: sgl.hpp:2540
const unsigned id
Definition: sgl.h:268
double x
Definition: sgl.h:77
void paint() const override
Definition: sgl.hpp:1809
void set_key_pressed_function(const std::function< void(int, double, double)> &f)
Definition: sgl.hpp:3195
bool make_checkerboard()
Definition: sgl.hpp:1030
bool equals(double d1, double d2, double delta)
Definition: sgl.hpp:3046
void set_mouse_pressed_function(const std::function< void(double, double, MouseButton)> &f)
Definition: sgl.hpp:3170
double elapsed() const
Definition: sgl.hpp:2985
virtual void set_title(const std::string &str)
Definition: sgl.hpp:535
bool visible
Definition: sgl.h:1737
virtual void mouse_exited()
Definition: sgl.hpp:635
void set_visible(bool flag)
Definition: sgl.hpp:1904
int seconds
Definition: sgl.h:1953
virtual void set_viewport(double left, double right, double bottom, double top)
Definition: sgl.hpp:466
void decrement()
Definition: sgl.hpp:2008
void paint() override
Definition: sgl.hpp:3110
double bottom
Definition: sgl.h:247
double y
Definition: sgl.h:80
void pause(int msec)
Definition: sgl.hpp:3004
void set_leading_zero(bool flag)
Definition: sgl.hpp:1894
void mouse_dragged(double x, double y) override
Definition: sgl.hpp:2275
virtual void set_window_size(int w, int h)
Definition: sgl.hpp:598
double get_y() const
Definition: sgl.hpp:1560
void set_value(int value)
Definition: sgl.hpp:1826
virtual void mouse_pressed(double x, double y, MouseButton button)
Definition: sgl.hpp:2463
void decrement()
Definition: sgl.hpp:1853
double height
Definition: sgl.h:255
SevenSegmentDigit seconds_tens
Definition: sgl.h:1947
std::vector< GraphicalObject * > object_list
Definition: sgl.h:1073
void mouse_moved(double x, double y) override
Definition: sgl.hpp:751
virtual Window * set_window(ObjectWindow *win)
Definition: sgl.hpp:2513
void mouse_dragged(double x, double y) override
Definition: sgl.hpp:2039
void resize(double inc)
Definition: sgl.hpp:2245
virtual bool hit(double x, double y)
Definition: sgl.hpp:2414
int get_screen_width()
Definition: sgl.hpp:2901
virtual void mouse_moved(double x, double y)
Definition: sgl.hpp:615
CursorShape
Definition: sgl.h:171
bool running
Definition: sgl.h:2437
double max_y
Definition: sgl.h:537
void draw_polygon(const std::vector< Point > &pts)
Definition: sgl.hpp:2779
virtual double get_max_y() const
Definition: sgl.hpp:594
int current_value
Definition: sgl.h:1533
virtual void set(double x, double y, double width, double height)
Definition: sgl.hpp:2402
double red
Definition: sgl.h:101
void fill_polygon(const std::vector< Point > &pts)
Definition: sgl.hpp:2806
bool intersect(const GraphicalObject &obj1, const GraphicalObject &obj2)
Definition: sgl.hpp:2639
void run(Args &&... args)
Definition: sgl.hpp:2924
void decrement()
Definition: sgl.hpp:1763
void initialize_graphics(unsigned int mode)
Definition: sgl.hpp:148
void paint() const override
Definition: sgl.hpp:2159
double green
Definition: sgl.h:103
CursorShape normal_cursor
Definition: sgl.h:540
Multidigit(int n, Color color, double x, double y, double height)
Definition: sgl.hpp:1920
virtual double get_min_x() const
Definition: sgl.hpp:582
GraphicalObject(double left, double bottom, double width, double height)
Definition: sgl.hpp:2338
bool mouse_over
Definition: sgl.h:263
void draw_text(const std::string &text, double x, double y, int font_size)
Definition: sgl.hpp:2830
void key_pressed(int k, double x, double y) override
Definition: sgl.hpp:3130
virtual ~Window()
Definition: sgl.hpp:403
KeyModifier get_key_modifiers() const
Definition: sgl.hpp:668
int get_screen_height()
Definition: sgl.hpp:2910
void run_window()
Definition: sgl.hpp:3152
void mouse_dragged(double x, double y) override
Definition: sgl.hpp:3126
double blue
Definition: sgl.h:105
virtual void move_to(double left, double bottom) override
Definition: sgl.hpp:2059
double min_y
Definition: sgl.h:533
bool leading_units
Definition: sgl.h:1957
std::vector< GraphicalObject * >::iterator end()
Definition: sgl.hpp:841
void draw_point(double x, double y)
Definition: sgl.hpp:2662
virtual void mouse_dragged(double x, double y)
Definition: sgl.hpp:617
void set_key_modifiers(KeyModifier mod)
Definition: sgl.hpp:672
virtual void resized(int w, int h)
Definition: sgl.hpp:602
virtual void key_pressed(int k, double x, double y)
Definition: sgl.hpp:2508
void decrement()
Definition: sgl.hpp:2235
SevenSegmentDigit hours_tens
Definition: sgl.h:1935
void paint() const override
Definition: sgl.hpp:1130
bool read_BMP_file(const char *fname)
Definition: sgl.hpp:942
std::vector< SevenSegmentDigit > digits
Definition: sgl.h:1823
void set_point_size(int point_size)
Definition: sgl.hpp:2686
void set_value(int value)
Definition: sgl.hpp:1657