Created
April 24, 2013 21:49
-
-
Save tai2/5455867 to your computer and use it in GitHub Desktop.
Draw munching square. c.f. http://mathworld.wolfram.com/MunchingSquares.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <time.h> | |
| #include <GLUT/glut.h> | |
| #define KEY_ESC 27 | |
| #define WINDOW_POS_X 100 | |
| #define WINDOW_POS_Y 100 | |
| #define DEF_SCREEN_WIDTH 640 | |
| #define DEF_SCREEN_HEIGHT 360 | |
| #define UPDATE_PERIOD 16 | |
| static int curr_width = 0; | |
| static int curr_height = 0; | |
| static GLubyte *screen_buf = NULL; | |
| static int fullscreen = 0; | |
| static int n = 1; | |
| static int d = 1; | |
| static clock_t c_old = 0; | |
| static void | |
| keyboard(unsigned char c, int x, int y) | |
| { | |
| switch (c) { | |
| case KEY_ESC: | |
| exit(0); | |
| break; | |
| case 'f': | |
| if (fullscreen) { | |
| glutReshapeWindow(DEF_SCREEN_WIDTH, DEF_SCREEN_HEIGHT); | |
| glutPositionWindow(WINDOW_POS_X, WINDOW_POS_Y); | |
| fullscreen = 0; | |
| } else { | |
| glutFullScreen(); | |
| fullscreen = 1; | |
| } | |
| break; | |
| } | |
| } | |
| void | |
| idle() | |
| { | |
| glutPostRedisplay(); | |
| } | |
| static void | |
| reshape(int w, int h) | |
| { | |
| curr_width = w; | |
| curr_height = h; | |
| if (screen_buf) { | |
| free(screen_buf); | |
| } | |
| screen_buf = (GLubyte *)malloc(curr_width * curr_height * 4); | |
| if (!screen_buf) { | |
| abort(); | |
| } | |
| } | |
| static void | |
| draw_pixel(int x, int y, GLubyte r, GLubyte g, GLubyte b) | |
| { | |
| int base = 4 * ((curr_height - 1 - y) * curr_width + x); | |
| screen_buf[base + 0] = r; | |
| screen_buf[base + 1] = g; | |
| screen_buf[base + 2] = b; | |
| screen_buf[base + 3] = 255; | |
| } | |
| static void | |
| display() | |
| { | |
| int x, y; | |
| clock_t c_new; | |
| int plot, noplot; | |
| glClear(GL_COLOR_BUFFER_BIT); | |
| plot = 0; | |
| noplot = 0; | |
| for (y = 0; y < curr_height; y++) { | |
| for (x = 0; x < curr_width; x++) { | |
| if ((x^y) < n) { | |
| GLubyte v = 1 < n ? 255 * (n - 1 - (x^y)) / (n - 1) : 0; | |
| draw_pixel(x, y, v, v, v); | |
| plot = 1; | |
| } else { | |
| draw_pixel(x, y, 0, 0, 0); | |
| noplot = 1; | |
| } | |
| } | |
| } | |
| c_new = clock(); | |
| if (UPDATE_PERIOD < (1000 * (c_new - c_old) / CLOCKS_PER_SEC)) { | |
| c_old = c_new; | |
| n += d; | |
| if ((d == 1 && !noplot) || (d == -1) && !plot) { | |
| d = -d; | |
| } | |
| } | |
| glWindowPos2i(0, 0); | |
| glDrawPixels(curr_width, curr_height, GL_RGBA, GL_UNSIGNED_BYTE, screen_buf); | |
| glutSwapBuffers(); | |
| } | |
| int | |
| main(int argc, char** argv) | |
| { | |
| srand(0); | |
| glutInit(&argc, argv); | |
| glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ); | |
| glutInitWindowSize(DEF_SCREEN_WIDTH, DEF_SCREEN_HEIGHT); | |
| glutInitWindowPosition(WINDOW_POS_X, WINDOW_POS_Y); | |
| glutCreateWindow(argv[0]); | |
| glutKeyboardFunc(keyboard); | |
| glutIdleFunc(idle); | |
| glutReshapeFunc(reshape); | |
| glutDisplayFunc(display); | |
| glClearColor(0.0, 0.0, 0.0, 0.0); | |
| glShadeModel(GL_FLAT); | |
| c_old = clock(); | |
| glutMainLoop(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment