yik
yik

Reputation: 75

Texture repeating over surface when rendered from FBO

I am trying to render a texture to a surface from a FBO but I am getting a repeat image effect like this: Repeating Image effect

I am not sure what is doing this. I am adapting the code from this tutorial: https://www.youtube.com/watch?v=21UsMuFTN0k which is in java to c++.

This is my code i use to setup to FBO:

GLuint frameBuffer;
glGenFramebuffers(1, &frameBuffer);
//generate name for frame buffer
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//create the framebuffer
glDrawBuffer(GL_COLOR_ATTACHMENT0);
//indicate that we will always render to color attachment 0

//texture setup
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 320, 180, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,texture, 0);

//depth buffer setup
GLuint depthBuffer;
glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 320, 180);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthBuffer);

This section is used to render:

//water is two triangle joined together
Water test(texture);
render->addWater(&test);
while (!glfwWindowShouldClose(window))
{
    // Set frame time
    GLfloat currentFrame = (float)glfwGetTime();
    deltaTime = currentFrame - lastFrame;
    lastFrame = currentFrame;
    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    gameController->update(deltaTime);

    glBindTexture(GL_TEXTURE_2D, 0);//To make sure the texture isn't bound
    glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
    glViewport(0, 0, 320, 180);

    render->renderScene();
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

    render->renderScene();
    render->renderWater();
    glfwSwapBuffers(window);
}

If there is any other code that is needed, let me know.

Upvotes: 1

Views: 91

Answers (1)

Rabbid76
Rabbid76

Reputation: 211278

The "repeat image" effect is caused, because you don't clear the framebuffer (color attachment texture and render buffer for the depth).

It is not sufficient to clear the drawing buffer. You have to clar the color plane and the depth buffer of the framebuffer too.

Bind the framebuffer, set the clear color (background of the texture) and clear the frame buffer. This causes that the each texel of the texture object is set to the color which you specify by glClearColor right before and the render buffer object (depthBuffer) is cleared (set to 1.0 - default value see glClearDepth).

glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

After rendering to the texture, set the default framebuffer for rendering, set the background color and clear the buffer:

glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Upvotes: 1

Related Questions