原本是一件很簡單的事情,就是將View上使用OpenGL畫出來的數據生成圖片讓其實現打印的功能,咱們知道MFC提供打印的接口是不支持OpenGL的(至少我不清楚),必須將它轉成GDI再畫在Print的pDC上。html
OpenGL一直都有一個函數名字叫:glReadPixels,它能read a block of pixels from the frame buffer,可是誰都沒想到它居然轉換成CImage居然是這樣的規則。函數
http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml中說到:Specify the window coordinates of the first pixel that is read from the frame buffer. This location is the lower left corner of a rectangular block of pixels. 是從左下角開始讀,這一條是我始料未及的,通常一般都是從左上角開始的,我至今沒想明白爲何它要這樣設計。在調用這個函數以前還須要glReadBuffer(GL_BACK_LEFT);這句,若是你想將它設置成GL_FRONT_LEFT彷佛還不行,它並不會從左上角開始,真弄不懂這設計者的邏輯。spa
而後接着下一步就開始往CImage裏面寫東西了:直接上code:設計
.h文件中定義:code
GLubyte *_print_image_data;
CImage _print_img;
OnPreparePrinting(CPrintInfo* pInfo)component
_print_image_data = nullptr;
glReadBuffer(GL_BACK_LEFT);
OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)orm
int format = GL_RGB ,components = 0 , width = m_width, height = m_height; switch(format) { case GL_RGB: components = 3; break; case GL_RGBA: components = 4; break; case GL_ALPHA: case GL_LUMINANCE: components = 1; break; } _print_image_data = (GLubyte*)malloc(components * width * height); glReadPixels(0, 0, width, height, format, GL_UNSIGNED_BYTE, _print_image_data); _print_img.Create(width, height, 24); int nPixel = height*width*3; for(int j = 0; j <height ; j++) for(int i = width-1; i >=0; i--) { BYTE b = _print_image_data[--nPixel]; BYTE g = _print_image_data[--nPixel]; BYTE r = _print_image_data[--nPixel]; _print_img.SetPixelRGB(i, j, r,g,b); }
OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)xml
free(_print_image_data); _print_image_data = nullptr; _print_img.Destroy();
OnPrint(CDC* pDC, CPrintInfo* pInfo)htm
if(_print_image_data != nullptr) _print_img.Draw(pDC->m_hDC, 0, 0, _print_img.GetWidth()*4, _print_img.GetHeight()*4);
能夠看到那個x、y軸的雙層循環的code真是有點怪異,一個++、一個--,可是又必須這樣寫才能對,但願之後有人再碰到這種狀況可以Lucky的找到我這篇blog了吧。blog