I have read several tutorials and answers regarding framebuffers and glViewport, but I can't seem to resolve this issue I have. I want to take a low resolution framebuffer (400x225) and place it in a 1280x720 window at the position 100x100 (from bottom-left);

  1. Load a 400x225 png image in a framebuffer with the same size
glGenFramebuffers(1, &m_framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);

glGenTextures(1, &m_textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, m_textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 400, 225, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_textureColorbuffer, 0);

glGenRenderbuffers(1, &m_renderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screenW, screenH); stencil buffer.
    printf("ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
glBindFramebuffer(GL_FRAMEBUFFER, 0);
  1. Generate the quad for the framebuffer:
    float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
    // positions   // texCoords
    -1.0f,  1.0f,  0.0f, 1.0f,
    -1.0f, -1.0f,  0.0f, 0.0f,
     1.0f, -1.0f,  1.0f, 0.0f,

    -1.0f,  1.0f,  0.0f, 1.0f,
     1.0f, -1.0f,  1.0f, 0.0f,
     1.0f,  1.0f,  1.0f, 1.0f

    unsigned int quadVBO;
    glGenVertexArrays(1, &m_quadVAO);
    glGenBuffers(1, &quadVBO);
    glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
  1. Create an orthographic projection matrix with the framebuffer size:
glm::mat4 bgProjection = glm::ortho(0.0f, static_cast<float>(400), static_cast<float>(225), 0.0f, -1.0f, 1.0f);
  1. Set the glViewport:
glViewport(0, 0, 400, 225);
  1. Bind the framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
  1. Draw the sprite:
    glm::mat4 model = glm::mat4(1.0f);
    model = glm::translate(model, glm::vec3(position, 0.0f));  // first translate (transformations are: scale happens first, then rotation, and then final translation happens; reversed order)

    model = glm::translate(model, glm::vec3(0.5f * size.x, 0.5f * size.y, 0.0f)); // move origin of rotation to center of quad
    model = glm::rotate(model, glm::radians(rotate), glm::vec3(0.0f, 0.0f, 1.0f)); // then rotate
    model = glm::translate(model, glm::vec3(-0.5f * size.x, -0.5f * size.y, 0.0f)); // move origin back

    model = glm::scale(model, glm::vec3(size, 1.0f)); // last scale

    shader->setMat4("model", model);
    shader->setMat4("projection", projection);

    shader->setVec3("Colour", color);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
  1. Unbind the framebuffer:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
  1. Finally render the framebuffer:
    glBindTexture(GL_TEXTURE_2D, m_textureColorbuffer); // use the color attachment texture as the texture of the quad plane
    glDrawArrays(GL_TRIANGLES, 0, 6);

This is the output I get when glViewport(0, 0, 400, 225); enter image description here

But when I set the glViewport(100, 100, 400, 225); I get these black borders: enter image description here

As you can see, the glViewport has moved to 100x100, but it has also created a 100x100 gap in the viewport. I have tried adjusting the projection matrix and framebuffer, but it seems like I am doing something incorrect with glViewport. Thank you.


1 Answer 1


Your viewport is taken into account 2 times: before drawing the sprite and before rendering the framebuffer. I suggest keeping current glViewport(0, 0, 400, 225); as it is and adding one more glViewport right before drawing the framebuffer. In this seccond glViewport you can set up needed offset.

  • \$\begingroup\$ That worked brilliantly, thank you. Here is what I changed: 1. glViewport(0, 0, 400, 225); 2.. Bind framebuffer 3. Draw sprite 4. Unbind framebuffer 5. glViewport(100, 100, 400, 225); 6. Render framebuffer \$\endgroup\$
    – Aaron Z
    Commented Jan 9, 2021 at 15:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .