Rewrite getSplitscreenWindow to fully occupy the remaining pixels

It fixed render inconsistency when drawing lap
This commit is contained in:
Benau 2024-05-17 07:27:18 +00:00
parent 37e024f1e1
commit 14c002c7ca
2 changed files with 37 additions and 30 deletions

View File

@ -88,6 +88,8 @@
#include "utils/translation.hpp"
#include "utils/vs.hpp"
#include <algorithm>
#include <cmath>
#include <irrlicht.h>
#if !defined(SERVER_ONLY) && defined(ANDROID)
@ -322,38 +324,43 @@ void IrrDriver::updateConfigIfRelevant()
}
#endif // !SERVER_ONLY
} // updateConfigIfRelevant
core::recti IrrDriver::getSplitscreenWindow(int WindowNum)
// ----------------------------------------------------------------------------
core::recti IrrDriver::getSplitscreenWindow(int window_num)
{
const int playernum = RaceManager::get()->getNumLocalPlayers();
const float playernum_sqrt = sqrtf((float)playernum);
int rows = int( UserConfigParams::split_screen_horizontally
? ceil(playernum_sqrt)
: round(playernum_sqrt) );
int cols = int( UserConfigParams::split_screen_horizontally
? round(playernum_sqrt)
: ceil(playernum_sqrt) );
if (rows == 0){rows = 1;}
if (cols == 0) {cols = 1;}
//This could add a bit of overhang
const int width_of_space =
int(ceil( (float)irr_driver->getActualScreenSize().Width
/ (float)cols) );
const int height_of_space =
int (ceil( (float)irr_driver->getActualScreenSize().Height
/ (float)rows) );
// Determine the number of columns and rows needed
int total_players = RaceManager::get()->getNumLocalPlayers();
if (total_players < 1)
total_players = 1;
int columns = (int)(std::ceil(std::sqrt(total_players)));
int rows = (int)(std::ceil((double)(total_players) / columns));
if (UserConfigParams::split_screen_horizontally)
std::swap(columns, rows);
const int x_grid_Position = WindowNum % cols;
const int y_grid_Position = int(floor((WindowNum) / cols));
// Calculate the base dimensions of each viewport
int base_viewport_width = irr_driver->getActualScreenSize().Width / columns;
int base_viewport_height = irr_driver->getActualScreenSize().Height / rows;
// Calculate remaining pixels to distribute
int extra_width = irr_driver->getActualScreenSize().Width % columns;
int extra_height = irr_driver->getActualScreenSize().Height % rows;
// Determine the row and column for the given player index
int row = window_num / columns;
int col = window_num % columns;
// Calculate the top-left corner of the viewport
int viewport_x = col * base_viewport_width + std::min(col, extra_width);
int viewport_y = row * base_viewport_height + std::min(row, extra_height);
// Adjust width and height to fully occupy the remaining pixels
int viewport_width = base_viewport_width + (col < extra_width ? 1 : 0);
int viewport_height = base_viewport_height + (row < extra_height ? 1 : 0);
return core::recti(core::position2di(viewport_x, viewport_y),
core::dimension2du(viewport_width, viewport_height));
} // getSplitscreenWindow
//To prevent the viewport going over the right side, we use std::min to ensure the right corners are never larger than the total width
return core::recti(
x_grid_Position * width_of_space,
y_grid_Position * height_of_space,
(x_grid_Position * width_of_space) + width_of_space,
(y_grid_Position * height_of_space) + height_of_space);
}
// ----------------------------------------------------------------------------
/** Gets a list of supported video modes from the irrlicht device. This data
* is stored in m_modes.

View File

@ -214,7 +214,7 @@ public:
void increaseObjectCount();
core::array<video::IRenderTarget> &getMainSetup();
void updateConfigIfRelevant();
core::recti getSplitscreenWindow(int WindowNum);
core::recti getSplitscreenWindow(int window_num);
void setAllMaterialFlags(scene::IMesh *mesh) const;
scene::IAnimatedMesh *getAnimatedMesh(const std::string &name);
scene::IMesh *getMesh(const std::string &name);