Archived

This topic is now archived and is closed to further replies.

Louis_Wu

Tutorial Idea

Recommended Posts

I disagree I think it''s important that we *all* see what kind of tutorial requests are being made. It let''s us know that we''re not the only ones wondering about something, and we can add our "support" to the request. It also gives us the opportunity to say "Oh yah! I''ve been wanting to write a tutorial about that, now I have the motivation to do it!".

As it so happens, I recently wrote some code to save an OpenGL anim to an AVI file, if you''re interested here''s a snipit of the AVI specific stuff...


void save_to_avi(struct S_BMP *frame, char *filename)
{
int i;
AVISTREAMINFO strhdr;
PAVIFILE pfile = NULL;
PAVISTREAM ps = NULL, psCompressed = NULL, psText = NULL;
AVICOMPRESSOPTIONS opts;
AVICOMPRESSOPTIONS FAR * aopts[1] = {&opts};
HRESULT hr;
WORD wVer;
BITMAPINFOHEADER binfo;

binfo.biSize = sizeof(binfo);
binfo.biWidth = frame->width;
binfo.biHeight = frame->height;
binfo.biPlanes = 1;
binfo.biBitCount = 24;
binfo.biCompression = BI_RGB;
binfo.biSizeImage = frame->width*frame->height*3;
binfo.biClrUsed = 0;
binfo.biClrImportant = 0;

/* first let''s make sure we are running on 1.1 */
wVer = HIWORD(VideoForWindowsVersion());
if(wVer < 0x010a)
return;

AVIFileInit();

hr = AVIFileOpen(&pfile, // returned file pointer
filename, // file name
OF_WRITE | OF_CREATE, // mode to open file with
NULL); // use handler determined
// from file extension....
if (hr != AVIERR_OK)
goto error;

// Fill in the header for the video stream....

// The video stream will run in 15ths of a second....

memset(&strhdr, 0, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;// stream type
strhdr.fccHandler = 0;
strhdr.dwScale = 1;
strhdr.dwRate = 15; // 15 fps
strhdr.dwSuggestedBufferSize = binfo.biSizeImage;
SetRect(&strhdr.rcFrame, 0, 0, // rectangle for stream
(int) binfo.biWidth,
(int) binfo.biHeight);

// And create the stream;
hr = AVIFileCreateStream(pfile, // file pointer
&ps, // returned stream pointer
&strhdr); // stream header
if (hr != AVIERR_OK) {
goto error;
}

memset(&opts, 0, sizeof(opts));

if (!AVISaveOptions(NULL, 0, 1, &ps, (LPAVICOMPRESSOPTIONS FAR *) &aopts))
goto error;

hr = AVIMakeCompressedStream(&psCompressed, ps, &opts, NULL);
if (hr != AVIERR_OK) {
goto error;
}

hr = AVIStreamSetFormat(psCompressed, 0,
&binfo, // stream format
binfo.biSize + // format size
binfo.biClrUsed * sizeof(RGBQUAD));
if (hr != AVIERR_OK) {
goto error;
}

for (i = 0; i < 480; i++) {
hr = AVIStreamWrite(psCompressed, i, 1, frame->data, frame->width*frame->height*3, AVIIF_KEYFRAME, NULL, NULL);
// hr = AVIStreamWrite(psCompressed, // stream pointer
// i * 10, // time of this frame
// 1, // number to write
// (LPBYTE) &binfo + // pointer to data
// binfo.biSize +
// binfo.biClrUsed * sizeof(RGBQUAD),
// binfo.biSizeImage, // size of this frame
// AVIIF_KEYFRAME, // flags....
// NULL,
// NULL);
if (hr != AVIERR_OK)
break;
pov.hrot -= 0.04f;
pov.origin[1] += 1.5f;
}

error:
//
// Now close the file
//
if (ps)
AVIStreamClose(ps);

if (psCompressed)
AVIStreamClose(psCompressed);

if (pfile)
AVIFileClose(pfile);

AVIFileExit();
}



I hacked this code up a little right here to remove some globals and what not, so it probably wouldn''t compile exactly like this, but it should give you the idea. This would save a 480 frame AVI consisting of just the one input image. My original code actually rendered different frames in the inner loop there.

Share this post


Link to post
Share on other sites