Mac OS OpenGL屏幕抓取

时间:2015-06-01 12:53:47

标签: c++ macos opengl

我正在通过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 个答案:

答案 0 :(得分:2)

OpenGL无法可靠地用于屏幕捕获。 " OpenGL屏幕截图示例"做全屏幕窗口glReadPixels的事情依赖于底层图形系统的未定义行为。即,窗口共享屏幕帧缓冲区,并且没有擦除笔刷的新创建的窗口将继续"继承"创建它的屏幕内容。

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

  • Windows 共享屏幕帧缓冲区
  • Windows 始终使用一些清除刷
  • 进行初始化
  • Windows被合成到最终桌面外观