capture feature
[censuslogo] / src / main_glut.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <assert.h>
4 #include <GL/glut.h>
5 #include "app.h"
6
7 static void display(void);
8 static void idle(void);
9 static void reshape(int x, int y);
10 static void keyb(unsigned char key, int x, int y);
11 static int save_image(const char *fname, unsigned char *pix, int xsz, int ysz);
12
13 static long start_time;
14 static int capture;
15 static long cap_frame_interval = 67;
16 static unsigned char *pixels;
17
18 int main(int argc, char **argv)
19 {
20         char *env;
21         unsigned int flags = GLUT_RGB | GLUT_DOUBLE;
22
23         glutInitWindowSize(1280, 800);
24         glutInit(&argc, argv);
25         if(app_parse_args(argc, argv) == -1) {
26                 return 1;
27         }
28
29 #ifdef MSAA
30         if(msaa) {
31                 flags |= GLUT_MULTISAMPLE;
32         }
33 #endif
34
35         glutInitDisplayMode(flags);
36         glutCreateWindow("census");
37
38         win_width = glutGet(GLUT_WINDOW_WIDTH);
39         win_height = glutGet(GLUT_WINDOW_HEIGHT);
40
41         if(fullscr) {
42                 glutFullScreen();
43                 glutSetCursor(GLUT_CURSOR_NONE);
44         }
45
46         glutDisplayFunc(display);
47         glutIdleFunc(idle);
48         glutReshapeFunc(reshape);
49         glutKeyboardFunc(keyb);
50
51         if((env = getenv("CAPFPS")) && (cap_frame_interval = atoi(env)) > 0) {
52                 cap_frame_interval = 1000 / cap_frame_interval;
53                 capture = 1;
54                 if(!(pixels = malloc(win_width * win_height * 3))) {
55                         fprintf(stderr, "failed to allocate frame capture buffer\n");
56                         return 1;
57                 }
58                 nloops = 1;
59         }
60
61         if(app_init() == -1) {
62                 return 1;
63         }
64         start_time = glutGet(GLUT_ELAPSED_TIME);
65
66         glutMainLoop();
67         return 0;
68 }
69
70 static void display(void)
71 {
72         if(capture) {
73                 msec += cap_frame_interval;
74         } else {
75                 msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
76         }
77
78         app_display();
79
80         if(capture) {
81                 static int frame;
82                 char buf[64];
83
84                 glReadPixels(0, 0, win_width, win_height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
85
86                 sprintf(buf, "frm%03d.ppm", frame++);
87                 save_image(buf, pixels, win_width, win_height);
88         }
89
90         glutSwapBuffers();
91         assert(glGetError() == GL_NO_ERROR);
92 }
93
94 static void idle(void)
95 {
96         glutPostRedisplay();
97 }
98
99 static void reshape(int x, int y)
100 {
101         app_reshape(x, y);
102         win_width = x;
103         win_height = y;
104 }
105
106 static void keyb(unsigned char key, int x, int y)
107 {
108         app_keyboard(key, 1);
109 }
110
111 void app_quit(void)
112 {
113         exit(0);
114 }
115
116 static int saved_width = 1280, saved_height = 800;
117
118 void app_fullscreen(void)
119 {
120         saved_width = win_width;
121         saved_height = win_height;
122         glutFullScreen();
123         glutSetCursor(GLUT_CURSOR_NONE);
124 }
125
126 void app_windowed(void)
127 {
128         glutReshapeWindow(saved_width, saved_height);
129         glutSetCursor(GLUT_CURSOR_INHERIT);
130 }
131
132 static int save_image(const char *fname, unsigned char *pix, int xsz, int ysz)
133 {
134         int i;
135         FILE *fp;
136
137         if(!(fp = fopen(fname, "wb"))) {
138                 fprintf(stderr, "failed to open %s for writing\n", fname);
139                 return -1;
140         }
141         fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
142
143         for(i=0; i<xsz * ysz; i++) {
144                 fputc(*pix++, fp);
145                 fputc(*pix++, fp);
146                 fputc(*pix++, fp);
147         }
148         fclose(fp);
149         return 0;
150 }