摘自:http://www.verydemo.com/demo_c288_i41599.html
MFC+Opengl:截取对话框的屏幕后,直接作为背景纹理
我遇到的问题大体是用定时器每隔1秒控制进行对话框截屏,可以生成一个内存位图BITMAP,然后想提取这个BITMAP的信息,直接作为纹理。具体如下:我首先截取一个对话框的窗口,然后放到DC中,然后根据该DC生成一个BITMAP,最后根据这个BITMAP来生成纹理。因为我不想将截取的屏幕保存成图片,因为在硬盘上生成图片和加载纹理,速度比较慢。所以,直接将截取的窗口,保存到BITMAP中,然后根据BITMAP,生成纹理。
代码如下:
-
C/C++ code
//截屏并产生纹理 void CDialogGLDlg::Screen(char *filename) { int Width = 512; int Height = 512; //获取当前设备 HWND hwnd = GetSafeHwnd(); HDC hDC = ::GetDC(hwnd); CDC *pDC;//窗口DC pDC = CDC::FromHandle(hDC); CDC memDC;//内存DC memDC.CreateCompatibleDC(pDC); HDC memoryDC = CreateCompatibleDC(hDC); CBitmap memBitmap, *oldmemBitmap;//建立和屏幕兼容的bitmap memBitmap.CreateCompatibleBitmap(pDC, Width, Height); oldmemBitmap = memDC.SelectObject(&memBitmap);//将memBitmap选入内存DC memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY); BITMAP bmp; memBitmap.GetBitmap(&bmp);//获得位图信息 //加载图片并获取其位图句柄 //BITMAP bmp; //HBITMAP hBitmap=(HBITMAP)LoadImage( NULL , filename , IMAGE_BITMAP, 0 , 0 , LR_CREATEDIBSECTION | LR_LOADFROMFILE ); //if(hBitmap == NULL) //{ // MessageBox("Failed"); //} //GetObject(hBitmap,sizeof(BITMAP),&bmp); glGenTextures(1, &texture[0]); // 生成对象名,存放在texture[0]中 glBindTexture(GL_TEXTURE_2D, texture[0]); //创建纹理对象 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //双线性采样滤波方式 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0 , 3, bmp.bmWidth, bmp.bmHeight, 0 ,GL_RGB , GL_UNSIGNED_BYTE, bmp.bmBits); //DeleteObject(hBitmap); memDC.DeleteDC(); ReleaseDC(pDC); memBitmap.DeleteObject(); oldmemBitmap->DeleteObject(); } //纹理的绑定和设置 void CDialogGLDlg::RenderScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture[0]); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(-30.0f,-30.0f,-50.0f); glTexCoord2f(1.0f,0.0f); glVertex3f(30.0f,-30.0f,-50.0f); glTexCoord2f(1.0f,1.0f); glVertex3f(30.0f,30.0f,-50.0f); glTexCoord2f(0.0f,1.0f); glVertex3f(-30.0f,30.0f,-50.0f); glEnd(); ::glCallList(1); glPopMatrix(); }
结果用这种方式加载的纹理是花的,看起来是密密麻麻的竖线,看不清本来面貌。感觉函数是没问题的,就怀疑是读取的位置的问题、或者是显存没有清空的问题。