MFC+Opengl:截取对话框的屏幕后,直接作为背景纹理

lianxiang_biancheng 2012-01-06 01:55:57
我遇到的问题大体是用定时器每隔1秒控制进行对话框截屏,可以生成一个内存位图BITMAP,然后想提取这个BITMAP的信息,直接作为纹理。
具体如下:我首先截取一个对话框的窗口,然后放到DC中,然后根据该DC生成一个BITMAP,最后根据这个BITMAP来生成纹理。因为我不想将截取的屏幕保存成图片,因为在硬盘上生成图片和加载纹理,速度比较慢。所以,直接将截取的窗口,保存到BITMAP中,然后根据BITMAP,生成纹理。
代码如下:
//截屏并产生纹理
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();
}


结果用这种方式加载的纹理是花的,看起来是密密麻麻的竖线,看不清本来面貌。感觉函数是没问题的,就怀疑是读取的位置的问题、或者是显存没有清空的问题。

我的定时器是每隔一定时间执行一次Screen()函数。请各位大神们指教,能帮我测一下上面的代码更好了。多谢了。
...全文
156 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
问题解决,是BGR与RGB的问题。BITMAP默认的存储格式是BGR,转换成opengl纹理时,需要进行转化, glTexImage2D(GL_TEXTURE_2D, 0 , 3, Width, Height,0 ,GL_BGR_EXT , GL_UNSIGNED_BYTE, p); //我们得到的图形数据格式是BGR(BGRA),所以在生成纹理的时候,需指定格式为GL_BGR_EXT(GL_BGRA_EXT)
ryfdizuo 2012-01-12
  • 打赏
  • 举报
回复
可以读取opengl的帧缓存么,
给个示例:http://www.codesampler.com/oglsrc/oglsrc_14.htm#ogl_frame_buffer_object
idol31 2012-01-12
  • 打赏
  • 举报
回复
帮你顶下,我想在Win32下截取屏幕指定区域再做成纹理贴图,不过卡在截取那个地方了。、。

刚好看到你这,顺便学习下,希望有高手能帮到你。
  • 打赏
  • 举报
回复
肿么没人回答啊。自己顶起来。

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧