I want to draw my rectangular game board in a resizable window. When the window's aspect ratio does not match there should be black margins at either top&bottom or left&right.
Right now I have margins on both sides (see screenshot). This is because I first set view on a square with a side equal to the board's larger dimension and then I set its viewport to account for window's aspect ratio. I think to achieve what I want the viewport should take board's dimensions into account as well, but I don't see how. Please help.
// -*- compile-command: "g++ board.cpp -o board -lsfml-graphics -lsfml-window -lsfml-system && ./board"; -*-
#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <SFML/Window.hpp>
int main()
{
const int BW = 40;
const int BH = 30;
sf::RenderWindow window(sf::VideoMode(960, 540), "Board drawing test");
window.setFramerateLimit(10);
const int MAX_DIMENSION = std::max(BW,BH);
sf::View view({-(MAX_DIMENSION-BW)/2, -(MAX_DIMENSION-BH)/2, MAX_DIMENSION, MAX_DIMENSION});
window.setView(view);
while (window.isOpen()) {
sf::Event event;
while (true) {
bool moreEvents = window.pollEvent(event);
switch (event.type) {
case sf::Event::Closed:
window.close();
break;
case sf::Event::Resized:
int ww = event.size.width;
int wh = event.size.height;
if (ww > wh) {
float aspect = (float)wh/ww;
float empty = 1.0f - aspect;
view.setViewport(sf::FloatRect(empty/2, 0.0f, aspect, 1.0));
} else {
float aspect = (float)ww/wh;
float empty = 1.0f - aspect;
view.setViewport(sf::FloatRect(0.0f, empty/2, 1.0, aspect));
}
window.setView(view);
break;
}
if (!moreEvents)
break;
}
window.clear();
// blue rectangle, filling the entire board
sf::RectangleShape shape(sf::Vector2f(BW, BH));
shape.setFillColor(sf::Color(0, 0, 255));
window.draw(shape);
// red square at the corner of the board
shape.setFillColor(sf::Color(255, 0, 0, 255));
shape.setPosition(BW-1, BH-1);
shape.setSize(sf::Vector2(1.0f, 1.0f));
window.draw(shape);
window.display();
}
return 0;
}