0

我正在尝试渲染两个纹理,从第一个渲染到第二个,然后从第二个渲染到第一个等。问题是当我将第一个纹理渲染到第二个时,它工作正常,但渲染第二个是白色纹理,而它应该是紫色的。我正在使用 Qt 和 OpenGL。

两种纹理都绑定到同一个 FBO,我通过 glDrawBuffer(GL_COLOR_ATTACHMENT_i) 切换它们

这是我的初始化代码:

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

这是我的绘图代码:

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

我应该得到一个蓝色的屏幕,中间有一个紫色的四边形,而不是中间有一个白色的四边形。我在这里做错了什么?

4

1 回答 1

1

我在您的代码中看到了几个设置活动纹理的地方。但是设置活动纹理并不意味着程序将从哪个纹理单元中提取。这是由访问纹理的采样器制服中设置的纹理图像单元决定的。您需要更改该制服,而不是活动纹理。

或者更好的是,只需将其他纹理绑定到上下文。无需设置活动纹理图像单元;只需绑定要从中采样的纹理。glActiveTexture真的,你打的任何电话都没有意义。

于 2013-05-05T14:23:58.580 回答