2012-02-12 3 views
6

Я пытаюсь сделать многосэмплинную сцену текстурой, вот код, который я использую. Я получаю черный экран. Я проверяю полноту fbo в конце init, и они сообщают, что оба fbo завершены.FBO Blitting не работает

void init_rendered_FBO() { 
    glGenFramebuffers(1,&fbo); 
    glBindFramebuffer(GL_FRAMEBUFFER, fbo); 
    glGenTextures(1,&fbo_tex); 
    glBindTexture(GL_TEXTURE_2D, fbo_tex); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width_screen, height_screen, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); 
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, width_screen, height_screen); 
    glBindTexture (GL_TEXTURE_2D, 0); 
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_tex, 0); 
    int objectType; 
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,&objectType); 
    ASSERT(objectType == GL_TEXTURE); 
    int objectName; 
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,&objectName); 
    ASSERT(glIsTexture(objectName) == GL_TRUE); 
    int wid, hei, fmt; 
    glBindTexture(GL_TEXTURE_2D, objectName); 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &wid); 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &hei); 
    glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, 
      &fmt); 
    glBindTexture(GL_TEXTURE_2D, 0); 
    std::string format = convertInternalFormatToString(fmt); 
    std::cout << "Color attachment 0: " << objectName << " " << wid << "x" << hei << ", " << format << std::endl; 
    ASSERT(checkFramebufferStatus()); 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
} 

// this is the init function that gets called. 
void init_rendered_multisample_FBO() { 
    init_rendered_FBO(); 
    // now I'm going to set up the additional component necessary to perform multisampling which is a new fbo 
    // that has a multisampled color buffer attached. I won't need a multisample depth buffer. 
    glGenFramebuffers(1,&multi_fbo); 
    glBindFramebuffer(GL_FRAMEBUFFER,multi_fbo); 
    glGenRenderbuffers(1,&renderbuffer_multi); 
    glBindRenderbuffer(GL_RENDERBUFFER,renderbuffer_multi); 
    glRenderbufferStorageMultisample(GL_RENDERBUFFER, 4, GL_RGBA, width_screen,height_screen); 
    glBindRenderbuffer(GL_RENDERBUFFER,0); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer_multi); 
    int objectType; 
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,&objectType); 
    ASSERT(objectType == GL_RENDERBUFFER); 
    int objectName; 
    glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,&objectName); 
    ASSERT(glIsRenderbuffer(objectName) == GL_TRUE); 
    glBindRenderbuffer(GL_RENDERBUFFER,objectName); 
    int wid,hei,fmt,sam; 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_WIDTH,&wid); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_HEIGHT,&hei); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_INTERNAL_FORMAT,&fmt); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,GL_RENDERBUFFER_SAMPLES,&sam); 
    glBindRenderbuffer(GL_RENDERBUFFER,0); 
    printf("Renderbuffer: %dx%d, fmt=%d, samples=%d\n",wid,hei,fmt,sam); 
    ASSERT(checkFramebufferStatus()); 
    glBindFramebuffer(GL_FRAMEBUFFER, 0); 
} 
// this is called after rendering to multi_fbo 
void resolve_multisample_FBO() { 
    glBindFramebuffer(GL_READ_FRAMEBUFFER, multi_fbo); 
    glReadBuffer(GL_COLOR_ATTACHMENT0); 
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); 
    GLenum drawbuf = GL_COLOR_ATTACHMENT0; 
    glDrawBuffers(1,&drawbuf); 
    glBlitFramebuffer(0,0,width_screen,height_screen,0,0,width_screen,height_screen,GL_COLOR_BUFFER_BIT,GL_NEAREST); 
} 

Можете ли вы заметить что-нибудь, что я упустил? Я думаю, что проблема может быть связана с вызовом glFramebufferRenderbuffer. Я попытался переключить первый arg на GL_READ_FRAMEBUFFER, но это не исправить.

Я проверяю glGetError и ошибок нет. Если я настрою что-то неправильно, наверняка что-то не получится и даст мне INVALID_ENUM или INVALID_OPERATION, чтобы помочь мне сузить вопрос.

Способ использования этого кода заключается в том, что для включения мультисэмплирования все, что мне нужно изменить, это привязать multi_fbo при рисовании, а затем вызвать функцию разрешения, которая будет связываться и blit. После этого моя текстура fbo (которая отлично работает, когда я показываю непосредственно ей) теперь должна содержать мультисэмплин. Но это просто черное. Я также позвонил glEnable(GL_MULTISAMPLE) в другой части кода инициализации.

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

Обновление: Таким образом, получается копирование обычного FBO на другое идентичное FBO (оба имеют текстуры, прикрепленные к цветному вложению 0), выдает тот же черный экран. Блит просто не работает.

Также странно, что как только я пытаюсь вспыхнуть, затем нарисуйте текстуру SOURCE fbo, она все еще черная. Это похоже на попытку блаженства, просто разрушает все.

Кто-нибудь знает или имеет код БЛП? Я не могу найти никого, но я знаю, что люди получили многосэмплинговое FBO.

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

Обновление: Blit to backbuffer работает, даже с мультисэмплингом! Это, конечно, абсолютно не требует установки, так как я просто привязываю фреймбуфер 0. Поэтому проблема заключается в том, что проблема заключается в создании FBO, у которого есть привязка текстуры, которая должна быть задействована.

ответ

4

Ну, оказывается, я не делал ничего плохого, кроме как не сбрасывал привязку фреймбуфера.

В конце void resolve_multisample_FBO() я просто нуждался в glBindFramebuffer(GL_FRAMEBUFFER, 0);

ужасный способ тратить 3 часа, я вас уверяю. Но мультисэмплинг выглядит великолепно и более чем компенсирует это.