+
+
+void save_tiles(void)
+{
+ unsigned char *pixels, *tilepix;
+ int i, j, tilesz = win_height / grid_rows;
+ char fname[256];
+
+ if(!(pixels = malloc(win_width * win_height * 3))) {
+ fprintf(stderr, "failed to allocate pixel buffer\n");
+ return;
+ }
+ glReadPixels(0, 0, win_width, win_height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
+
+ for(i=0; i<grid_rows; i++) {
+ for(j=0; j<grid_cols; j++) {
+ tilepix = pixels + (i * win_width + j) * tilesz * 3;
+
+ sprintf(fname, "tile-%02d%02d.ppm", j, i);
+ save_tile(fname, tilepix, tilesz, tilesz, win_width * 3);
+ }
+ }
+}
+
+int save_tile(const char *fname, unsigned char *pixptr, int xsz, int ysz, int pitch)
+{
+ int i, j;
+ FILE *fp;
+
+ printf("saving tile: %s\n", fname);
+
+ if(!(fp = fopen(fname, "wb"))) {
+ fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
+ return -1;
+ }
+
+ pixptr += ysz * pitch;
+ fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
+ for(i=0; i<ysz; i++) {
+ pixptr -= pitch;
+ for(j=0; j<xsz; j++) {
+ int r = pixptr[j * 3];
+ int g = pixptr[j * 3 + 1];
+ int b = pixptr[j * 3 + 2];
+ fputc(r, fp);
+ fputc(g, fp);
+ fputc(b, fp);
+ }
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+void draw_grid(void)
+{
+ int x, y;
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0, win_width, 0, win_height, -1, 1);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glBegin(GL_LINES);
+ glColor3f(0.5, 0.2, 0.1);
+ for(y=0; y<win_height; y += 32) {
+ glVertex2f(0, y);
+ glVertex2f(win_width, y);
+ }
+ for(x=0; x<win_width; x += 32) {
+ glVertex2f(x, 0);
+ glVertex2f(x, win_height);
+ }
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+}