capture feature screensaver
authorJohn Tsiombikas <jtsiomb@census.gr>
Thu, 12 Sep 2019 12:21:45 +0000 (15:21 +0300)
committerJohn Tsiombikas <jtsiomb@census.gr>
Thu, 12 Sep 2019 12:21:45 +0000 (15:21 +0300)
src/app.c
src/app.h
src/main_glut.c

index 8c4b6dd..7f6ed9f 100644 (file)
--- a/src/app.c
+++ b/src/app.c
@@ -48,6 +48,12 @@ void app_display(void)
        glLineWidth(5.0);
 
        anim = fmod(t / 6.0f, LOOPTIME);
+
+       if(nloops > 0 && (anim < t / 6.0f)) {
+               app_quit();
+               return;
+       }
+
        alpha = 1.0f - ((anim - (LOOPTIME - 0.075)) / 0.06f);
        if(alpha < 0.0f) alpha = 0.0f;
        if(alpha > 1.0f) alpha = 1.0f;
index 70f89ed..b93c6b7 100644 (file)
--- a/src/app.h
+++ b/src/app.h
@@ -9,6 +9,7 @@ int nverts;
 int msaa;
 int fullscr;
 long msec;
+int nloops;
 
 int app_init(void);
 void app_display(void);
index 2cd51ef..73cab31 100644 (file)
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <GL/glut.h>
@@ -7,13 +8,19 @@ static void display(void);
 static void idle(void);
 static void reshape(int x, int y);
 static void keyb(unsigned char key, int x, int y);
+static int save_image(const char *fname, unsigned char *pix, int xsz, int ysz);
 
 static long start_time;
+static int capture;
+static long cap_frame_interval = 67;
+static unsigned char *pixels;
 
 int main(int argc, char **argv)
 {
+       char *env;
        unsigned int flags = GLUT_RGB | GLUT_DOUBLE;
 
+       glutInitWindowSize(1280, 800);
        glutInit(&argc, argv);
        if(app_parse_args(argc, argv) == -1) {
                return 1;
@@ -25,10 +32,12 @@ int main(int argc, char **argv)
        }
 #endif
 
-       glutInitWindowSize(1280, 800);
        glutInitDisplayMode(flags);
        glutCreateWindow("census");
 
+       win_width = glutGet(GLUT_WINDOW_WIDTH);
+       win_height = glutGet(GLUT_WINDOW_HEIGHT);
+
        if(fullscr) {
                glutFullScreen();
                glutSetCursor(GLUT_CURSOR_NONE);
@@ -39,6 +48,16 @@ int main(int argc, char **argv)
        glutReshapeFunc(reshape);
        glutKeyboardFunc(keyb);
 
+       if((env = getenv("CAPFPS")) && (cap_frame_interval = atoi(env)) > 0) {
+               cap_frame_interval = 1000 / cap_frame_interval;
+               capture = 1;
+               if(!(pixels = malloc(win_width * win_height * 3))) {
+                       fprintf(stderr, "failed to allocate frame capture buffer\n");
+                       return 1;
+               }
+               nloops = 1;
+       }
+
        if(app_init() == -1) {
                return 1;
        }
@@ -50,10 +69,24 @@ int main(int argc, char **argv)
 
 static void display(void)
 {
-       msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
+       if(capture) {
+               msec += cap_frame_interval;
+       } else {
+               msec = glutGet(GLUT_ELAPSED_TIME) - start_time;
+       }
 
        app_display();
 
+       if(capture) {
+               static int frame;
+               char buf[64];
+
+               glReadPixels(0, 0, win_width, win_height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+               sprintf(buf, "frm%03d.ppm", frame++);
+               save_image(buf, pixels, win_width, win_height);
+       }
+
        glutSwapBuffers();
        assert(glGetError() == GL_NO_ERROR);
 }
@@ -95,3 +128,23 @@ void app_windowed(void)
        glutReshapeWindow(saved_width, saved_height);
        glutSetCursor(GLUT_CURSOR_INHERIT);
 }
+
+static int save_image(const char *fname, unsigned char *pix, int xsz, int ysz)
+{
+       int i;
+       FILE *fp;
+
+       if(!(fp = fopen(fname, "wb"))) {
+               fprintf(stderr, "failed to open %s for writing\n", fname);
+               return -1;
+       }
+       fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
+
+       for(i=0; i<xsz * ysz; i++) {
+               fputc(*pix++, fp);
+               fputc(*pix++, fp);
+               fputc(*pix++, fp);
+       }
+       fclose(fp);
+       return 0;
+}