通过调用glBindFramebuffer(GL_FRAMEBUFFER,0),OpenGL不会呈现到屏幕

时间:2017-02-25 12:14:24

标签: c++ qt opengl opengl-es

通常,此代码会将纹理图像渲染为屏幕。但是,如果我现在将命令glBindFramebuffer(GL_FRAMEBUFFER,0)添加到代码中,它将不会呈现任何内容。它以glClearColor的颜色呈现屏幕。我正在使用QT,所以使用QOpenGLWidget。

glViewport(0, 0, _width, _height);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glDisable(GL_DEPTH_TEST);

_program.bind();
glBindVertexArray(_vao);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureID);
glUniform1i(glGetUniformLocation(_program.programId(), "u_texture"), 1);

glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);

想要可能出错?

编辑:

/ * final.fsh * /

版本330核心

uniform sampler2D u_texture;
in vec4 qt_TexCoord0;

out vec4 fragColor;

void main(void)
{
    fragColor = texture(u_texture, qt_TexCoord0.xy);
}

/ * final.vsh * /

版本330核心

layout (location = 0) in vec3 a_position;

out vec4 qt_TexCoord0;

void main(void)
{
    gl_Position =  vec4(a_position, 1.0);

    const mat4 B = mat4(0.5,  0.0, 0.0, 0.0,
                            0.0,  0.5, 0.0, 0.0,
                            0.0,  0.0, 0.5, 0.0,
                            0.5,  0.5, 0.5, 1.0);

    qt_TexCoord0 = B * vec4(a_position, 1.0);
}

/ *将VAO加载到GPU * /

GLfloat max_ = 1.0;
GLfloat min_ = -1.0;
GLfloat vert[] = {
    max_,  max_, 0,
    max_, min_, 0,
    min_, max_, 0,

    max_,  min_, 0,
    min_, min_, 0,
    min_,  max_, 0,
};

glGenVertexArrays(1, &_vao);
glBindVertexArray(_vao);

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);

glBufferData(GL_ARRAY_BUFFER, sizeof(vert), vert, GL_STATIC_DRAW);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*3, (GLvoid*)0);
glBindVertexArray(0);

1 个答案:

答案 0 :(得分:6)

正如G.M.所述,根据the docsglBindFramebuffer(GL_FRAMEBUFFER, 0)“打破了帧缓冲对象与目标的现有绑定”。在使用帧缓冲区进行一些屏幕外渲染后,您需要此调用。当您想最终渲染到屏幕时,您必须通过调用glDrawBuffer(GL_BACK)来渲染后台缓冲区

所以你的渲染循环可能看起来像

// Do some rendering stuff in n offscreen textures
glBindFramebuffer(GL_FRAMEBUFFER, the_buffer);
glDrawBuffers(n, buffers);
// Rendering calls

// Finally use the results for the final rendering 
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
// Rendering calls

编辑: 您似乎正在使用QOpenGLWidget作为OpenGL提供商/窗口系统。 Qt人正在使用framebuffers来渲染他们的UI,而QOpenGLWidget的结果内容则是在FBO中绘制的。

所以,它意味着什么(至少根据我的经验,可能有更好的方法来解决这个问题),就是你不能再在后台缓冲区渲染了,你必须在Qt s {{{ 1}}。

一种方法(再次,它可能不是最好的方式,但它对我有用),是在渲染开始时保存绑定的帧缓冲区,并在此缓冲区中进行最终渲染。这导致

framebuffer