OpenGL ping ponging with two textures on the same framebuffer

I'm trying to render to two textures, rendering from the first to the second, and then from the second to the first etc. The problem is that when I'm rendering the first texture to the second, it works fine but rendering the second to the first leaves a white texture, when it's supposed to be a purple one. I'm working with Qt and OpenGL.

Both textures are bound to the same FBO, and I'm switching them through glDrawBuffer(GL_COLOR_ATTACHMENT_i)

Here is my initialization code:

void GlWidget::initializeGL() {
    glewInit();
    src = true;
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_TEXTURE_2D);
    //glEnable(GL_CULL_FACE);

// Generate the texture to be drawn
    tex = new float[256*256*4];
    for(int i = 0; i < 256*256*4; i++){
        if (i % 4 == 0){
            tex[i] = 0.5;
        }else if (i % 4 == 1){
            tex[i] = 0.3;
        }else if (i % 4 == 2){
            tex[i] = 0.5;
        }else if (i % 4 == 3){
            tex[i] = 0;
        }
    }



    glGenTextures(1, &texture);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    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_RGBA32F, 256, 256, 0,  GL_RGBA, GL_FLOAT, tex);

    glGenTextures(1, &targetTex);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, targetTex);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    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_RGBA32F, 256, 256, 0,  GL_RGBA, GL_FLOAT, NULL);

    glGenFramebuffers(1, &fb);
    glBindFramebuffer(GL_FRAMEBUFFER, fb);
    //Attach 2D texture to this FBO
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, targetTex, 0);
    glDrawBuffer (GL_COLOR_ATTACHMENT1);
    //-------------------------
    glGenRenderbuffers(1, &depth_rb);
    glBindRenderbuffer(GL_RENDERBUFFER_EXT, depth_rb);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, 256, 256);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER, depth_rb);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
    shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
    shaderProgram.link();
    vertices << QVector3D(-1, -1, -2) << QVector3D(-1, 1, -2) << QVector3D(1, 1, -2) << QVector3D(1, -1, -2);
    texCoords << QVector2D(0, 0) << QVector2D(0, 1) <<  QVector2D(1, 1) << QVector2D(1, 0);
}

And here is my drawing code:

void GlWidget::render_to_screen () {
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    qglClearColor(QColor(Qt::blue));
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    if(src){
        glActiveTexture(GL_TEXTURE0);
    }else{
        glActiveTexture(GL_TEXTURE1);
    }

    shaderProgram.enableAttributeArray("textureCoordinates");
    shaderProgram.enableAttributeArray("vertex");

    glDrawArrays(GL_QUADS, 0, vertices.size());
    shaderProgram.disableAttributeArray("vertex");
    shaderProgram.disableAttributeArray("textureCoordinates");
}

void GlWidget::paintGL()
{
    qDebug() << "Updating";
    glBindFramebuffer(GL_FRAMEBUFFER, fb);
    if(src) {
        glDrawBuffer(GL_COLOR_ATTACHMENT1);
        glActiveTexture(GL_TEXTURE0);
    }else {
        glDrawBuffer(GL_COLOR_ATTACHMENT0);
        glActiveTexture(GL_TEXTURE1);
    }
    src = !src;
    qglClearColor(QColor(Qt::white));
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    QMatrix4x4 mMatrix;
    QMatrix4x4 vMatrix;


    shaderProgram.bind();

    shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
    shaderProgram.setAttributeArray ("textureCoordinates", texCoords.constData ());
    shaderProgram.enableAttributeArray("textureCoordinates");
    shaderProgram.setAttributeArray("vertex", vertices.constData());
    shaderProgram.enableAttributeArray("vertex");

    glDrawArrays(GL_QUADS, 0, vertices.size());

    shaderProgram.disableAttributeArray("vertex");
    shaderProgram.disableAttributeArray("textureCoordinates");
    render_to_screen ();
    shaderProgram.release();
}

I'm supposed to be getting a blue screen with a purple quad in the center, instead I'm getting a white quad in the center. What am I doing wrong here?


I see several places in your code where you set the active texture. But setting the active texture means nothing as far as what texture unit the program will pull from. That's decided by the texture image unit set into the sampler uniform that's accessing the texture. You need to change that uniform, not the active texture.

Or better yet, just bind the other texture to the context. There's no need to set the active texture image unit; just bind the texture you want to sample from. Really, there's no point in any of the glActiveTexture calls you're making.

链接地址: http://www.djcxy.com/p/33926.html

上一篇: FBO渲染纹理导致白色纹理

下一篇: OpenGL在相同的帧缓冲上使用两种纹理乒乓