2 * freeglut offscreen rendering demo.
6 * offscreen [standard GLUT options] [filename]
8 * The filename is used to say where to write a PNM image file
9 * that is the sole way to verify that this program is doing what
10 * it should (i.e., rendering offscreen).
12 * You can view the PNM file in image viewers and editors such as
13 * the GIMP. (Everyone doing any kind of graphics has at least one
14 * multi-format-reading image manipulation program, right?)
16 * If no filename is specified, the chosen filename is "offscreen.pnm".
18 * Some suggested uses for GLUT_OFFSCREEN:
20 * * Implementation of a graphics language that writes bitmapped image files.
21 * * Capture GLUT bitmapped fonts to a texture at runtime to make scalable
23 * * Using OpenGL to create special-effect textures at run-time.
25 * * Getting the depth-buffer for a height-field.
26 * * Using OpenGL to create a poster texture (e.g., for pasting onto a a
27 * video screen in a virtual world).
28 * * Using OpenGL to prescale an image to a power-of-2 dimension (including
29 * OpenGL antialiasing). There's no reason that you couldn't do this
30 * yourself, but OpenGL can do it for you, so why not?
31 * * Rendering to a bitmap larger than the display has been suggested
32 * as well. This is a cheap way to produce arbitrarily high resolution
33 * images for printing.
35 * In every case, there are at least cases where you would want to do this
36 * without actually rendering to a visible window.
40 #include <GL/freeglut.h>
42 #define OFFSCREEN_W 500
43 #define OFFSCREEN_H 250
48 const char *save_file_name = "offscreen.pnm";
51 void cb_onscreen_display( void )
53 glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );
54 glColor3d( 1.0, 0.0, 0.0 );
55 glBegin( GL_LINE_LOOP );
56 glVertex2d( 0.0, 0.0 );
57 glVertex2d( 0.5, 0.0 );
58 glVertex2d( 0.5, 0.5 );
59 glVertex2d( 0.0, 0.5 );
60 glVertex2d( 0.0, 0.0 );
62 glColor3d( 1.0, 1.0, 1.0 );
63 glRasterPos2d( -1.0, 0.8 );
65 GLUT_BITMAP_TIMES_ROMAN_24, "Press `s' or `S' to Send to"
67 glRasterPos2d( -.8, 0.6 );
69 GLUT_BITMAP_TIMES_ROMAN_24, "'offscreen.pnm'"
71 glRasterPos2d( -1.0, 0.3 );
73 GLUT_BITMAP_TIMES_ROMAN_24, "Press `q', `Q', or Esc to quit."
79 void write_raw_pnm( char *fname, char *pixels, int w, int h)
83 printf( "Trying to create: %s\n", fname );
84 f = fopen( fname, "wb" );
86 printf( "Ouch! Cannot create file.\n" );
91 printf( "Opened file.\n" );
93 fprintf( f, "# CREATOR: offscreen freeglut demo\n" );
94 fprintf( f, "%d %d\n", w, h );
95 fprintf( f, "255\n" );
98 * Write the rows in reverse order because OpenGL's 0th row
101 for( row = h; row; --row )
102 fwrite( pixels + ((row - 1)*w*3), 1, 3 * w, f );
109 void cb_offscreen_display( void )
111 static char pixels [OFFSCREEN_W * OFFSCREEN_H * 3];
114 cb_onscreen_display( );
115 glColor3d( 0.0, 1.0, 0.0 );
117 for( i = 0; i < 100; ++i)
119 glVertex2d( +1 - (i/50.0), +1 );
120 glVertex2d( -1 + (i/50.0), -1 );
125 glPixelStorei( GL_PACK_ALIGNMENT, 1 );
127 0, 0, OFFSCREEN_W, OFFSCREEN_H,
128 GL_RGB, GL_UNSIGNED_BYTE, (GLvoid *)pixels
130 write_raw_pnm( save_file_name, pixels, OFFSCREEN_W, OFFSCREEN_H );
134 void cb_onscreen_keyboard( unsigned char key, int x, int y )
140 glutSetWindow( offscreen_id );
141 glutPostRedisplay( );
155 int main( int argc, char **argv )
157 glutInit( &argc, argv );
159 save_file_name = argv[ 1 ];
161 glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE );
162 onscreen_id = glutCreateWindow( "Offscreen demo" );
163 glutDisplayFunc( cb_onscreen_display );
164 glutKeyboardFunc( cb_onscreen_keyboard );
166 glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_OFFSCREEN );
167 glutInitWindowSize( OFFSCREEN_W, OFFSCREEN_H );
168 offscreen_id = glutCreateWindow( "" );
169 glutDisplayFunc( cb_offscreen_display );