Search code examples
c++openglshaderframebuffer

Render to Framebuffer/texture shows empty


I am trying to render to a framebuffer (with the same size as the window/screen) for post processing. Everything is in 2D so it should not give much trouble. Rendering directly to the screen works fine. But I only get the clear color and an empty buffer. The only way to render anything into it is by rendering a rectangle with the exact size of the buffer at position (0,0), which is strange.

I tried rendering at random locations into the buffer and nothing worked. Displaying/rendering the buffer to screen works.

Here is how i create the buffer:

    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    std::cout << "frame buffer fbo: " << fbo << std::endl;

    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    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, texture, 0);

    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        std::cout << "error creating screen buffer width: " << width << " height: " << height << std::endl;
    }
    else {
        std::cout << "created screen buffer width: " << width << " height: " << height << std::endl;
    }

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

Vertex shader:

#version 330 core

layout (location = 0) in vec2 vertex;
uniform mat4 projection;

void main() {
    gl_Position = projection * vec4(vertex.x, vertex.y, 0.0f, 1.0f);
}

Fragment shader:

#version 330 core

uniform vec4 in_color;
out vec4 FragColor ;

void main() {
    FragColor = in_color;
}

Projection matrix for rendering:

glm::mat4 projection = glm::ortho(0.0f, static_cast<GLfloat>(this->width), static_cast<GLfloat>(this->height), 0.0f, -1.0f, 1.0f);

Code to render into the buffer:

// binding and clearing the buffer to render into it
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glViewport(0, 0, width, height);
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

// render the rectangle
renderer->drawRectangle(0, 0, 10, 10, glm::vec4(1.0f, 0.0f, 1.0f, 1.0f));

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, resolutionWidth, resolutionHeight);

// rendering main screen showing the quad

The result is this (buffer rendered to screen at half size): Empty Quad/framebuffer showing clear color


Solution

  • I was following this tutorial when implementing this: https://learnopengl.com/Advanced-OpenGL/Framebuffers

    As my solution I simply changed the screen shader to accept my vertex/texture data. Then I noticed that the actual buffer data was perfectly fine...

    Vertex Shader:

    #version 330 core
    layout (location = 0) in vec4 aPos;
    
    out vec2 TexCoords;
    
    void main()
    {
        TexCoords = aPos.zw;
        gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
    } 
    

    Fragment Shader:

    #version 330 core
    out vec4 FragColor;
    
    in vec2 TexCoords;
    
    uniform sampler2D screenTexture;
    
    void main()
    { 
        FragColor = texture(screenTexture, TexCoords);
    }