2015-01-12 5 views
1

Я пытаюсь отладить этот цикл рендеринга, который я не писал. Там где-то ошибка, из-за которой программа рушится, но glGetError(), похоже, играет смешно.glGetError() не работает до следующего кадра

Это в на прошивкой, и я использую GLKViewController, GLKView и EAGLContext рисовать.

Значительно сокращенный вариант рендеринга цикла что-то вроде этого:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{ 
    // At this point, GLKView's EAGLContext should be the active context 

    checkGlGetError(); 

    if (!isTextureInit || geometryChanged) 
    { 
     setupRenderTextureAndRenderbuffer(); 
    } 
    glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_originalFramebufferId); 
    glBindFramebuffer(GL_FRAMEBUFFER, _framebufferId); 

    // a. Some complex operations 
    // b. Some rendering on the texture framebuffer 

    glBindFramebuffer(GL_FRAMEBUFFER, _originalFramebufferId); 

    // c. Some additional complex operations 
    // d. Render the texture on screen 

    checkGlGetError(); 
} 

Это делает сбой приложения. Проблема в том, что последний вызов checkGlGetError() первого визуализированного фрейма не вызывает ошибок (и на экране ничего не отображается).

Первый checkGlGetError() вызов второго визуализированного фрейма дает критический текст GL_INVALID_ENUM, и вскоре после этого приложение сработает.

Если я заменить мой цикл рендеринга этим:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect 
{ 
    checkGlGetError(); 

    // a. Some complex operations 
    // b. Some rendering on the screen 

    checkGlGetError(); 
} 

Все работает, и никаких ошибок не сообщается. Но: почему не glGetError() ловит ошибку сразу после ошибочного вызова OpenGL? Почему он сообщает об этом только в начале следующего кадра?

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


UPDATE

Я загрузил весь код here. Это незавершенный порт Google's CardboardSDK (decompiled) от Java до Objective-C++, который я пытаюсь выполнить.

Основная линия рендеринга находится на классе CardboardViewController. Команда OpenGL, вызывающая сбой, должна быть в классе DistortionRenderer (функция которого состоит в том, чтобы использовать простые стереоскопические видовые экраны и отображать их на текстуре, чтобы применить искажение объектива к каждому).

Если вы установили CardboardViewController в distortionCorrectionEnabled на номер NO, авария уходит.

ответ

3

Там не достаточно информации здесь, чтобы отлаживать вашу проблему, так что вместо этого, общее замечание об отладке ...

glGetError это плохой способ отладки проблем GL в целом, но особенно в прошивке, и даже больше поэтому, когда вы используете GLKView или другие системы, которые работают от вашего имени. Возможно, вы устанавливаете какое-то состояние, которое не приводит к ошибке до тех пор, пока GLKView не начнет передавать материал на GPU (когда возвращается ваш drawRect:/glkView:drawInRect:).

Попробуйте использовать вместо этого Xcode Frame Capture tool. Вместо того, чтобы требовать, чтобы вы вставляли glGetError, проверяйте весь свой код (и убедитесь, что они отключены в сборках релизов), а затем попытайтесь понять результаты, он показывает вам ошибки (с хотя бы некоторым уровнем объяснения) для каждого вызов, в том числе сделанный от вашего имени в системном коде.И он показывает полный граф состояний и моментальные снимки кадра, который визуализируется для вызова по вызову, поэтому вы можете сказать более раннее, если вы устанавливаете какое-то состояние, вызывающее проблему.


Хорошо, одна мысль, что может быть специфическими для вашей проблемы: попробуйте использовать bindDrawable на GLKView вместо непосредственного повторного связывания его видеобуфер с glBindFramebuffer.

+0

Спасибо, это в высшей степени полезно. Я думаю, что сам смогу отлаживать его, используя инструмент * Xcode Frame Capture *. Тем не менее, пока вы отвечали, я просто добавил исходный код и более подробную информацию. –

+0

Использование bindDrawable фиксированной одной проблемы, связанной с буфером глубины, не присутствующим. Но странно, теперь кадр OpenGL говорит о наличии недопустимых ошибок перечисления в обеих этих двух строках: 'glGetIntegerv (GL_CULL_FACE, & this-> cullFaceEnabled); glGetIntegerv (GL_SCISSOR_TEST, & this-> scissorTestEnabled); '. Согласно документации OpenGL, они кажутся действительными. Есть предположения? –

+0

Итак, теперь я вижу, что для этих двух вы должны использовать 'glIsEnabled()' вместо этого (возможно, 'glGetIntegerv()' работает для этих двух аргументов на Android, но не на iOS). Попытка исправить дополнительную проблему сейчас. –