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 (400×225) and place it in a 1280×720 window at the position 100×100 (from bottom-left);
- Load a 400×225 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); 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, m_textureColorbuffer, 0); glGenRenderbuffers(1, &m_renderBuffer); glBindRenderbuffer(GL_RENDERBUFFER, m_renderBuffer); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, screenW, screenH); stencil buffer. glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_renderBuffer); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) printf("ERROR::FRAMEBUFFER:: Framebuffer is not complete!"); glBindFramebuffer(GL_FRAMEBUFFER, 0);
- 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); glBindVertexArray(m_quadVAO); glBindBuffer(GL_ARRAY_BUFFER, quadVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
- 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);
- Set the
glViewport
:
glViewport(0, 0, 400, 225);
- Bind the framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
- Draw the sprite:
shader->use(); 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); glBindVertexArray(this->quadVAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0);
- Unbind the framebuffer:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
- Finally render the framebuffer:
shader.use(); glBindVertexArray(m_quadVAO); 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);
But when I set the glViewport(100, 100, 400, 225);
I get these black borders:
As you can see, the glViewport
has moved to 100×100, but it has also created a 100×100 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.