Hi,
it's the first time I make a post here for help I hope to give all the necessary info about my issue.
I'm building a game engine using SFML and I got stuck in a very "dumb" feature that I want for my cameras: when the window is resized I want the "view" to be fully fit inside the viewport. I will attach a clip of what a Unity game does (I want to replicate that, even if I prefer to use the resize event for now instead of constant checking like Unity).
As you can see, you can resize on both axis and maintaining the game's aspect ratio the engine zooms in or out to fit as wide as possible the viewport. I'm focusing on the down-sizing for now, my implementation works if I resize only width or only Y. but as soon as I first resize on one axis and then on the other the zoom starts being a little off, never really fitting correctly the view in the viewport.
This is the code I'm using, it's not relying on any engine specific feature (a part for being attached to my custom event), just SFML3.
m_engine->OnResize += [this](const sf::Vector2u& oldSize, const sf::Vector2u& newSize)
{
constexpr float targetAspectRatio = 16.f / 9.f; // testing on 1920x1080
float newAspectRatio = (float)newSize.x / (float)newSize.y;
auto oldViewSize = m_view->getSize(); //! this changes every time because of the zoom
m_view->setSize({ (float)newSize.x, (float)newSize.y });
float zoomX = oldViewSize.x / (float)newSize.x;
float zoomY = oldViewSize.y / (float)newSize.y;
float zoom = (newAspectRatio > targetAspectRatio) ? zoomY : zoomX;
m_view->zoom(zoom);
std::cout << zoomX << " " << zoomY << " " << zoom << std::endl;
};
*Edit
of course I make a post after 4 hours of banging my head against a wall and find my answer right after. I should have used the original width and height instead of oldViewSize (which, as stated in my own commend, changes with zoom..)
The following now works as intended:
m_engine->OnResize += [this](const sf::Vector2u& oldSize, const sf::Vector2u& newSize)
{
constexpr float targetAspectRatio = 16.f / 9.f; // testing on 1920x1080
constexpr float initialX = 1920.f, initialY = 1080.f;
float newAspectRatio = (float)newSize.x / (float)newSize.y;
m_view->setSize({ (float)newSize.x, (float)newSize.y });
float zoomX = initialX / (float)newSize.x;
float zoomY = initialY / (float)newSize.y;
float zoom = (newAspectRatio > targetAspectRatio) ? zoomY : zoomX;
m_view->zoom(zoom);
};