How to save an OpenGL rendering to disk
You can use the following code to read back an OpenGL rendering to a System.Drawing.Bitmap. You can then use the Save() method to save this to disk.
Hints:
- Don't forget to call
Dispose()on the returnedBitmaponce you are done with it. Otherwise, you will run out of memory rapidly. If you wish to save a video, rather than a single screenshot, consider modifying this method to reuse the sameBitmap. - Call
GrabScreenshot()from your main rendering thread, i.e. the thread which contains your GraphicsContext. - Make sure you have bound the correct framebuffer object before calling
GrabScreenshot(). - You can improve performance significantly by removing the
bmp.RotateFlip()call and saving the resulting image as a BMP rather than a PNG file. This is especially important if you wish to record a video - it is the difference between a real-time recording and a slideshow. - This code can record 720p/30Hz video relatively easily, given suitable hardware and a little optimization (as outlined above). There are many programs that can encode a stream of consecutive BMP files into a high definition video.
using System; using System.Drawing; using OpenTK.Graphics; using OpenTK.Graphics.OpenGL; static class GraphicsHelpers { // Returns a System.Drawing.Bitmap with the contents of the current framebuffer public static Bitmap GrabScreenshot() { if (GraphicsContext.CurrentContext == null) throw new GraphicsContextMissingException(); Bitmap bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); System.Drawing.Imaging.BitmapData data = bmp.LockBits(this.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb); GL.ReadPixels(0, 0, this.ClientSize.Width, this.ClientSize.Height, PixelFormat.Bgr, PixelType.UnsignedByte, data.Scan0); bmp.UnlockBits(data); bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); return bmp; } }

