OpenGL ES 2.x: как удалить буфер глубины glDiscardFramebufferEXT? - PullRequest
2 голосов
/ 17 сентября 2011

Я прочитал Загрузки логического буфера iOS OpenGL ES , что прирост производительности может быть достигнут путем "отбрасывания" буфера глубины после каждого цикла отрисовки. Я пытаюсь это сделать, но мой игровой движок больше не рендерится. Я получаю glError 1286 или GL_INVALID_FRAMEBUFFER_OPERATION_EXT, когда пытаюсь выполнить следующий цикл.

У меня такое чувство, что мне нужно инициализировать или настраивать буфер глубины каждый цикл, если я собираюсь его отбросить, но я не могу найти какую-либо информацию по этому поводу. Вот как я запускаю буфер глубины (на самом деле все буферы):

    // ---- GENERAL INIT ---- //        
    // Extract width and height.
    int bufferWidth, bufferHeight;
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                 GL_RENDERBUFFER_WIDTH, &bufferWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,
                                 GL_RENDERBUFFER_HEIGHT, &bufferHeight);

    // Create a depth buffer that has the same size as the color buffer.
    glGenRenderbuffers(1, &m_depthRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, m_depthRenderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, GAMESTATE->GetViewportSize().x, GAMESTATE->GetViewportSize().y);

    // Create the framebuffer object.
    GLuint framebuffer;
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                              GL_RENDERBUFFER, m_colorRenderbuffer);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                              GL_RENDERBUFFER, m_depthRenderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, m_colorRenderbuffer);

И вот что я пытаюсь сделать, чтобы сбросить буфер глубины в конце каждого цикла рисования:

    // Discard the depth buffer
    const GLenum discards[]  = {GL_DEPTH_ATTACHMENT, GL_COLOR_ATTACHMENT0};
    glBindFramebuffer(GL_FRAMEBUFFER, m_depthRenderbuffer);
    glDiscardFramebufferEXT(GL_FRAMEBUFFER,1,discards);

Я звоню так сразу после всех моих розыгрышей и ...

[m_context presentRenderbuffer:GL_RENDERBUFFER];

Есть идеи? Любая информация, на которую кто-то может указать мне? Я попытался прочитать руководство Apple по этому вопросу (откуда у меня появилась оригинальная идея), http://developer.apple.com/library/ios/#documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html,, но, похоже, оно мне не совсем подходит.

1 Ответ

7 голосов
/ 17 сентября 2011

Ваш вызов glDiscardFramebufferEXT(GL_FRAMEBUFFER,1,discards) говорит о том, что вы отбрасываете только 1 вложение кадрового буфера, однако ваш массив сбросов включает в себя два: GL_DEPTH_ATTACHMENT и GL_COLOR_ATTACHMENT0.

Попробуйте изменить его на:

glDiscardFramebufferEXT(GL_FRAMEBUFFER, 2, discards);

Фактически вы говорите, что отбрасываете эти вложения кадрового буфера в конце цикла отрисовки, но непосредственно перед [m_context presentRenderbuffer:GL_RENDERBUFFER];.Вы отбрасываете вложение цветового рендеринга буфера, которое вам нужно для представления рендеринга буфера - возможно, попробуйте просто отбросить вложение глубины, так как в этом месте оно больше не требуется.

Вам нужно только инициализировать свои буферы один раз, не каждый цикл розыгрыша.glDiscardFramebufferEXT() на самом деле не удаляет ваше вложение кадрового буфера - это просто подсказка API, чтобы сказать, что содержимое рендеринга буфера не требуется в этом цикле отрисовки после завершения команды сброса.Из Apple OpenGL ES Руководство по программированию для iOS :

Операция сброса определяется расширением EXT_discard_framebuffer и доступна в iOS 4.0 и более поздних версиях.Операции сброса должны быть опущены, когда ваше приложение работает в более ранних версиях ioS, но включаются, когда они доступны.Сброс - это подсказка производительности для OpenGL ES;он сообщает OpenGL ES, что содержимое одного или нескольких буферов рендеринга не используется вашим приложением после завершения команды сброса.Намекнув OpenGL ES, что вашему приложению не нужно содержимое рендеринга, данные в буферах могут быть отброшены или можно избежать дорогостоящих задач по обновлению содержимого этих буферов.

...