http://blog.sina.com.cn/s/blog_60707c0f0100q9vf.html
现在的OpenGL己经具有GL_BGR_EXT的方式读取像素,默认己经是4字节对齐了,所以下面代码注释掉了处理部分,如果你的OpenGL不支持,GL_BGR_EXT,把注释部分复原即可。
BOOL SaveBMPFromOpenGl(LPCTSTR lpFileName)
{
ASSERT(lpFileName != NULL);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport);
CRect rect;
GetClientRect(rect);
int width = viewport[2];
int height = viewport[3];
//glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
int nAlignWidth = (width*24+31)/32;
unsigned char* pdata = new unsigned char[nAlignWidth * height * 4];
memset(pdata, 0, nAlignWidth * height * 4);
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pdata);
由RGB变BGR
//for(int i = 0 ; i < width * height * 3 ; i += 3)
//{
// unsigned char tmpRGB;
// tmpRGB = pdata[i];
// pdata[i] = pdata[i+2];
// pdata[i+2] = tmpRGB;
//}
四字节对齐
//int nAlignWidth = (width*24+31)/32;
//unsigned char *pDataAfterAlign = (unsigned char *) malloc(4 * nAlignWidth * height);
//memset(pDataAfterAlign, 0, 4 * nAlignWidth * height);
//int nZero = 4*nAlignWidth - 3*width;
//for(int j=0; j<height; j++)
//{
// for(int i=0; i<width*3; i++)
// {
// pDataAfterAlign[j*(nZero+3*width)+i] = pdata[3*width*j+i];
// }
//}
BITMAPFILEHEADER Header;
BITMAPINFOHEADER HeaderInfo;
Header.bfType = 0x4D42;
Header.bfReserved1 = 0;
Header.bfReserved2 = 0;
Header.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)) ;
Header.bfSize =(DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + nAlignWidth* height * 4);
HeaderInfo.biSize = sizeof(BITMAPINFOHEADER);
HeaderInfo.biWidth = width;
HeaderInfo.biHeight = height;
HeaderInfo.biPlanes = 1;
HeaderInfo.biBitCount = 24;
HeaderInfo.biCompression = 0;
HeaderInfo.biSizeImage = 4 * nAlignWidth * height;
HeaderInfo.biXPelsPerMeter = 0;
HeaderInfo.biYPelsPerMeter = 0;
HeaderInfo.biClrUsed = 0;
HeaderInfo.biClrImportant = 0;
FILE *pfile;
if(!(pfile = fopen(lpFileName, "wb+")))
{
AfxMessageBox("保存图像失败!");
return FALSE;
}
fwrite(&Header, 1, sizeof(BITMAPFILEHEADER), pfile);
fwrite(&HeaderInfo, 1, sizeof(BITMAPINFOHEADER), pfile);
fwrite(pdata, 1, HeaderInfo.biSizeImage, pfile);
fclose(pfile);
delete[] pdata;
return TRUE;
}
O了,主要功能就是一个函数:
void glReadPixels( GLint x,
GLint y,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
GLvoid * data);