Set GLUT_PPM_FILE to the desired filename. The first frame rendered will be written to that file.tags/mesa_7_3_rc1
@@ -56,6 +56,7 @@ SOURCES = \ | |||
glut_modifier.c \ | |||
glut_mroman.c \ | |||
glut_overlay.c \ | |||
glut_ppm.c \ | |||
glut_roman.c \ | |||
glut_shapes.c \ | |||
glut_space.c \ |
@@ -51,6 +51,7 @@ int __glutInitX = -1, __glutInitY = -1; | |||
GLboolean __glutForceDirect = GL_FALSE, | |||
__glutTryDirect = GL_TRUE; | |||
Atom __glutWMDeleteWindow; | |||
char *__glutPPMFile = NULL; | |||
/* *INDENT-ON* */ | |||
#ifdef _WIN32 | |||
@@ -341,6 +342,9 @@ glutInit(int *argcp, char **argv) | |||
__glutFPS = 5000; /* 5000 milliseconds */ | |||
} | |||
} | |||
/* check if GLUT_PPM_FILE env var is set */ | |||
__glutPPMFile = getenv("GLUT_PPM_FILE"); | |||
} | |||
#ifdef _WIN32 |
@@ -0,0 +1,80 @@ | |||
/* | |||
* PPM file output | |||
* Brian Paul | |||
* 8 Dec 2008 | |||
*/ | |||
#include <assert.h> | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include "glutint.h" | |||
static void | |||
write_ppm_file(const char *filename, const GLubyte *buffer, | |||
int width, int height) | |||
{ | |||
const int binary = 1; | |||
FILE *f = fopen( filename, "w" ); | |||
if (f) { | |||
const GLubyte *ptr = buffer; | |||
int i, x, y; | |||
if (binary) { | |||
fprintf(f,"P6\n"); | |||
fprintf(f,"# ppm-file created by GLUT\n"); | |||
fprintf(f,"%i %i\n", width, height); | |||
fprintf(f,"255\n"); | |||
fclose(f); | |||
f = fopen( filename, "ab" ); /* reopen in binary append mode */ | |||
for (y = height - 1; y >= 0; y--) { | |||
for (x = 0; x < width; x++) { | |||
i = (y * width + x) * 4; | |||
fputc(ptr[i], f); /* write red */ | |||
fputc(ptr[i+1], f); /* write green */ | |||
fputc(ptr[i+2], f); /* write blue */ | |||
} | |||
} | |||
} | |||
else { | |||
/*ASCII*/ | |||
int counter = 0; | |||
fprintf(f,"P3\n"); | |||
fprintf(f,"# ascii ppm file created by GLUT\n"); | |||
fprintf(f,"%i %i\n", width, height); | |||
fprintf(f,"255\n"); | |||
for (y = height - 1; y >= 0; y--) { | |||
for (x = 0; x < width; x++) { | |||
i = (y * width + x) * 4; | |||
fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]); | |||
counter++; | |||
if (counter % 5 == 0) | |||
fprintf(f, "\n"); | |||
} | |||
} | |||
} | |||
fclose(f); | |||
} | |||
} | |||
/** | |||
* Called from SwapBuffers if the GLUT_PPM_FILE env var is set. | |||
*/ | |||
void __glutWritePPMFile(void) | |||
{ | |||
int w = glutGet(GLUT_WINDOW_WIDTH); | |||
int h = glutGet(GLUT_WINDOW_HEIGHT); | |||
GLubyte *buf; | |||
assert(__glutPPMFile); | |||
buf = (GLubyte *) malloc(w * h * 4); | |||
if (buf) { | |||
/* XXX save/restore pixel packing */ | |||
glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buf); | |||
write_ppm_file(__glutPPMFile, buf, w, h); | |||
free(buf); | |||
} | |||
__glutPPMFile = NULL; /* only write one file */ | |||
} |
@@ -18,6 +18,10 @@ glutSwapBuffers(void) | |||
{ | |||
GLUTwindow *window = __glutCurrentWindow; | |||
if (__glutPPMFile) { | |||
__glutWritePPMFile(); | |||
} | |||
if (window->renderWin == window->win) { | |||
if (__glutCurrentWindow->treatAsSingle) { | |||
/* Pretend the double buffered window is single buffered, |
@@ -664,6 +664,7 @@ extern unsigned int __glutModifierMask; | |||
#ifdef _WIN32 | |||
extern void (__cdecl *__glutExitFunc)(int retval); | |||
#endif | |||
extern char *__glutPPMFile; | |||
/* private variables from glut_menu.c */ | |||
extern GLUTmenuItem *__glutItemSelected; | |||
@@ -684,6 +685,9 @@ extern void __glutFreeOverlay(GLUToverlay * overlay); | |||
extern XVisualInfo *__glutDetermineWindowVisual(Bool * treatAsSingle, | |||
Bool * visAlloced, void **fbc); | |||
/* private variables from glut_ppm.c */ | |||
extern void __glutWritePPMFile(void); | |||
/* private variables from glut_mesa.c */ | |||
extern int __glutMesaSwapHackSupport; | |||
@@ -812,4 +816,5 @@ extern LONG WINAPI __glutWindowProc(HWND win, UINT msg, WPARAM w, LPARAM l); | |||
extern HDC XHDC; | |||
#endif | |||
#endif /* __glutint_h__ */ |