hi,
does anyone know of a library that will let me write each frame of an opengl rendering to a comon graphics file… or even better… a library that will create an avi?
thanks
hi,
does anyone know of a library that will let me write each frame of an opengl rendering to a comon graphics file… or even better… a library that will create an avi?
thanks
Here’s some code to capture the framebuffer
to a variety of formats.
I guess you could capture each frame
and then create an AVI from each still image.
I’m not sure how to do that exactly, but I’m
sure a quick search of freshmeat will help.
This code is copyright (C) 2000 Ryan T. Sammartino and is licensed under the GPL
#ifndef SCREENSHOT_H
#define SCREENSHOT_H
typedef enum {
SCREENSHOT_PPM,
SCREENSHOT_TGA,
SCREENSHOT_BMP,
} SCREENSHOT_FORMAT;/*
- SCREENSHOT_Take will dump the given portion of the GL framebuffer to
- the given filename. The file will be overwritten
- x, y, width, height define the rectangle to capture.
- The image will be stored in the given format
- Returns negative on failure, zero on success
*/
int SCREENSHOT_Take(int x, int y, int width, int height,
const char *fname,
SCREENSHOT_FORMAT format);
#endif // !SCREENSHOT_H
/*
- screenshot.c
- Routines for taking screen shots from GL
- Ryan T. Sammartino
*/#include <stdio.h>
#include <malloc.h>
#include <GL/gl.h>#include “screenshot.h”
static int SCREENSHOT_WriteBMP(const char *fname,
const unsigned char image,
int w, int h)
{
/ See http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/BMP.txt */
struct BMPHeader {
unsigned short type;
unsigned int size;
unsigned short res1;
unsigned short res2;
unsigned int offset;
} attribute((packed)) header;
struct BMPInfo {
unsigned int size;
unsigned int width;
unsigned int height;
unsigned short planes;
unsigned short bit_count;
unsigned int comp;
unsigned int sizeImage;
unsigned int x_pels_per_meter;
unsigned int y_pels_per_meter;
unsigned int clr_used;
unsigned int clr_important;
} attribute((packed)) info;
FILE *fp;
int ret = 0;/* Open file /
fp = fopen(fname, “wb”);
if (!fp) {
fprintf(stderr,
"Unable to open %s for writing
",
fname);
ret = -1;
} else {
/ Header */
header.type = ‘B’ | ‘M’ << 8;
header.size = sizeof(header) + sizeof(info) + w * h * 3;
header.res1 = header.res2 = 0;
header.offset = sizeof(header) + sizeof(info);
info.size = sizeof(info);
info.width = w;
info.height = h;
info.planes = 1;
info.bit_count = 24;
info.comp = 0;
info.sizeImage = w * h * 3;
info.x_pels_per_meter = info.y_pels_per_meter = 0;
info.clr_used = 0;
info.clr_important = 0;fwrite(, sizeof(header), 1, fp); fwrite(, sizeof(info), 1, fp); fwrite(image, sizeof(unsigned char), h*w*3, fp);
}
if (fp) {
fclose(fp);
}return ret;
}static int SCREENSHOT_WriteTGA(const char *fname,
const unsigned char *image,
int w, int h)
{
int i;
FILE fp;
int ret = -1;
/ See http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/TGA.txt for spec */
struct TGAHeader {
unsigned char idfield_len;
unsigned char cmap_type;
unsigned char image_type;
unsigned char cmap_spec[5];
unsigned char x_orig[2];
unsigned char y_orig[2];
unsigned char width[2];
unsigned char height[2];
unsigned char pixel_size;
unsigned char image_desc;
} attribute((packed)) header;/* Open file /
fp = fopen(fname, “wb”);
if (!fp) {
fprintf(stderr,
"Unable to open %s for writing
",
fname);
ret = -1;
} else {
/ Construct header /
header.idfield_len = 0;
header.cmap_type = 0;
header.image_type = 2;
for (i = 0; i < 5; i++) {
header.cmap_spec[i] = 0;
}
for (i = 0; i < 2; i++) {
header.x_orig[i] = 0;
header.y_orig[i] = 0;
}
/ Lo bits /
header.width[0] = w & 0xFF;
/ Hi bits */
header.width[1] = (w >> 8) & 0xFF;
header.height[0] = h & 0xFF;
header.height[1] = (h >> 8) & 0xFF;
header.pixel_size = 24;
header.image_desc = 0;/* Output header */ fwrite(, sizeof(header), 1, fp); /* Output image */ fwrite(image, sizeof(unsigned char), w*h*3, fp);
}
if (fp) {
fclose(fp);
}return ret;
}static int SCREENSHOT_WritePPM(const char *fname,
const unsigned char *image,
int w, int h)
{
unsigned char *row;
int i;
FILE *fp;
int ret = 0;/* Open file /
fp = fopen(fname, “wb”);
if (!fp) {
fprintf(stderr,
"Unable to open %s for writing
",
fname);
ret = -1;
} else {
/ Output header */
fprintf(fp,
"P6
#GL Screenshot %s
%d %d
%d
",
fname, w, h, 255);/* GL returns the data upside down */ for (i = h - 1; i >= 0; i--) { row = (unsigned char*)image + w * i * 3; fwrite(row, sizeof(unsigned char), w*3, fp); }
}
if (fp) {
fclose(fp);
}return ret;
}/*
- SCREENSHOT_Take will dump the given portion of the GL framebuffer to
- a the given filename
- x, y, width, height define the rectangle to capture.
- The image will be stored in the given format
- Returns negative on failure, zero on success
*/
int SCREENSHOT_Take(int x, int y, int width, int height,
const char *fname,
SCREENSHOT_FORMAT format)
{
unsigned char *image = NULL;
int ret = 0;/* Reserve some memory /
image = (unsigned char)malloc(sizeof(unsigned char)widthheight*3);
if (!image) {
fprintf(stderr,
"Unable to allocate image buffer
");
ret = -1;
} else {
switch(format) {
case SCREENSHOT_PPM:
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
ret = SCREENSHOT_WritePPM(fname, image, width, height);
break;
case SCREENSHOT_TGA:
glReadPixels(x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, image);
ret = SCREENSHOT_WriteTGA(fname, image, width, height);
break;
case SCREENSHOT_BMP:
glReadPixels(x, y, width, height, GL_BGR, GL_UNSIGNED_BYTE, image);
ret = SCREENSHOT_WriteBMP(fname, image, width, height);
break;
default:
fprintf(stderr, "Invalid format %d
", format);
ret = -1;
break;
}
}if (image) {
free(image);
}return ret;
}
Hope that helps
[This message has been edited by rts (edited 09-23-2000).]
[This message has been edited by rts (edited 09-23-2000).]
[This message has been edited by rts (edited 04-07-2001).]
[This message has been edited by rts (edited 04-07-2001).]
This is a very usful bit of code, but there seems to be an problem with the lines
in SCREENSHOT_WriteBMP
fwrite(, sizeof(header), 1, fp);
fwrite(, sizeof(info), 1, fp);
and in SCREENSHOT_WriteTGA
fwrite(, sizeof(header), 1, fp);
these generate a parse error.
Thanks for any help
Well, for some reason, the word “image” got lost there.
You really should have been able to figure that out for yourself.
I did try putting image in here, but the file generated by the SCREENSHOT_WriteBMP and SCREENSHOT_WriteTGA functions are not recognized as valid formats (the SCREENSHOT_WritePPM worked fine). As this was the only function I had not changed I had assumed that image was not supposed to go here. My output pictures are available at http://www.hgmp.mrc.ac.uk/~hmorgan2/pictures.html.
If anyone knows why these files are not being recognized it would be great.
[This message has been edited by Hugh (edited 12-06-2001).]
This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.