creating an MPEG from an open GL animation

Hi. I have an animation that I’d like to turn into an MPEG. I’m running GL under linux, and it seems that I need to dump each frame of the animation to a separate file (gif or ppm?) to then convert the result into an MPEG. Is there an easy way to save each frame? I’m new to all this, so any help will be appreciated…

Loren Frank

To save each frame, just do a glReadPixels of the entire front buffer after every swapbuffer(use GL_UNSIGNED_BYTE for type). This way you store the frame into an array of GLubyte in memory. Then from this array, you can rebuild an image file (uncompressed is easier, so no gif).

Thanks for the info. Do you know how to take the array of pixel values and convert it into a gif, ppm, or other graphics format that can be read in to a MPEG encoder?

Thanks again,

Loren

I use the following function to save RGB or RGBA images to targa files.
I don’t know if you can make mpegs directly from TGA files or if you need to convert them first.
You probably won’t need to save the alpha channel, but that can be done with TGA files.

//---------------------------------------------------------------------------
// Inputs
// pixels_data pointer to an array of bytes containing the pixel
// data of the image to save.
// file_name Pointer to a string of characters containing the
// name of the Output file.
// width Width of the image in pixels.
// height Height of the image in pixels.
// has_alpha Parameter definig if alpha values are present in
// the memory buffer.
// save_alpha Parameter definig if alpha values must be stored
// in the targa file.
//---------------------------------------------------------------------------
void SaveImageToTargaFile(unsigned char *pixel_data, char *file_name,
int width, int height,bool has_alpha, bool save_alpha)
{
FILE *image_file; // Targa image file’s handle
char file_info[6]; // TGA file’s header’s second part
int image_size; // Size of the image in pixels
int i, j; // Counter variables
int bytes_per_pixel; // Bytes per pixel in original image
int bytes_to_store; // Bytes per pixel in the output file
unsigned char *file_buffer; // temporary buffer
int pixpos; // Current writting position in the file buffer
int pixel_data_size; // size of pixel data

image_size = width * height;

// Create second part of the header
i = width % 256;
j = height % 256;
file_info[0] = (char)(i);
file_info[1] = (char)((width - i) / 256);
file_info[2] = (char)(j);
file_info[3] = (char)((height - j)/ 256);
file_info[4] = (char)(24 + (((save_alpha) && (has_alpha)) ? 8 : 0));
file_info[5] = 0;

// Preparing to write pixel data into the file buffer
bytes_per_pixel = has_alpha ? 4 : 3;
bytes_to_store = file_info[4] / 8;
pixel_data_size = image_size * bytes_to_store;
file_buffer = new unsigned char[18 + (image_size * bytes_to_store)];
// Write first part of the header into the file buffer
memcpy(file_buffer, TGA_header, 12);
// Write second part of the header into the file buffer
memcpy(&file_buffer[12], file_info, 6);
for(i = 0; i < image_size; i++)
{
    pixpos = 18 + i * bytes_per_pixel;
    for(j = 0; j < 3; j++)
    {
        file_buffer[pixpos + j] = pixel_data[i * bytes_per_pixel + 2 - j];
    }
    if((has_alpha) && (save_alpha))
    {
        file_buffer[pixpos + 3] = pixel_data[i * bytes_per_pixel + 3];
    }
}

// Try to create the output file
image_file = fopen(file_name, "wb");
if(image_file == NULL)
return;

if(fwrite(file_buffer, 18 + pixel_data_size, 1, image_file) != 1)
return;	

fclose(image_file);
// Free memory
delete [] file_buffer;

}