首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >渲染到FBO会损坏另一个FBO

渲染到FBO会损坏另一个FBO
EN

Stack Overflow用户
提问于 2018-07-31 16:59:17
回答 1查看 87关注 0票数 0

我正在使用Qt构建一个渲染点云的应用程序。我的点云是在QQuickFrameBufferObject (包装OpenGL帧缓冲区对象并直接在屏幕上显示结果的Qt对象)中呈现的。

我还有另一个帧缓冲对象(QOpenGLFrameBufferObject),用来进行屏幕外渲染,它的大小是第一个对象的一半。

我从同一个函数(称为render)渲染到这两个函数。

如果我只在大的FBO中渲染,没有问题,一切看起来都应该是这样的。

但当我渲染到两者时,大FBO的内容被随机破坏(点被渲染在正确的位置,但都是黑色的)。它不会在所有的帧上发生,但当它发生时,所有的点都是黑色的(在所有VBO上)。哪个帧变暗是随机的。

我的VBO包含3个属性:vec3 positionfloat intensityfloat time。当这些点是黑色时,看起来我的第一个顶点属性(vec3 position)通过了,但所有其他属性都没有设置,依赖于这些属性的颜色是黑色的(因为属性等于0);

顶点着色器:

代码语言:javascript
复制
#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in float intensity; // randomly equals to 0
layout (location = 2) in float time;

uniform mat4 viewProjectionMatrix;

flat out vec4 f_color;

vec4 getIntensityColor() {
    return vec4(vec3(intensity / 65535.0), 1.0);
}

void main() {   
    gl_PointSize = properties.pointSize;
    gl_Position = viewProjectionMatrix * vec4(position.x, position.y, position.z, 1.0);


    f_color = getIntensityColor();
}

我的渲染函数如下所示:

代码语言:javascript
复制
void render() {

    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ZERO);
    glBlendEquation(GL_FUNC_ADD);

    // the big FBO is bound before the call to this function. Hence why I do not bind it here
    if(_manager.renderToBigFbo()) { 

        glClearColor(_properties.clearColor.redF(), _properties.clearColor.greenF(), _properties.clearColor.blueF(), _properties.clearColor.alphaF());

        glEnable(GL_PROGRAM_POINT_SIZE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        QMatrix4x4 viewProjectionMatrix = _properties.camera.viewProjectionMatrix();

        _renderer->beforeRendering(viewProjectionMatrix, _properties, boundingBox, datasetMetadata);
        _renderer->bindVao();

        for(auto const& vbo : _vbos) {
            _renderer->render(vbo.second->data.get());
        }

        _renderer->afterRendering();
        _renderer->unbindVao();

    }

    if(_manager.renderToSmallFbo()) {
        static constexpr int boxSize = 20.0 * _fboFactor + 1; // box of NxNxN.
        QSize fboSize = _size * _fboFactor;

        _smallFbo->bind(); // FBO is bound here

        glViewport(0, 0, fboSize.width(), fboSize.height());

        glClearColor(0, 0, 0, 0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_PROGRAM_POINT_SIZE);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LESS);
        glEnable(GL_SCISSOR_TEST);
        glScissor(_manager.getMousePosition().x() * _fboFactor - (boxSize / 2.0), 
            _manager.getMousePosition().y() * _fboFactor - (boxSize / 2.0), boxSize, boxSize);

        QMatrix4x4 viewProjectionMatrix = _properties.camera.viewProjectionMatrix();

        // change some properties. Will cause the vertex shader to be recompiled
        auto colorMode = _properties.colorMode;
        auto pointSize = _properties.pointSize;
        _properties.colorMode = ColorModeItem::ColorMode::INDEX;
        _properties.pointSize = pointSize / 2;


        _renderer->beforeRendering(viewProjectionMatrix, _properties, boundingBox, datasetMetadata);
        _renderer->bindVao();

        for(auto const& vbo : _vbos) {
            _renderer->render(vbo.second->data.get());
        }

        _renderer->afterRendering();
        _renderer->unbindVao();

        }

        // reset the old color mode
        _properties.colorMode = colorMode;
        _properties.pointSize = pointSize;

        glDisable(GL_SCISSOR_TEST);

        // do stuff with the FBO's content
        QImage img (_smallFbo->toImage(false));
        QImage image(img.constBits(), img.width(), img.height(), QImage::Format_ARGB32);

        _smallFbo->release();           
    }

    // needed by Qt
    if(_window != nullptr) {
        _window->resetOpenGLState();
    }
}

vbos对象的render成员函数绑定缓冲区,设置顶点属性指针并调用glDrawArrays

我正在渲染完全相同的VBO,并在两个FBO中绑定完全相同的VAO,但顶点着色器在两个渲染之间重新编译,以显示不同的颜色集。

如果我不在小FBO渲染部分绑定VAO,问题就会消失(当然,小FBO不再包含我想要的东西,但它会停止破坏其他FBO)。这很奇怪,因为VAO已经成功地绑定在大FBO部分之前片刻。

我完全不知道是什么导致了这种情况。

EN

回答 1

Stack Overflow用户

发布于 2018-08-01 16:36:44

我找到问题了。我正在重新编译着色器程序,而它仍然被绑定和使用。这就是问题所在。我重构了着色器编译步骤,问题就消失了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51609420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档