CaptureScreen в Objective-C с использованием OpenGL на IMac - PullRequest
1 голос
/ 21 августа 2011

У меня мультидисплейная система, 27 дюймов (2560 x 1440) и Apple Cinema Display (1920 x 1200) с видеокартой ATI Radeon HD 5750 1024 МБ.Раньше я мог снимать скриншоты с моего предыдущего iMac с картой Nvidia, также с мультидисплейными системами.Теперь я получаю сообщение об ошибке OpenGL.

Эта GDB была настроена как "x86_64-apple-darwin" .tty / dev / ttys001 [Переключение на процесс 28434 поток 0x0] 2011-08-20 19:07.OpenGLScreenReader.m: 230 2011-08-20 19: 07: 42.043 DetectObjectColor [28434: c03] * Завершение работы приложения из-за необработанного исключения «NSInternalInconsistencyException», причина: «Ошибка OpenGL 0x0506»

Я вызываю это из моей основной программы:

OpenGLScreenReader *mOpenGLScreenReader;
mOpenGLScreenReader = [[OpenGLScreenReader alloc] init];
[mOpenGLScreenReader readRectScreen:CGRectMake(570, 265, 35, 800)];

Это мой метод инициализации

-(id) init
{
    if (self = [super init])
    {
     // Create a full-screen OpenGL graphics context
     // Specify attributes of the GL graphics context
      NSOpenGLPixelFormatAttribute attributes[] = {

     NSOpenGLPFANoRecovery,
        NSOpenGLPFAFullScreen,
        NSOpenGLPFAScreenMask,
        CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
        (NSOpenGLPixelFormatAttribute) 0
    };

    NSOpenGLPixelFormat *glPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
    if (!glPixelFormat)
    {
        return nil;
    }

    // Create OpenGL context used to render
    mGLContext = [[[NSOpenGLContext alloc] initWithFormat:glPixelFormat shareContext:nil] autorelease];

    // Cleanup, pixel format object no longer needed
    [glPixelFormat release];
    if (!mGLContext)
    {
        [self release];
        return nil;
    }
    [mGLContext retain];

    // Set our context as the current OpenGL context
    [mGLContext makeCurrentContext];

    // Set full-screen mode
    [mGLContext setFullScreen];

    NSRect mainScreenRect = [[NSScreen mainScreen] frame];
    mWidth = mainScreenRect.size.width;
    mHeight = mainScreenRect.size.height;       
    mByteWidth = mWidth * 4;                // Assume 4 bytes/pixel for now
    mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes      
    mData = malloc(mByteWidth * mHeight);
    NSAssert( mData != 0, @"malloc failed");        
  }
  return self;
}

Это мой метод readRectScreen, который выдает мне ошибку в OpenGL, когда он выполняет readPartialScreenToBuffermethod

- (void) readRectScreen:(CGRect) srcRect
{
    mWidth = srcRect.size.width;
mHeight = srcRect.size.height;
mByteWidth = mWidth * 4;                // Assume 4 bytes/pixel for now
mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes

mData = malloc(mByteWidth * mHeight);

[self readPartialScreenToBuffer:srcRect bufferBaseAddress: mData];
}

- (void) readPartialScreenToBuffer: (CGRect) srcRect bufferBaseAddress: (void *) baseAddress
{
// select front buffer as our source for pixel data
    GLint width, height;
    width = srcRect.size.width;
    height = srcRect.size.height;
    glReadBuffer(GL_FRONT);
    //Read OpenGL context pixels directly.
    // For extra safety, save & restore OpenGL states that are changed
    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
    glPixelStorei(GL_PACK_ROW_LENGTH, 0);
    glPixelStorei(GL_PACK_SKIP_ROWS, 0);
    glPixelStorei(GL_PACK_SKIP_PIXELS, 0);

    //Read a block of pixels from the frame buffer
glReadPixels((GLint)srcRect.origin.x, (GLint)srcRect.origin.y, width, height, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,baseAddress);

    glPopClientAttrib();

    //Check for OpenGL errors
    GLenum theError = GL_NO_ERROR;
    theError = glGetError();
    NSAssert1( theError == GL_NO_ERROR, @"OpenGL error 0x%04X", theError);
}

Может кто-нибудь помочь, пожалуйста ... Я совершенно заблудился в том, где может быть ошибка.

Ответы [ 2 ]

3 голосов
/ 21 августа 2011

Полагаю, на вашем новом компьютере установлена ​​Mac OS X 10.7 (Lion).Лев больше не позволяет этот метод захвата экрана (чтение переднего буфера).Приложения должны перейти на API CGDisplayCaptureImage (), который был представлен в 10.6.

2 голосов
/ 21 августа 2011

Похоже, ваша проблема в том, что вы не получаете / не имеете действительный контекст OpenGL.Но это не ваша настоящая проблема:

OpenGL - это библиотека для рисования / рендеринга. glReadPixels предназначен для считывания изображения, созданного вашей программой.OpenGL не является графическим API общего назначения (хотя некоторые / многие путают его за это).

В течение некоторого времени можно использовать побочные эффекты между контекстами OpenGL, окнами и кадровыми буферамиснимки экрана с использованием glReadPixels . В современных системах с композитными оконными менеджерами это больше не работает!

Вы лаете не на то дерево, извините.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...