Mac OS OpenGL 屏幕抓取
Posted
技术标签:
【中文标题】Mac OS OpenGL 屏幕抓取【英文标题】:Mac OS OpenGL screen grab 【发布时间】:2015-06-01 12:53:46 【问题描述】:我正在尝试通过 OpenGL 捕获 mac os 桌面,即 GL 桌面抓取。
CGContextRef bitmap;
CGImageRef image;
void * data;
long bytewidth;
GLint width, height;
long bytes;
CGColorSpaceRef cSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
CGLContextObj glContextObj;
CGLPixelFormatObj pixelFormatObj ;
GLint numPixelFormats ;
int attribs[] =
kCGLPFAFullScreen,
kCGLPFADisplayMask,
NULL,
kCGLPFAColorSize, 24,
kCGLPFAAlphaSize, 0,
kCGLPFADepthSize, 32,
NULL
;
CGDirectDisplayID display;
if(display == kCGNullDirectDisplay)
display = CGMainDisplayID();
attribs[2] = CGDisplayIDToOpenGLDisplayMask(display);
CGLChoosePixelFormat( (CGLPixelFormatAttribute*) attribs, &pixelFormatObj, &numPixelFormats );
if ( pixelFormatObj == NULL ) // No full screen context support
attribs[10] = NULL;
CGLChoosePixelFormat( (CGLPixelFormatAttribute*) attribs, &pixelFormatObj, &numPixelFormats );
if (pixelFormatObj == NULL)
return;
CGLCreateContext( pixelFormatObj, NULL, &glContextObj ) ;
CGLDestroyPixelFormat( pixelFormatObj ) ;
if ( glContextObj == NULL )
return;
CGLSetCurrentContext( glContextObj ) ;
CGLSetFullScreen( glContextObj ) ;
glReadBuffer(GL_FRONT);
width = scrWidth;
height = srcHeight;
bytewidth = width * 4; // Assume 4 bytes/pixel for now
bytewidth = (bytewidth + 3) & ~3; // Align to 4 bytes
bytes = bytewidth * height; // width * height
data = malloc(height * bytewidth);
if ( data == NULL )
CGLSetCurrentContext( NULL );
CGLClearDrawable( glContextObj ); // disassociate from full screen
CGLDestroyContext( glContextObj ); // and destroy the context
return;
bitmap = CGBitmapContextCreate(data, width, height, 8, bytewidth,
cSpace, kCGImageAlphaNoneSkipFirst /* XRGB */);
CFRelease(cSpace);
glFinish();
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glReadPixels(0, 0, width, height,
GL_RGB,
#ifdef __BIG_ENDIAN__
GL_UNSIGNED_BYTE, // for PPC
#else
GL_UNSIGNED_BYTE, // for Intel!
#endif
data);
swizzleBitmap(data, bytewidth, height);
image = CGBitmapContextCreateImage(bitmap);
CFRelease(bitmap);
free(data);
CGLSetCurrentContext( NULL );
CGLClearDrawable( glContextObj );
CGLDestroyContext( glContextObj );
但我得到的是黑色图像。 我正在使用 10.10.3 OS X Yosemite 。 这里有什么问题? 也许问题出在mac os版本?
我正在通过 glReadPixels 将像素数据写入文件,但没有结果,又是黑色图像。
【问题讨论】:
【参考方案1】:OpenGL 不能可靠地用于屏幕捕获。执行 fullscreen-window-glReadPixels 的“OpenGL 屏幕捕获示例”依赖于底层图形系统的未定义行为。也就是说,窗口共享屏幕帧缓冲区,并且新创建的没有擦除画笔的窗口将“继承”创建它的屏幕内容。
在现代图形系统上,所有这些假设都失败了:
Windows 不共享屏幕帧缓冲区 Windows 总是用一些清除画笔初始化 Windows 被合成到最终的桌面外观中【讨论】:
感谢您提供此信息。即对于 Mac 屏幕抓取,我必须使用标准函数,如 CGDisplayCreateImageForRect、CGImageGetDataProvider ...? @GeorgGPU:是的,您必须为此使用标准系统函数。以上是关于Mac OS OpenGL 屏幕抓取的主要内容,如果未能解决你的问题,请参考以下文章
在 Mac OS X 上使用 CGL 设置 OpenGL 上下文
在 Mac OS X 中编译使用 OpenGL 的 C 程序