Renderice la escena OpenGL para texturizar usando FBO en el dibujo de tubería de función fija

El problema

Trabajo en los torcs de juegos de código abierto (http://torcs.sourceforge.net/) La canalización gráfica del juego todavía está utilizando la canalización de función fija (FFP) de OpenGL 1.3.

Intento renderizar las escenas del juego a texturas en un FBO (objeto Framebuffer) para realizar un procesamiento posterior en las texturas renderizadas. Yo uso OpenGL 3.3. en mi maquina

Actualmente he configurado el FBO con texturas adjuntas enGL_COLOR_ATTACHMENT0&1 (2 para tener dos cuadros consecutivos legibles en el sombreador) y un buffer de renderizado adjunto enGL_DEPTH_ATTACHMENT.

Después de vincular el FBO, se ejecuta la función de representación del juego. Cuando luego desate el FBO y para la validación, escriba la textura a través de un programa de sombreado en el búfer de la ventana, la escena está incompleta. Para ser más específicos, solo se muestra el contorno del automóvil, al igual que las marcas de los neumáticos y algo de humo. Esto muestra quealgo se representa a la textura de la FBO, pero no todo. Entre otros, no se presentan texturas (para árboles, casas, césped, etc.) a la textura en el FBO. Esto sugiere que mi configuración de textura es incorrecta, pero desafortunadamente mi conocimiento de OpenGL es limitado, por lo que espero su ayuda.

Otra cosa que vale la pena señalar es que si dejo de lado la líneaglActiveTexture(GL_TEXTURE0); antes de que ocurra el dibujo, se mostrará una textura (es decir, se escribirá en el FBO y se volverá a escribir en el marco del sistema de ventanas en lugar del contorno del automóvil).

El código

El siguiente código muestra la inicialización del FBO (dehttps://en.wikibooks.org/wiki/OpenGL_Programming/Post-Processing):

int screen_width = 640; 
int screen_height = 480;
/* Texture A*/
glGenTextures(1, &fbo_texture);
glBindTexture(GL_TEXTURE_2D, fbo_texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);

/* Texture B*/
//glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &fbo_texture_a);
glBindTexture(GL_TEXTURE_2D, fbo_texture_a);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, screen_width, screen_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_2D, 0);

/* Depth buffer */
glGenRenderbuffers(1, &rbo_depth);
glBindRenderbuffer(GL_RENDERBUFFER, rbo_depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, screen_width, screen_height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);

/* Framebuffer to link everything together */
glGenFramebuffers(1, &fbo);
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo_texture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, fbo_texture_a, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo_depth);
GLenum status;
if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
    fprintf(stderr, "glCheckFramebufferStatus: error 0x%x", status);
    return 0;
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);

/* Compile and link shaders */
...

El siguiente código muestra dónde ocurre el dibujo: Editar: Siuse_fbo=false entonces todo se representará en la pantalla directamente como antes. Los únicos cambios que hice están dentro de los corchetes.

if (use_fbo) 
{
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glPushAttrib(GL_VIEWPORT_BIT);
    glViewport(0,0,grWinw, grWinh);

    if (fbo_a) // drawing to fbo_texture_a
    {               
        glDrawBuffer(GL_COLOR_ATTACHMENT1);
        glActiveTexture(GL_TEXTURE0+11);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, fbo_texture_a);
    }
    else
    {
        glDrawBuffer(GL_COLOR_ATTACHMENT0);
        glActiveTexture(GL_TEXTURE0+12);
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, fbo_texture);
    }
    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
}

glClearColor(0.7f, 0.1f, 0.1f, 1.0f); //clear with red to see what is drawn to the fbo
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

grScreens[0]->update(s, grFps);//THIS IS WHERE THE DRAWING HAPPENS unchanged from original drawing in TORCS

if (use_fbo) 
{
    glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glEnable(GL_TEXTURE_2D);
    glDrawBuffer(GL_BACK);

    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glUseProgram(program_postproc);

    if (fbo_a) // drawn to fbo_texture_a
    {
        glUniform1i(uniform_fbo_texture, 11);        
        glUniform1i(uniform_fbo_texture_a, 12);        
        fbo_a=!fbo_a;
    }
    else
    {
        glUniform1i(uniform_fbo_texture, 12);        
        glUniform1i(uniform_fbo_texture_a, 11);        
        fbo_a=!fbo_a;
    }

    glEnableVertexAttribArray(attribute_v_coord_postproc);

    glBindBuffer(GL_ARRAY_BUFFER, vbo_fbo_vertices);
    glVertexAttribPointer(
            attribute_v_coord_postproc, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    glDisableVertexAttribArray(attribute_v_coord_postproc);
    glUseProgram(0); 
}

Espero haberte proporcionado suficiente información para que me ayudes con esto. Cualquier consejo es apreciado.

EDITAR: Revisé mi código de sombreador y la implementación de FBO nuevamente (lo simplifiqué a un solo archivo adjunto de color, etc. con un dibujo simplificado) y todo funcionó. Creo que el problema es la combinación de la canalización de funciones fijas para dibujar y mi implementación del FBO ...

EDITAR: Aquí hay dos imágenes de lo que sucede con use_fbo = verdadero vs. falso: (Nota: el color rojo es el color claro después de que se vincula el FBO, para ver lo que se procesa en el fbo: nada más que la sombra y las marcas de deslizamiento)

También intenté visualizar el búfer de profundidad (cambié la implementación a un archivo adjunto de textura para la profundidad) y aunque linealicé, no había información. Supongo que la profundidad tampoco está escrita correctamente en el FBO.

Respuestas a la pregunta(1)

Su respuesta a la pregunta