Function to Capture OpenGL Images to JPG (uses free IJL Library) 

 

Acknowledgements

This article is based on Pierre Alliez's fine article that illustrates how to capture OpenGL images to the clipboard. 

Prerequisites

The function presented here uses the class wrapper (CJpeg) that is wraps the (free) Intel JPEG Library. 

Function Overview

This function, RenderToJpeg, takes the name of the file (as a LPTSTR) and the quality of the output jpeg image (an int with a value of 0-100). The result is nice JPG of your OpenGL screen! 

BOOL CWinChannelView::RenderToJpeg(LPTSTR szFile, int quality)

{

 // Opening the file

 CFile file;

 if (!file.Open(szFile,CFile::modeWrite | CFile::modeCreate))

 return FALSE;

 // Get client geometry 

 CRect rect; 

 GetClientRect(&rect); 

 CSize size(rect.Width(),rect.Height()); 

 // getting device context

 CDC *pDC=GetDC();

 // Alloc pixel bytes 

 int NbBytes = 3 * size.cx * size.cy; 

 unsigned char *pPixelData = new unsigned char[NbBytes]; 

 unsigned char *pPixelData2 = new unsigned char[NbBytes]; 

 // Copy from OpenGL 

 // Don't forget to make OpenGL rendering context 

 // current (wglMakeCurrent)

 glReadPixels(0, 0, 

              size.cx, size.cy,

              GL_RGB,GL_UNSIGNED_BYTE,

              pPixelData); 

 // Swapping lines in the buffer

 // OpenGL writes from lower line going up but ijl works 

 // reverse (from up to down)

 for (int j=0;j// line counter

 {

  for (int i=0;i>size.cx;i++) // column counter

  {

   pPixelData2[(j*size.cx+i)*3] 

   = pPixelData[((size.cy-1-j)*size.cx+i)*3];

   pPixelData2[(j*size.cx+i)*3+1]

   = pPixelData[((size.cy-1-j)*size.cx+i)*3+1];

   pPixelData2[(j*size.cx+i)*3+2]

   = pPixelData[((size.cy-1-j)*size.cx+i)*3+2];

  }

 }

 // Compressing in jpeg

 int len; // the length of the buffer after compression

 CJpeg jpeg;

 pPixelData2 = (unsigned char*)jpeg.Compress(pPixelData2,

                                             size.cx,

                                             size.cy,

                                             3,

                                             len,

                                             quality);

 // Writing file and that's it

 file.Write(pPixelData2,len); 

 // Cleaning memory

 delete [] pPixelData; 

 delete [] pPixelData2; 

 return TRUE;

}