[ODE] Making movies from DrawStuff

David Whittaker david at wowgod.net
Wed Apr 24 00:01:01 2002


Hey, I believe I can answer this one.  See my comments below.

-----Original Message-----
From: ode-admin@q12.org [mailto:ode-admin@q12.org]On Behalf Of Martin C.
Martin
Sent: Tuesday, April 23, 2002 10:24 PM
To: ode@q12.org
Subject: [ODE] Making movies from DrawStuff


I'd like to make some movies of the images appearing in the DrawStuff
window.  Does anyone know:

(a) How to get the raster out of DrawStuff, i.e. OpenGL?  I've never
programmed OpenGL, so I don't even know where to look.  Would anyone be
interested in writing a dsGetRaster() function?

=======================================================================
Getting the raster out of OpenGL requires a call to glReadPixels.  To ensure
that it is in the correct mode to send you back a bitmap in a standard
format (PPM works best - it starts with the top left corner, storing bytes
in RGB order), you have to throw in a few extra lines of code.  Here it is:

unsigned char pixels[width * height * 3];
//You'll probably want to make this global (or a class member if OO)

glPixelStorei(GL_PACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
//Those lines should set OpenGL up for PCM reading.

glReadPixels(0,0,width,height, GL_RGB, GL_UNSIGNED_BYTE, pixels);

That's it.  Now you've got an array of bytes containing your picture in 24
bit PPM format.  If you want to write that to a file, the PCM format is (for
a 640 x 480 picture with each pixel having a maximum value of 255):

P6
640 480
255
raw image data, i.e. the pixels array

That almost all you need to know for getting the raster from an OpenGL
application.  Note this one fact:  glReadPixels is SLOW!  Make it the last
thing you do in the step function if you are going to use it for video
capture.  Also a call to glFinish() before you call it might keep you from
stalling the graphics pipeline quite as bad.  There is a faster way to do
it, but it requires drawing into a memory dc, then BitBlt'ing to the window.
Then the bitmap that was selected into the memory dc would always contain
the picture you're capturing.  I'm not sure what the unix equivalent to that
would be.  The problem with this approach is, it would require rewriting
drawstuff to some extent (or not using it is what ended up doing).  And it
depends on your graphics hardware as to whether drawing to the memory dc can
be accelerated or not.  It's just that, even on my Dual Athlon MP 1.2 Ghz
system with an ATI All-in-Wonder Radeon, glReadPixels slowed to under 7 fps
for video capture of a 640x480 screen.  320x240 was a little better.  So I
would choose the fewest fps that your video format of choice will support.
You might need to only capture every 3rd or 4th frame or something.
=======================================================================

(b) Given a series of images, what's the best/easiest/favourite way to
turn them into a movie, say an .avi?

=======================================================================
Well, since I found the video for windows sdk to be quite buggy and slow on
my machine, as well as the files being way too large for posting on the web
for example, I chose to write my own video capture utility.  It uses the
Dali engine found at http://www.cs.cornell.edu/dali/.  I have converted into
a win32 dll if you would like to use it.  That is located at
ftp://ftp.csworkbench.com/ODE/, there is a release version, which only
contains the dll, header, lib, etc. and there is a source version if you
want to tweak it.  It's just that the setup for Dali isn't exactly simple
and definitely isn't quick, so the dll is provided mainly as a precompiled
version of Dali.  At it's minimum, it requires two lines of code:

CMPEGout mpeg(640, 480, pixels, PICTYPE_PPM, "output.mpg");
//constructor takes width, height, pixels, type, and filename

mpeg.AddFrame();

Just call the AddFrame function every step, after you've updated the pixels
array, and you will be ready to go.  Note that there are more options in my
dll, like variable compression rates and the like.  The header file is very
well commented.

It has been noted that Dali doesn't work well with sizes that aren't powers
of 16.
=======================================================================

Thanks,
Martin

=======================================================================
Well, I hope you can use that.  If you have any more questions about my dll,
email me off the list at david@csworkbench.com.

David Whittaker
=======================================================================
_______________________________________________
ODE mailing list
ODE@q12.org
http://q12.org/mailman/listinfo/ode