我的项目需要实时捕获屏幕图像(部分屏幕),GDI方式捕获屏幕工作但速度慢并且使用了太多资源。然后我想尝试使用opengl glReadpixels读取屏幕并保存到GPU内存(PBO)。我不能使用窗口捕获,因为应用程序经常更改窗口布局,我需要的是固定的矩形区域。 我使用屏幕DC生成opengl上下文(包括setpixel部分产生黑色图像(由于窗口本身只绘制黑色,但在窗口顶部,还有其他窗口显示感兴趣的东西)。
以下是我的部分代码:
void CMainWnd::setup_screencapture()
{
hdcScr=::GetDC(NULL);
////searching hints that setpixelformat cannot be done to screen
//but if commented, no context will be able to generate.
PIXELFORMATDESCRIPTOR pixelDesc =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,//
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
int n_PixelFormat = ::ChoosePixelFormat(hdcScr,&pixelDesc);
SetPixelFormat(hdcScr,n_PixelFormat,&pixelDesc);
///////////
hglrcScr = wglCreateContext(hdcScr);
//clean all buffers
pbo_indx=0;
max_num_pbos=100;
num_frames_captured=0;
for(int i=0;i<max_num_pbos;i++) pbo_scr_list[i]=0;
pVideoBuffer=0;
//the
//wglMakeCurrent(hdcScr,hglrcScr);
}
int CMainWnd::capture_screen()
{
//capture limited rGlWin
hptime t0;
double dtime=t0.gettime();
wglMakeCurrent(hdcScr,hglrcScr);
screencapture_width=(rGlWin.right-rGlWin.left)/4*4;
screencapture_height=(rGlWin.bottom-rGlWin.top)/4*4;
if(!pbo_scr_list[pbo_indx])
{
glGenBuffersARB(1,&pbo_scr_list[pbo_indx]);
glBindBufferARB(GL_PIXEL_PACK_BUFFER,pbo_scr_list[pbo_indx]);
glBufferDataARB(GL_PIXEL_PACK_BUFFER,screencapture_width*screencapture_height*3,0,GL_DYNAMIC_READ);
glBindBufferARB(GL_PIXEL_PACK_BUFFER,0);
}
glReadBuffer(GL_FRONT); //read the backbuffer
glBindBufferARB(GL_PIXEL_PACK_BUFFER,pbo_scr_list[pbo_indx]); //link the buffer for pixel reading
//gl read pixel uses the lower-left corner as
glReadPixels(rGlWin.left,rGlWin.bottom,screencapture_width,screencapture_height,GL_BGR,GL_UNSIGNED_BYTE,0);
glBindBufferARB(GL_PIXEL_PACK_BUFFER,0); //unlink
pbo_indx++;num_frames_captured++;
if(pbo_indx>=max_num_pbos) pbo_indx=0;
if(num_frames_captured>max_num_pbos) num_frames_captured=max_num_pbos;
wglMakeCurrent(NULL,NULL);
dtime=t0.gettime()-dtime;
TRACE("screencapture time=%.2fms\n",dtime);
return pbo_indx;
}
简化案例:mainwnd是黑色并且有几个子窗口显示图像,我想捕获主窗口的矩形(带有那些子窗口)。我使用屏幕DC生成opengl上下文,它无法获得正确的屏幕。有人可以帮忙吗?非常感谢。