Внеэкранные кадровые буферы в OpenGL - PullRequest
3 голосов
/ 30 января 2012

Я создаю игру для iPhone с использованием OpenGL и хочу нарисовать на закадровом кадровом буфере, а затем использовать этот кадровый буфер в качестве текстуры для рисования на реальном экране.Я основал свой код на Apple и примере GLSprite, но кажется, что я не делаю это правильно, когда дело доходит до переключения цели рисования, поскольку я получаю только пустую текстуру.Код, который я использую ниже.Что случилось?Каков наилучший способ рендеринга текстуры на лету?

При создании нижекадрового кадрового буфера приведен код ошибки 8cd6.

Создание экранного кадрового буфера

glGenFramebuffersOES(1, &viewFramebuffer);
glGenRenderbuffersOES(1, &viewRenderbuffer);

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer];
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);

glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);

if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
    NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
    return NO;
}

Создание закадрового кадрового буфера

glGenFramebuffers(1, &offscreenFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, offscreenFramebuffer);

glGenTextures(1,&framebufferTexture);
glBindTexture(GL_TEXTURE_2D, framebufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferTexture, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE) {
    NSLog(@"ERROR: %x", status);
}

Рисование, цикл:

glBindTexture(GL_TEXTURE_2D,textureFromFile); //Switch to a texture from a file
glBindFramebufferOES(GL_FRAMEBUFFER_OES, offscreenFramebuffer); //Switch to the offscreen framebuffer
//Render the texture to be used later
glBindTexture(GL_TEXTURE_2D,framebufferTexture); //Switch to the offscreen framebuffer's texture
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); //Switch to the screen framebuffer
//Do the drawing using the texture rendered just before, and present this to the screen.

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

Ответы [ 2 ]

4 голосов
/ 30 января 2012

Проблема проста: вы забыли нарисовать на экране . Вы знаете, кадровый буфер по умолчанию, что вы получаете, когда делаете glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); То, что вы рендерили, было очень хорошо перед написанием этого кода.

Не существует такого понятия, как "экранный" объект кадрового буфера. Все пользовательские FBO по определению находятся вне экрана.

У тебя не должно быть этого viewFramebuffer FBO вообще. Вместо этого вы должны рисовать на вашей текстуре, а затем использовать эту текстуру для рисования в стандартный кадровый буфер.

0 голосов
/ 31 января 2012

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

Я считаю, что вам нужно добавить что-то вроде следующего в ваш код создания закадрового кадрового буфера (вам нужно добавить суффикс OES к одной или нескольким функциям здесь, потому что они из приложения OpenGL ES 2.0) :

    glGenRenderbuffers(1, &renderbuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8_OES, bufferSize.width, bufferSize.height);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer); 
...