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;
}