我正在使用Qt构建一个渲染点云的应用程序。我的点云是在QQuickFrameBufferObject (包装OpenGL帧缓冲区对象并直接在屏幕上显示结果的Qt对象)中呈现的。
我还有另一个帧缓冲对象(QOpenGLFrameBufferObject),用来进行屏幕外渲染,它的大小是第一个对象的一半。
我从同一个函数(称为render)渲染到这两个函数。
如果我只在大的FBO中渲染,没有问题,一切看起来都应该是这样的。
但当我渲染到两者时,大FBO的内容被随机破坏(点被渲染在正确的位置,但都是黑色的)。它不会在所有的帧上发生,但当它发生时,所有的点都是黑色的(在所有VBO上)。哪个帧变暗是随机的。
我的VBO包含3个属性:vec3 position、float intensity和float time。当这些点是黑色时,看起来我的第一个顶点属性(vec3 position)通过了,但所有其他属性都没有设置,依赖于这些属性的颜色是黑色的(因为属性等于0);
顶点着色器:
#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();
}我的渲染函数如下所示:
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部分之前片刻。
我完全不知道是什么导致了这种情况。
发布于 2018-08-01 16:36:44
我找到问题了。我正在重新编译着色器程序,而它仍然被绑定和使用。这就是问题所在。我重构了着色器编译步骤,问题就消失了。
https://stackoverflow.com/questions/51609420
复制相似问题