【问题标题】:Mac OS OpenGL screen grabMac OS OpenGL 屏幕抓取
【发布时间】: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 将像素数据写入文件,但没有结果,又是黑色图像。

【问题讨论】:

    标签: c++ macos opengl


    【解决方案1】:

    OpenGL 不能可靠地用于屏幕捕获。执行 fullscreen-window-glReadPixels 的“OpenGL 屏幕捕获示例”依赖于底层图形系统的未定义行为。也就是说,窗口共享屏幕帧缓冲区,并且新创建的没有擦除画笔的窗口将“继承”创建它的屏幕内容。

    在现代图形系统上,所有这些假设都失败了:

    • Windows 共享屏幕帧缓冲区
    • Windows 总是用一些清除画笔初始化
    • Windows 被合成到最终的桌面外观中

    【讨论】:

    • 感谢您提供此信息。即对于 Mac 屏幕抓取,我必须使用标准函数,如 CGDisplayCreateImageForRect、CGImageGetDataProvider ...?
    • @GeorgGPU:是的,您必须为此使用标准系统函数。
    猜你喜欢
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 2019-01-17
    • 2011-06-03
    相关资源
    最近更新 更多