Skip to content

Commit 89d7cc0

Browse files
committed
Fix offscreen example
1 parent e52e447 commit 89d7cc0

1 file changed

Lines changed: 21 additions & 14 deletions

File tree

opengl/offscreen.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include <GL/glext.h>
1414

1515
enum Constants { SCREENSHOT_MAX_FILENAME = 256 };
16-
static const char *SCREENSHOT_FILENAME_PREFIX = "tmp";
1716
static GLubyte *pixels = NULL;
1817
static GLuint fbo;
1918
static GLuint rbo_color;
@@ -23,25 +22,37 @@ static const GLuint FORMAT_NBYTES = 4;
2322
static const unsigned int HEIGHT = 100;
2423
static const unsigned int WIDTH = 100;
2524
static int offscreen = 1;
26-
static unsigned int time0;
2725
static unsigned int max_nframes = 100;
2826
static unsigned int nframes = 0;
27+
static unsigned int time0;
2928

3029
/* Model. */
3130
static double angle;
3231
static double delta_angle;
3332

33+
/*
34+
Take screenshot with glReadPixels and save to a file in PPM format.
35+
- filename: file path to save to, without extension
36+
- width: screen width in pixels
37+
- height: screen height in pixels
38+
- format: glReadPixelsFormat
39+
- format_nbytes: number of bytes per pixel. This is implied by format,
40+
but we haven't found a built-in way to get this information automatically.
41+
- pixels: intermediate buffer to avoid repeated mallocs across multiple calls.
42+
Contents of this buffer do not matter.
43+
May be NULL, in which case it is initialized.
44+
You must `free` it when you won't be calling this function anymore.
45+
*/
3446
static void screenshot_ppm(const char *filename, unsigned int width, unsigned int height,
35-
GLenum format, unsigned int pixel_nbytes, GLubyte **pixels) {
47+
GLenum format, unsigned int format_nbytes, GLubyte **pixels) {
3648
size_t i, j, k, cur;
37-
if (*pixels == NULL)
38-
(*pixels) = malloc(pixel_nbytes * width * height);
39-
glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, pixels);
4049
FILE *f = fopen(filename, "w");
4150
fprintf(f, "P3\n%d %d\n%d\n", width, height, 255);
51+
*pixels = realloc(*pixels, format_nbytes * width * height);
52+
glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, *pixels);
4253
for (i = 0; i < height; i++) {
4354
for (j = 0; j < width; j++) {
44-
cur = pixel_nbytes * (((height - i - 1) * width + j);
55+
cur = format_nbytes * ((height - i - 1) * width + j);
4556
fprintf(f, "%3d %3d %3d ", (*pixels)[cur], (*pixels)[cur + 1], (*pixels)[cur + 2]);
4657
}
4758
fprintf(f, "\n");
@@ -113,7 +124,7 @@ static void deinit(void) {
113124
}
114125
}
115126

116-
static void draw_scene() {
127+
static void draw_scene(void) {
117128
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
118129
glLoadIdentity();
119130
glRotatef(angle, 0.0f, 0.0f, -1.0f);
@@ -135,14 +146,10 @@ static void display(void) {
135146
} else {
136147
glutSwapBuffers();
137148
}
138-
assert(
139-
snprintf(filename, SCREENSHOT_MAX_FILENAME, "%s%d.ppm",
140-
SCREENSHOT_FILENAME_PREFIX, nframes)
141-
< SCREENSHOT_MAX_FILENAME
142-
);
149+
snprintf(filename, SCREENSHOT_MAX_FILENAME, "tmp%d.ppm", nframes);
143150
screenshot_ppm(filename, WIDTH, HEIGHT, FORMAT, FORMAT_NBYTES, &pixels);
144151
nframes++;
145-
if (nframes >= max_nframes)
152+
if (nframes > max_nframes)
146153
exit(EXIT_SUCCESS);
147154
}
148155

0 commit comments

Comments
 (0)