c++ - 使用自定义着色器在全屏四边形上从 QGLFramebufferObject 绘制纹理

标签 c++ qt opengl textures fbo

使用 QT 4.7 和 QGLWidget,我想使用 QGLWidget::paintGL() 将场景渲染到 QGLFramebufferObject 中,然后 - 使用 QGLFramebufferObject 生成的纹理 - 到屏幕上。对于第二步,我使用正交投影渲染全屏四边形,并使用自己的着色器将纹理渲染到它上面。

渲染到 QGLFramebufferObject 似乎工作正常(至少我可以调用 QGLFramebufferObject::toImage().save(filename) 并且我得到正确渲染的图像),但我无法将渲染纹理绘制到屏幕。

这里是我用来渲染到帧缓冲区对象中的代码:

    //Draw into framebufferobject
    _fbo->bind();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    _camera->applyModelviewMatrix();
    _scene->glDraw();
    glFlush();
    _fbo->release();
    _fbo->toImage().save("image.jpg");

如前所述,此处保存的图像包含正确渲染的图像。

这里是我尝试将帧缓冲区对象渲染到屏幕上的代码。我正在使用自己的着色器来渲染它。

    //Draw framebufferobject to a full-screen quad on the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glEnable(GL_TEXTURE_2D);
    _selectionShader->bind();
    glBindTexture(GL_TEXTURE_2D, _fbo->texture());
    _selectionShader->setUniformValue("renderedTexture", _fbo->texture());

    glBegin(GL_QUADS);
        glTexCoord2f(0.0,0.0);
        glVertex3f(0.0f,0.0f,0.0f);
        glTexCoord2f(1.0,0.0);
        glVertex3f(1.0f,0.0f,0.0f);
        glTexCoord2f(1.0,1.0);
        glVertex3f(1.0f,1.0f,0.0f);
        glTexCoord2f(0.0,1.0);
        glVertex3f(0.0f,1.0f,0.0f);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glFlush();
}

顶点着色器简单地通过它用作纹理坐标的位置

varying vec2 position;

void main()
{
    gl_Position = ftransform();
    position = gl_Vertex.xy;
}

然后片段着色器绘制纹理

varying vec2 position;
uniform sampler2D renderedTexture;

void main()
{
    gl_FragColor = texture2D(renderedTexture, position);
}

我正在做的投影是正确的,因为当我将片段着色器与下面的替换时,它绘制了预期的颜色渐变:

varying vec2 position;
uniform sampler2D renderedTexture;

void main()
{
    gl_FragColor = vec4(position.x, 0.0f, position.y, 1.0f);
}

但是使用另一个应该渲染纹理的片段着色器,我只得到一个空白屏幕(在渲染开始时被 glClear() 变成空白)。所以片段着色器似乎要么画黑色要么什么都不画。

我错过了什么吗?我是否将纹理正确传递给着色器?我还需要做任何其他事情来准备纹理吗?

最佳答案

_selectionShader->setUniformValue("renderedTexture", _fbo->texture());

这是(或)错误的部分。着色器中的采样器统一未设置为纹理对象,而是设置为该对象作为纹理绑定(bind)到的纹理单元(您已经使用 glBindTexture(GL_TEXTURE_2D, _fbo->texture() )。因此,由于您似乎一直在使用 GL_TEXTURE0,因此您只需将其设置为纹理单元 0:

_selectionShader->setUniformValue("renderedTexture", 0);

顺便说一下,不需要 glEnable(GL_TEXTURE_2D),使用着色器时不需要。如果您只是将顶点位置用作纹理坐标,为什么还要使用 glTexCoord2f

关于c++ - 使用自定义着色器在全屏四边形上从 QGLFramebufferObject 绘制纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19953055/

相关文章:

c++ - 指向数组的指针的声明 - 访问问题

c++ - 如何向 Global char *Array[] 添加一个元素?

c++ - C++中的指针与变速

c++ - 当基类是 QFile 时,为什么我不能从 QIODevice 重新实现方法?

c++ - 具有独特着色器的 OpenGL 多次绘制调用会出现空白屏幕

c++ - 不同模型的转换不起作用

c++ - 不用乘法求一个数的平方

c++ - Qt creator 无法解析 stddef.h --> 不正确的代码完成和突出显示

opengl - GLUT 退出重新定义错误

c++ - 为什么调用另一个对象的析构函数?