1b3dfa806Smrg/* 2b3dfa806Smrg * PPM file output 3b3dfa806Smrg * Brian Paul 4b3dfa806Smrg * 8 Dec 2008 5b3dfa806Smrg */ 6b3dfa806Smrg 7b3dfa806Smrg#include <assert.h> 8b3dfa806Smrg#include <stdio.h> 9b3dfa806Smrg#include <stdlib.h> 10b3dfa806Smrg#include "glutint.h" 11b3dfa806Smrg 12b3dfa806Smrg 13b3dfa806Smrgstatic void 14b3dfa806Smrgwrite_ppm_file(const char *filename, const GLubyte *buffer, 15b3dfa806Smrg int width, int height) 16b3dfa806Smrg{ 17b3dfa806Smrg const int binary = 1; 18b3dfa806Smrg FILE *f = fopen( filename, "w" ); 19b3dfa806Smrg if (f) { 20b3dfa806Smrg const GLubyte *ptr = buffer; 21b3dfa806Smrg int i, x, y; 22b3dfa806Smrg if (binary) { 23b3dfa806Smrg fprintf(f,"P6\n"); 24b3dfa806Smrg fprintf(f,"# ppm-file created by GLUT\n"); 25b3dfa806Smrg fprintf(f,"%i %i\n", width, height); 26b3dfa806Smrg fprintf(f,"255\n"); 27b3dfa806Smrg fclose(f); 28b3dfa806Smrg f = fopen( filename, "ab" ); /* reopen in binary append mode */ 29b3dfa806Smrg for (y = height - 1; y >= 0; y--) { 30b3dfa806Smrg for (x = 0; x < width; x++) { 31b3dfa806Smrg i = (y * width + x) * 4; 32b3dfa806Smrg fputc(ptr[i], f); /* write red */ 33b3dfa806Smrg fputc(ptr[i+1], f); /* write green */ 34b3dfa806Smrg fputc(ptr[i+2], f); /* write blue */ 35b3dfa806Smrg } 36b3dfa806Smrg } 37b3dfa806Smrg } 38b3dfa806Smrg else { 39b3dfa806Smrg /*ASCII*/ 40b3dfa806Smrg int counter = 0; 41b3dfa806Smrg fprintf(f,"P3\n"); 42b3dfa806Smrg fprintf(f,"# ascii ppm file created by GLUT\n"); 43b3dfa806Smrg fprintf(f,"%i %i\n", width, height); 44b3dfa806Smrg fprintf(f,"255\n"); 45b3dfa806Smrg for (y = height - 1; y >= 0; y--) { 46b3dfa806Smrg for (x = 0; x < width; x++) { 47b3dfa806Smrg i = (y * width + x) * 4; 48b3dfa806Smrg fprintf(f, " %3d %3d %3d", ptr[i], ptr[i+1], ptr[i+2]); 49b3dfa806Smrg counter++; 50b3dfa806Smrg if (counter % 5 == 0) 51b3dfa806Smrg fprintf(f, "\n"); 52b3dfa806Smrg } 53b3dfa806Smrg } 54b3dfa806Smrg } 55b3dfa806Smrg fclose(f); 56b3dfa806Smrg } 57b3dfa806Smrg} 58b3dfa806Smrg 59b3dfa806Smrg 60b3dfa806Smrg/** 61b3dfa806Smrg * Called from SwapBuffers if the GLUT_PPM_FILE env var is set. 62b3dfa806Smrg */ 63b3dfa806Smrgvoid __glutWritePPMFile(void) 64b3dfa806Smrg{ 65b3dfa806Smrg int w = glutGet(GLUT_WINDOW_WIDTH); 66b3dfa806Smrg int h = glutGet(GLUT_WINDOW_HEIGHT); 67b3dfa806Smrg GLubyte *buf; 68b3dfa806Smrg 69b3dfa806Smrg assert(__glutPPMFile); 70b3dfa806Smrg 71b3dfa806Smrg buf = (GLubyte *) malloc(w * h * 4); 72b3dfa806Smrg if (buf) { 73b3dfa806Smrg /* XXX save/restore pixel packing */ 74b3dfa806Smrg glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, buf); 75b3dfa806Smrg write_ppm_file(__glutPPMFile, buf, w, h); 76b3dfa806Smrg free(buf); 77b3dfa806Smrg } 78b3dfa806Smrg 79b3dfa806Smrg __glutPPMFile = NULL; /* only write one file */ 80b3dfa806Smrg} 81