0

我正在处理我的 ssr 演示,因此我需要将一些渲染数据存储到纹理中以进行后期处理。但是当我使用这些纹理时,似乎在paintGL 中只能激活一个纹理单元:

//I did a small test
//enable texture unit
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gPosition);

//bind gColor to TEXTURE0
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gColor);

之后我可以确保渲染数据是正确的。但我无法在我的着色器中正确使用它,我测试了 gNormal、gColor、gPosition。但它们都显示与 gPosition 相同的图片。有人能帮我吗?

void fboTest::initShaders()
{
    //render to framebuffer
    QString vFrameBuffer ("#version 330 core\n"
            "layout (location = 0) in vec3 aPos;\n"
            "layout (location = 1) in vec3 aNormal;\n"

            "out float PosY;\n"
            "out vec3 FragPos;\n"
            "out vec3 Normal;\n"

            "uniform mat4 model;\n"
            "uniform mat4 view;\n"
            "uniform mat4 projection;\n"

            "void main()\n"
            "{\n"
            "   PosY = aPos.y + 0.3;\n"
            "   FragPos = aPos.xyz;\n"
            "   Normal = aNormal;\n"
            "   gl_Position = projection * view * model * vec4(aPos, 1.0);\n"
            "}\n");

    QString fFrameBuffer("#version 330 core\n"
                         "layout (location = 0) out vec3 gPosition;\n"
                         "layout (location = 1) out vec3 gNormal;\n"
                         "layout (location = 2) out vec3 gColor;\n"

                         "in float PosY;\n"
                         "in vec3 FragPos;\n"
                         "in vec3 Normal;\n"

                         "void main()\n"
                         "{\n"
                         "    gPosition = FragPos;\n"
                         "    gNormal = normalize(Normal);\n"
                         "    gColor = vec3(PosY, PosY + 0.2, PosY + 0.5);\n"
                         "    //gPosition = gColor;\n"
                         "}\n");
    shaderGeoPass.create();
    shaderGeoPass.addShaderFromSourceCode(QOpenGLShader::Vertex, vFrameBuffer);
    shaderGeoPass.addShaderFromSourceCode(QOpenGLShader::Fragment, fFrameBuffer);
    shaderGeoPass.link();

    //render to quad
    QString vQuad("#version 330 core\n"
                  "layout (location = 0) in vec2 aPos;\n"
                  "layout (location = 1) in vec2 aTexCoords;\n"

                  "out vec2 TexCoords;\n"

                  "void main()\n"
                  "{\n"
                  "    TexCoords = aTexCoords;\n"
                  "    gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0); \n"
                  "}\n");

    QString fQuad("#version 330 core\n"
                  "out vec4 FragColor;\n"
                  "in vec2 TexCoords;\n"

                  "uniform sampler2D gPosition;\n"
                  "uniform sampler2D gNormal;\n"
                  "uniform sampler2D gColor;\n"

                  "void main()\n"
                  "{\n"
//gPosition, gColor, gNormal get the same value???
                  "    vec3 col = texture(gPosition, TexCoords).rgb;\n"
                  "    FragColor = vec4(col, 1.0f);\n"
                  "} ");
    shaderReflectPass.create();
    shaderReflectPass.addShaderFromSourceCode(QOpenGLShader::Vertex, vQuad);
    shaderReflectPass.addShaderFromSourceCode(QOpenGLShader::Fragment, fQuad);
    shaderReflectPass.link();
    shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gPosition"), 0);
    shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gNormal"), 1);
    shaderReflectPass.setUniformValue(shaderReflectPass.uniformLocation("gColor"), 2);
}

油漆GL:

void fboTest::paintGL()
{
    glDisable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //enable texture unit
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, gColor);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, gNormal);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, gColor);

    shaderReflectPass.bind();
    glBindVertexArray(quadVAO);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}

初始化GL:

    initializeOpenGLFunctions();
    initShaders();
    initVAOs();
    initFrameBuffer();

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glEnable(GL_DEPTH_TEST);

    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, SCR_WIDTH, SCR_HEIGHT);

    shaderGeoPass.bind();
    QMatrix4x4 model;
    QMatrix4x4 view;
    QMatrix4x4 projection;
    view.lookAt({0, 0, 3}, {0, 0, 0}, {0, 1, 0});
    projection.perspective(45.0f,static_cast<float>(SCR_WIDTH)/static_cast<float>(SCR_HEIGHT),0.1f,100.0f);

    //render two cube
    glBindVertexArray(cubeVAO);
    model.translate(QVector3D(-1.0f, 0.0f, -1.0f));
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model);
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("view"), view);
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("projection"), projection);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    model.setToIdentity();
    model.translate(QVector3D(2.0f, 0.0f, 0.0f));
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model);
    glDrawArrays(GL_TRIANGLES, 0, 36);

    //render floor
    glBindVertexArray(planeVAO);
    model.setToIdentity();
    shaderGeoPass.setUniformValue(shaderGeoPass.uniformLocation("model"), model);
    glDrawArrays(GL_TRIANGLES, 0, 6);

初始化帧缓冲区:

void fboTest::initFrameBuffer()
{
    //first generate framebuffer object
    glGenFramebuffers(1, &framebuffer);
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

    //set up G-Buffer
    //1.positions
    //2.color
    //3.normal

    //1.positions
    glGenTextures(1, &gPosition);
    glBindTexture(GL_TEXTURE_2D, gPosition);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gPosition, 0);

    //2.normal
    glGenTextures(1, &gNormal);
    glBindTexture(GL_TEXTURE_2D, gNormal);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_FLOAT, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0);

    //3.color
    glGenTextures(1, &gColor);
    glBindTexture(GL_TEXTURE_2D, gColor);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SCR_WIDTH, SCR_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gColor, 0);

    //4.tell opengl which color attachment we'll use for rendering
    unsigned int attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 };
    glDrawBuffers(3, attachments);

    //5.we also need a depth buffer(renderbuffer)
    glGenRenderbuffers(1, &rbo);
    glBindRenderbuffer(GL_RENDERBUFFER, rbo);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, SCR_WIDTH, SCR_HEIGHT);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo);

    //finally check if framebuffer complete
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        qDebug() << "Framebuffer not complete!" << endl;
}
4

0 回答 0