C++ 使用opengl捕获屏幕,始终为黑色
我的项目需要实时捕获屏幕图像部分屏幕,GDI捕获屏幕的方式工作起来很慢,而且占用了太多资源。然后,我想尝试使用opengl glReadpixels读取屏幕并保存到GPU内存PBO。我不能使用窗口捕获,因为应用程序经常更改窗口布局,我需要的是一个固定的矩形区域。 我使用屏幕DC生成opengl上下文,其中包含的setpixel部分生成黑色图像,因为窗口本身只绘制黑色,但在窗口顶部,有其他窗口显示感兴趣的内容 以下是我的部分代码:C++ 使用opengl捕获屏幕,始终为黑色,c++,opengl,C++,Opengl,我的项目需要实时捕获屏幕图像部分屏幕,GDI捕获屏幕的方式工作起来很慢,而且占用了太多资源。然后,我想尝试使用opengl glReadpixels读取屏幕并保存到GPU内存PBO。我不能使用窗口捕获,因为应用程序经常更改窗口布局,我需要的是一个固定的矩形区域。 我使用屏幕DC生成opengl上下文,其中包含的setpixel部分生成黑色图像,因为窗口本身只绘制黑色,但在窗口顶部,有其他窗口显示感兴趣的内容 以下是我的部分代码: void CMainWnd::setup_screenca
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是黑色的,包含几个显示图像的子窗口,我想用这些子窗口捕获主窗口的矩形。我使用screen DC生成opengl上下文,但它无法获得正确的屏幕。有人能帮忙吗?非常感谢。您不能使用OpenGL捕获屏幕。真的吗?你能再给我解释一下吗?或者你有更好的方法吗?就OpenGL而言,任何你没有通过OpenGL渲染创建的帧缓冲区内容都是完全未定义的//阅读backbuffer当然没有任何帮助。您正在读取前端缓冲区,它在Windows Vista或更新版本中非常不可靠。大多数情况下,在从后端到前端交换之后,前端缓冲区的内容会立即被取消定义。在进行缓冲区交换之前,您应该注意读取后缓冲区,因为如果等到交换之后,后缓冲区也可能会变得未定义。但是,当您没有在上下文中绘制任何内容时,这些都不重要。渲染窗口顶部可能有窗口,但它们是完全独立的。窗口管理器会绘制所有这些内容,而您无法访问其他窗口生成的图像。这里的技巧基本上只在GDI处理桌面Windows XP或更早版本时有效-不要在现代版本的Windows中尝试。