Im trying to retain the ratio and sizes of the rendered content when resizing my window/framebuffer texture on which im rendering exclusively on the xy-plane (z=0) and would like to have an orthographic projection.
Some general questions, do i need to resize both glm::ortho and viewport, or just one of them? Do both of them have to have the same amount of pixels or just the same aspect ratio? What about their x and y offsets?
I understand that i need to update the texture size.
What i have tried (among many other things):
One texture attachment on my framebuffer, a gl_RGB on GL_COLOR_ATTACHMENT0. I render my framebuffers attached texture to a ImGui window with imgui::image(), When this ImGui window is resized I resize the texture assignent to my FBO using this: (i do not reattach the texture with glFramebufferTexture2D!)
void Texture2D::SetSize(glm::ivec2 size)`
{
Bind();
this->size = size;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.x, size.y, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
Unbind();
}
I also update the member variable windowSize.
In my renderingloop (for the Framebuffer) i use
view = glm::lookAt(glm::vec3(0, 0, 1), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
glm::vec2 projWidth = windowSize.x;
glm::vec2 projHeight = windowSize.y;
proj = glm::ortho(-projWidth/2, projWidth/2, -projHeight/2, projHeight/2, -1.f, 1.f);
shaderProgram.SetMat4("view", view, 1);
shaderProgram.SetMat4("proj", proj, 1);
shaderProgram.SetMat4("world", world, 1); // world is identity matrix for now
glViewport(-windowSize.x/2, -windowSize.y/2, windowSize.x, windowSize.y);
Now i now do have some variables here that i use to try to implement paning with but i first want to get resizing to work correctly.
EDIT:
ok i have now tried different parameters for the viewport and orthographic projection matrix:
auto aspect = (float)(windowSize.x)/(float)windowSize.y;
glViewport(0, 0, windowSize.x, windowSize.y);
proj = glm::ortho<float>(-aspect, aspect, -1/aspect, 1/aspect, 1, -1);
Resizing the window still stretches my renderTexture, but now it does it uniformely, x is scaled as much as y. My square sprites remain sqares, but becomes smaller as i decrease the window size. GIF
I believe there were problems with my handling of FBOs as i have now found a satisfactory solution, one that also seems to be the obvious one. Simply using the width and height of the viewport (and FBO attached texture) like this:
proj = glm::ortho<float>(-zoom *viewportSize.x/(2) , zoom*viewportSize.x/(2) , -zoom*viewportSize.y/(2), zoom*viewportSize.y/(2), 1, -1);
You might also want to divide the four parameters by a constant (possibly much larger than 2) to make the zooming range more natural around 1.
While i tried this exact code before, I actually did not recreate the framebuffer, but simply used glTexImage2D(); on the attached texture. It seems as though one need to delete and recreate the whole Framebuffer, and this was also stated to be safer on some posts here on SO, but I never found any sources saying that it was actually required.
So, lesson learnt, delete and create a new framebuffer. Window resizing is not something that happens very often.