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);
- 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);
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 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.