2012-02-12 7 views
6

Estoy intentando renderizar una escena de multiempampso, aquí está el código que estoy usando. Me aparece una pantalla negra. Compruebo la integridad de FBO al final de init, e informan que ambos fbo están completos.FBO Blitting no funciona

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); 
} 

¿Puedes ver algo que dejé? Creo que el problema puede ser con la llamada glFramebufferRenderbuffer. Traté de cambiar el primer arg a GL_READ_FRAMEBUFFER pero no lo corrigió.

Reviso glGetError y no hay ningún error. Si configuro algo mal, seguramente algo fallará y me dará INVALID_ENUM o INVALID_OPERATION para ayudarme a reducir el problema.

La forma en que uso este código es que, para habilitar la multimuestreo, todo lo que tengo que cambiar es vincular multi_fbo al dibujar, y luego llamar a la función de resolución que enlazará y blit. Después de eso, mi textura fbo (que funciona bien cuando la renderizo directamente) ahora debería contener el render multiempañado. Pero es solo negro. También llamé al glEnable(GL_MULTISAMPLE) en otra parte del código de inicialización.

Ahora voy a intentar ajustar una textura no multisemmada a otra textura para asegurarme de que funciona. Espero que eso me ayude a reducir mi error.

Actualización: Por lo tanto, resulta que al copiar un FBO normal en otro FBO idéntico (ambos tienen texturas adjuntas al adjunto de color 0) se produce la misma pantalla negra. La blit simplemente no funciona.

Lo que también es extraño es que una vez que intento blittear, y luego dibujar la textura de la fuente fbo, todavía está toda negra. Es como intentar bombardear simplemente arruina todo.

¿Alguien sabe o tiene algún código FBO Blitting? No puedo encontrar ninguno, pero sé que la gente ha conseguido que funcione FBO multipamplificado.

Así es como usted puede ayudar: Si tiene código que llama glBlitFramebuffer en cualquier punto, me gustaría ver las otras llamadas para establecer que la operación hacia arriba. Parece que no puedo obtener nada más que búferes negros y texturas una vez que lo invoco.

Actualización: Blit to backbuffer funciona incluso con multisampling. Esto, por supuesto, no requiere absolutamente ninguna configuración, ya que solo ato el framebuffer 0. Así que el problema parece ser mi configuración del FBO, que tiene un accesorio de textura que se supone que se embotó.

Respuesta

4

Bueno, resulta que no hice nada malo aparte de no restablecer el enlace del framebuffer.

Al final de void resolve_multisample_FBO() simplemente necesitaba un glBindFramebuffer(GL_FRAMEBUFFER, 0);

una terrible manera de perder 3 horas, se lo aseguro. Pero el multisampling se ve muy bien y lo compensa con creces.