使用XCode 4.3.2在Mac OS 10.7.3上进行屏幕捕获的glGrab

时间:2012-07-09 12:16:34

标签: objective-c macos opengl screen-capture

我正在尝试在提到的配置下在Mac OS上集成glGrab代码用于屏幕捕获,我目前卡在我窗口内呈现的全蓝屏幕上。我相信图像纹理的创建方式存在一些问题,但无法分辨出什么。我只是在OpenGL中待了几个星期,所以如果我错过了一些明显的东西,请放轻松。

我正在使用glGrab代码,除了CGLSetFullScreen方法(甚至不是CGLSetFullScreenOnDisplay),因为现在不推荐使用这些方法。所以这一行代码暂时被注释掉了。

我从一段时间以来一直在研究这个主题,并在stackoverflow上发现了另一个可能是完整答案的线程,但它仍有很大帮助。 Convert UIImage to CVImageBufferRef

对glGrab代码的直接引用是http://code.google.com/p/captureme/source/browse/trunk/glGrab.c

1 个答案:

答案 0 :(得分:1)

以上问题的答案如下。所以没有更多的opengl或glGrab。使用最适合Mac OSX的内容。这也不包括用于捕获鼠标指针的代码,但我相信如果你已经登陆这个页面,你就足够聪明,可以自己解决。或者,如果有人读这个知道解决方案,那么你有机会帮助兄弟会:)此代码返回一个CVPixelBufferRef。您可以选择发回CGImageRef甚至字节流,只需根据自己的喜好进行调整即可。 :

void swizzleBitmap(void *data, int rowBytes, int height) {
    int top, bottom;
    void * buffer;
    void * topP;
    void * bottomP;
    void * base;

    top = 0;
    bottom = height - 1;
    base = data;
    buffer = malloc(rowBytes);

    while (top < bottom) {
        topP = (void *)((top * rowBytes) + (intptr_t)base);
        bottomP = (void *)((bottom * rowBytes) + (intptr_t)base);

        bcopy( topP, buffer, rowBytes );
        bcopy( bottomP, topP, rowBytes );
        bcopy( buffer, bottomP, rowBytes );

        ++top;
        --bottom;
    }   
    free(buffer);
}   

CVImageBufferRef grabViaOpenGL() {
    int bytewidth;

    CGImageRef image = CGDisplayCreateImage(kCGDirectMainDisplay);    // Main screenshot capture call

    CGSize frameSize = CGSizeMake(CGImageGetWidth(image), CGImageGetHeight(image));    // Get screenshot bounds

    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                            [NSNumber numberWithBool:NO], kCVPixelBufferCGImageCompatibilityKey,
                            [NSNumber numberWithBool:NO], kCVPixelBufferCGBitmapContextCompatibilityKey,
                            nil];

    CVPixelBufferRef pxbuffer = NULL;
    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, frameSize.width,
                                          frameSize.height,  kCVPixelFormatType_32ARGB, (CFDictionaryRef) options,
                                          &pxbuffer);


    CVPixelBufferLockBaseAddress(pxbuffer, 0);
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(pxdata, frameSize.width,
                                                 frameSize.height, 8, 4*frameSize.width, rgbColorSpace,
                                                 kCGImageAlphaNoneSkipLast);

    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image),
                                           CGImageGetHeight(image)), image);

    bytewidth = frameSize.width * 4; // Assume 4 bytes/pixel for now
    bytewidth = (bytewidth + 3) & ~3; // Align to 4 bytes
    swizzleBitmap(pxdata, bytewidth, frameSize.height);     // Solution for ARGB madness

    CGColorSpaceRelease(rgbColorSpace);
    CGImageRelease(image);
    CGContextRelease(context);

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0);

    return pxbuffer;
}