mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-17 22:55:38 +00:00
Added support for running the application at lower resolution in fullscreen padded mode.
Also added support for offsetting the screen contents within the application window.
This commit is contained in:
parent
047ab9111e
commit
5be55d38ed
|
@ -601,8 +601,8 @@ void Screensaver::generateOverlayInfo()
|
|||
if (mGameName == "" || mSystemName == "")
|
||||
return;
|
||||
|
||||
float posX {mRenderer->getWindowWidth() * 0.023f};
|
||||
float posY {mRenderer->getWindowHeight() * 0.02f};
|
||||
float posX {mRenderer->getScreenWidth() * 0.023f};
|
||||
float posY {mRenderer->getScreenHeight() * 0.02f};
|
||||
|
||||
std::string favoriteChar;
|
||||
if (mCurrentGame && mCurrentGame->getFavorite())
|
||||
|
@ -629,7 +629,7 @@ void Screensaver::generateOverlayInfo()
|
|||
else
|
||||
textSizeX = mGameOverlayFont[0].get()->sizeText(systemName).x;
|
||||
|
||||
float marginX {mRenderer->getWindowWidth() * 0.01f};
|
||||
float marginX {mRenderer->getScreenWidth() * 0.01f};
|
||||
|
||||
mGameOverlayRectangleCoords.clear();
|
||||
mGameOverlayRectangleCoords.push_back(posX - marginX);
|
||||
|
|
|
@ -266,17 +266,6 @@ bool parseArgs(int argc, char* argv[])
|
|||
<< " supplied\n";
|
||||
return false;
|
||||
}
|
||||
Settings::getInstance()->setInt("WindowWidth", width);
|
||||
Settings::getInstance()->setInt("WindowHeight", height);
|
||||
i += 2;
|
||||
}
|
||||
else if (strcmp(argv[i], "--screensize") == 0) {
|
||||
if (i >= argc - 2) {
|
||||
std::cerr << "Error: Invalid screensize values supplied\n";
|
||||
return false;
|
||||
}
|
||||
int width {atoi(argv[i + 1])};
|
||||
int height {atoi(argv[i + 2])};
|
||||
Settings::getInstance()->setInt("ScreenWidth", width);
|
||||
Settings::getInstance()->setInt("ScreenHeight", height);
|
||||
i += 2;
|
||||
|
@ -307,18 +296,34 @@ bool parseArgs(int argc, char* argv[])
|
|||
settingsNeedSaving = true;
|
||||
++i;
|
||||
}
|
||||
else if (strcmp(argv[i], "--fullscreen-padding") == 0) {
|
||||
if (i >= argc - 1) {
|
||||
std::cerr << "Error: No fullscreen-padding value supplied\n";
|
||||
return false;
|
||||
}
|
||||
std::string fullscreenPaddingValue {argv[i + 1]};
|
||||
if (fullscreenPaddingValue != "on" && fullscreenPaddingValue != "off" &&
|
||||
fullscreenPaddingValue != "1" && fullscreenPaddingValue != "0") {
|
||||
std::cerr << "Error: Invalid fullscreen-padding value supplied\n";
|
||||
return false;
|
||||
}
|
||||
const bool fullscreenPadding {
|
||||
(fullscreenPaddingValue == "on" || fullscreenPaddingValue == "1") ? true : false};
|
||||
Settings::getInstance()->setBool("FullscreenPadding", fullscreenPadding);
|
||||
++i;
|
||||
}
|
||||
else if (strcmp(argv[i], "--vsync") == 0) {
|
||||
if (i >= argc - 1) {
|
||||
std::cerr << "Error: No VSync value supplied\n";
|
||||
return false;
|
||||
}
|
||||
std::string vSyncValue = argv[i + 1];
|
||||
std::string vSyncValue {argv[i + 1]};
|
||||
if (vSyncValue != "on" && vSyncValue != "off" && vSyncValue != "1" &&
|
||||
vSyncValue != "0") {
|
||||
std::cerr << "Error: Invalid VSync value supplied\n";
|
||||
return false;
|
||||
}
|
||||
bool vSync {(vSyncValue == "on" || vSyncValue == "1") ? true : false};
|
||||
const bool vSync {(vSyncValue == "on" || vSyncValue == "1") ? true : false};
|
||||
Settings::getInstance()->setBool("VSync", vSync);
|
||||
++i;
|
||||
}
|
||||
|
@ -327,7 +332,7 @@ bool parseArgs(int argc, char* argv[])
|
|||
std::cerr << "Error: Invalid VRAM value supplied\n";
|
||||
return false;
|
||||
}
|
||||
int maxVRAM {atoi(argv[i + 1])};
|
||||
const int maxVRAM {atoi(argv[i + 1])};
|
||||
Settings::getInstance()->setInt("MaxVRAM", maxVRAM);
|
||||
settingsNeedSaving = true;
|
||||
++i;
|
||||
|
@ -403,7 +408,9 @@ bool parseArgs(int argc, char* argv[])
|
|||
"Options:\n"
|
||||
" --display [1 to 4] Display/monitor to use\n"
|
||||
" --resolution [width] [height] Application resolution\n"
|
||||
" --screenoffset [horiz.] [vert.] Offset screen contents within application window\n"
|
||||
" --screenrotate [0, 90, 180 or 270] Rotate screen contents within application window\n"
|
||||
" --fullscreen-padding [1/on or 0/off] Padding if --resolution is lower than display resolution\n"
|
||||
" --vsync [1/on or 0/off] Turn VSync on or off (default is on)\n"
|
||||
" --max-vram [size] Max VRAM to use (in mebibytes) before swapping\n"
|
||||
#if !defined(USE_OPENGLES)
|
||||
|
@ -411,7 +418,7 @@ bool parseArgs(int argc, char* argv[])
|
|||
#endif
|
||||
" --no-splash Don't show the splash screen during startup\n"
|
||||
" --gamelist-only Skip automatic game ROM search, only read from gamelist.xml\n"
|
||||
" --ignore-gamelist Ignore the gamelist.xml files (useful for troubleshooting)\n"
|
||||
" --ignore-gamelist Ignore the gamelist.xml files\n"
|
||||
" --show-hidden-files Show hidden files and folders\n"
|
||||
" --show-hidden-games Show hidden games\n"
|
||||
" --force-full Force the UI mode to Full\n"
|
||||
|
@ -601,8 +608,8 @@ int main(int argc, char* argv[])
|
|||
// TODO: Remove when application window resizing has been implemented.
|
||||
Settings::getInstance()->setBool("Debug", true);
|
||||
Log::setReportingLevel(LogDebug);
|
||||
Settings::getInstance()->setInt("WindowWidth", 1280);
|
||||
Settings::getInstance()->setInt("WindowHeight", 720);
|
||||
Settings::getInstance()->setInt("ScreenWidth", 1280);
|
||||
Settings::getInstance()->setInt("ScreenHeight", 720);
|
||||
#endif
|
||||
|
||||
// Check if the configuration file exists, and if not, create it.
|
||||
|
@ -613,7 +620,7 @@ int main(int argc, char* argv[])
|
|||
Settings::getInstance()->saveFile();
|
||||
}
|
||||
else if (settingsNeedSaving) {
|
||||
LOG(LogInfo) << "Saving settings that were modified by the passed command line options...";
|
||||
LOG(LogInfo) << "Saving settings that were modified by command line options...";
|
||||
Settings::getInstance()->saveFile();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,22 +26,18 @@ namespace
|
|||
std::vector<std::string> settingsSkipSaving {
|
||||
// clang-format off
|
||||
// These options can be set using command-line arguments:
|
||||
"WindowWidth", // Set via --resolution [width] [height]
|
||||
"WindowHeight", // set via --resolution [width] [height]
|
||||
"ScreenWidth", // Set via --resolution [width] [height]
|
||||
"ScreenHeight", // set via --resolution [width] [height]
|
||||
"ScreenOffsetX", // Set via --screenoffset [horiz.] [vert.]
|
||||
"ScreenOffsetY", // Set via --screenoffset [horiz.] [vert.]
|
||||
"FullscreenPadding", // Set via --fullscreen-padding [1/on or 0/off]
|
||||
"VSync", // --vsync [1/on or 0/off]
|
||||
"IgnoreGamelist", // --ignore-gamelist
|
||||
"SplashScreen", // --no-splash
|
||||
"Debug", // --debug
|
||||
"VSync", // --vsync [1/on or 0/off]
|
||||
"ForceFull", // --force-full
|
||||
"ForceKiosk", // --force-kiosk
|
||||
"ForceKid", // --force-kid
|
||||
|
||||
// These command-line argument options are not shown in the --help text and are intended
|
||||
// for debugging and testing purposes:
|
||||
"ScreenWidth", // Set via --screensize [width] [height]
|
||||
"ScreenHeight", // set via --screensize [width] [height]
|
||||
"ScreenOffsetX", // Set via --screenoffset [X] [Y]
|
||||
"ScreenOffsetY", // Set via --screenoffset [X] [Y]
|
||||
"Debug", // --debug
|
||||
|
||||
// These options are only used internally during the application session:
|
||||
"DebugGrid",
|
||||
|
@ -137,7 +133,7 @@ void Settings::setDefaults()
|
|||
|
||||
mStringMap["ScraperRegion"] = {"eu", "eu"};
|
||||
mStringMap["ScraperLanguage"] = {"en", "en"};
|
||||
mIntMap["ScraperRetryOnErrorCount"] = {3, 3};
|
||||
mIntMap["ScraperRetryOnErrorCount"] = {5, 5};
|
||||
mIntMap["ScraperRetryOnErrorTimer"] = {3, 3};
|
||||
mBoolMap["ScraperOverwriteData"] = {true, true};
|
||||
mBoolMap["ScraperHaltOnInvalidMedia"] = {true, true};
|
||||
|
@ -297,11 +293,8 @@ void Settings::setDefaults()
|
|||
mBoolMap["IgnoreGamelist"] = {false, false};
|
||||
mBoolMap["SplashScreen"] = {true, true};
|
||||
mBoolMap["VSync"] = {true, true};
|
||||
mIntMap["WindowWidth"] = {0, 0};
|
||||
mIntMap["WindowHeight"] = {0, 0};
|
||||
mBoolMap["FullscreenPadding"] = {false, false};
|
||||
mIntMap["ScreenWidth"] = {0, 0};
|
||||
|
||||
// Undocumented options.
|
||||
mIntMap["ScreenHeight"] = {0, 0};
|
||||
mIntMap["ScreenOffsetX"] = {0, 0};
|
||||
mIntMap["ScreenOffsetY"] = {0, 0};
|
||||
|
|
|
@ -101,26 +101,50 @@ bool Renderer::createWindow()
|
|||
displayMode.h = displayBounds.h;
|
||||
#endif
|
||||
|
||||
mWindowWidth = Settings::getInstance()->getInt("WindowWidth") ?
|
||||
Settings::getInstance()->getInt("WindowWidth") :
|
||||
displayMode.w;
|
||||
mWindowHeight = Settings::getInstance()->getInt("WindowHeight") ?
|
||||
Settings::getInstance()->getInt("WindowHeight") :
|
||||
displayMode.h;
|
||||
sScreenWidth = Settings::getInstance()->getInt("ScreenWidth") ?
|
||||
Settings::getInstance()->getInt("ScreenWidth") :
|
||||
mWindowWidth;
|
||||
displayMode.w;
|
||||
sScreenHeight = Settings::getInstance()->getInt("ScreenHeight") ?
|
||||
Settings::getInstance()->getInt("ScreenHeight") :
|
||||
mWindowHeight;
|
||||
mScreenOffsetX = Settings::getInstance()->getInt("ScreenOffsetX") ?
|
||||
displayMode.h;
|
||||
mScreenOffsetX = glm::clamp((Settings::getInstance()->getInt("ScreenOffsetX") ?
|
||||
Settings::getInstance()->getInt("ScreenOffsetX") :
|
||||
0;
|
||||
mScreenOffsetY = Settings::getInstance()->getInt("ScreenOffsetY") ?
|
||||
0),
|
||||
-(displayMode.w / 2), displayMode.w / 2);
|
||||
mScreenOffsetY = glm::clamp((Settings::getInstance()->getInt("ScreenOffsetY") ?
|
||||
Settings::getInstance()->getInt("ScreenOffsetY") :
|
||||
0;
|
||||
0),
|
||||
-(displayMode.w / 2), displayMode.h / 2);
|
||||
mScreenRotation = Settings::getInstance()->getInt("ScreenRotate");
|
||||
|
||||
if (mScreenOffsetX != 0 || mScreenOffsetY != 0) {
|
||||
LOG(LogInfo) << "Screen offset: " << mScreenOffsetX << " horizontal, " << mScreenOffsetY
|
||||
<< " vertical";
|
||||
}
|
||||
else {
|
||||
LOG(LogInfo) << "Screen offset: disabled";
|
||||
}
|
||||
|
||||
mPaddingWidth = 0;
|
||||
mPaddingHeight = 0;
|
||||
bool fullscreenPadding {false};
|
||||
|
||||
if (Settings::getInstance()->getBool("FullscreenPadding") && sScreenWidth <= displayMode.w &&
|
||||
sScreenHeight <= displayMode.h) {
|
||||
mWindowWidth = displayMode.w;
|
||||
mWindowHeight = displayMode.h;
|
||||
mPaddingWidth = displayMode.w - sScreenWidth;
|
||||
mPaddingHeight = displayMode.h - sScreenHeight;
|
||||
mScreenOffsetX -= mPaddingWidth / 2.0f;
|
||||
mScreenOffsetY -= mPaddingHeight / 2.0f;
|
||||
fullscreenPadding = true;
|
||||
}
|
||||
|
||||
if (!fullscreenPadding) {
|
||||
mWindowWidth = sScreenWidth;
|
||||
mWindowHeight = sScreenHeight;
|
||||
}
|
||||
|
||||
// In case someone manually added an invalid value to es_settings.xml.
|
||||
if (mScreenRotation != 0 && mScreenRotation != 90 && mScreenRotation != 180 &&
|
||||
mScreenRotation != 270) {
|
||||
|
@ -158,7 +182,7 @@ bool Renderer::createWindow()
|
|||
SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
|
||||
#endif
|
||||
|
||||
bool userResolution = false;
|
||||
bool userResolution {false};
|
||||
// Check if the user has changed the resolution from the command line.
|
||||
if (mWindowWidth != displayMode.w || mWindowHeight != displayMode.h)
|
||||
userResolution = true;
|
||||
|
@ -219,17 +243,17 @@ bool Renderer::createWindow()
|
|||
// display so that the full application window is used for rendering.
|
||||
int width {0};
|
||||
SDL_GL_GetDrawableSize(mSDLWindow, &width, nullptr);
|
||||
int scaleFactor = static_cast<int>(width / mWindowWidth);
|
||||
int scaleFactor {static_cast<int>(width / sScreenWidth)};
|
||||
|
||||
LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x"
|
||||
<< std::to_string(displayMode.h) << " (physical resolution "
|
||||
<< std::to_string(displayMode.w * scaleFactor) << "x"
|
||||
<< std::to_string(displayMode.h * scaleFactor) << ")";
|
||||
LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate) << " Hz";
|
||||
LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(mWindowWidth) << "x"
|
||||
<< std::to_string(mWindowHeight) << " (physical resolution "
|
||||
<< std::to_string(mWindowWidth * scaleFactor) << "x"
|
||||
<< std::to_string(mWindowHeight * scaleFactor) << ")";
|
||||
LOG(LogInfo) << "Application resolution: " << std::to_string(sScreenWidth) << "x"
|
||||
<< std::to_string(sScreenHeight) << " (physical resolution "
|
||||
<< std::to_string(sScreenWidth * scaleFactor) << "x"
|
||||
<< std::to_string(sScreenHeight * scaleFactor) << ")";
|
||||
|
||||
mWindowWidth *= scaleFactor;
|
||||
mWindowHeight *= scaleFactor;
|
||||
|
@ -239,8 +263,8 @@ bool Renderer::createWindow()
|
|||
LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x"
|
||||
<< std::to_string(displayMode.h);
|
||||
LOG(LogInfo) << "Display refresh rate: " << std::to_string(displayMode.refresh_rate) << " Hz";
|
||||
LOG(LogInfo) << "EmulationStation resolution: " << std::to_string(mWindowWidth) << "x"
|
||||
<< std::to_string(mWindowHeight);
|
||||
LOG(LogInfo) << "Application resolution: " << std::to_string(sScreenWidth) << "x"
|
||||
<< std::to_string(sScreenHeight);
|
||||
#endif
|
||||
|
||||
sScreenHeightModifier = static_cast<float>(sScreenHeight) / 1080.0f;
|
||||
|
@ -252,6 +276,23 @@ bool Renderer::createWindow()
|
|||
else
|
||||
sScreenResolutionModifier = sScreenHeight / 1080.0f;
|
||||
|
||||
if (Settings::getInstance()->getBool("FullscreenPadding")) {
|
||||
if (!fullscreenPadding) {
|
||||
LOG(LogWarning) << "Fullscreen padding can't be applied when --resolution is set "
|
||||
"higher than the display resolution";
|
||||
LOG(LogInfo) << "Screen mode: windowed";
|
||||
}
|
||||
else {
|
||||
LOG(LogInfo) << "Screen mode: fullscreen padding";
|
||||
}
|
||||
}
|
||||
else if (userResolution) {
|
||||
LOG(LogInfo) << "Screen mode: windowed";
|
||||
}
|
||||
else {
|
||||
LOG(LogInfo) << "Screen mode: fullscreen";
|
||||
}
|
||||
|
||||
LOG(LogInfo) << "Setting up OpenGL...";
|
||||
|
||||
if (!createContext())
|
||||
|
@ -287,27 +328,30 @@ bool Renderer::init()
|
|||
return false;
|
||||
|
||||
glm::mat4 projection {getIdentity()};
|
||||
Rect viewport {0, 0, 0, 0};
|
||||
|
||||
viewport.x = mWindowWidth - mScreenOffsetX - sScreenWidth;
|
||||
viewport.y = mWindowHeight - mScreenOffsetY - sScreenHeight;
|
||||
viewport.w = sScreenWidth;
|
||||
viewport.h = sScreenHeight;
|
||||
|
||||
projection = glm::ortho(0.0f, static_cast<float>(sScreenHeight),
|
||||
static_cast<float>(sScreenWidth), 0.0f, -1.0f, 1.0f);
|
||||
|
||||
if (mScreenRotation == 0) {
|
||||
mViewport.x = mWindowWidth + mScreenOffsetX - sScreenWidth;
|
||||
mViewport.y = mWindowHeight + mScreenOffsetY - sScreenHeight;
|
||||
mViewport.w = sScreenWidth;
|
||||
mViewport.h = sScreenHeight;
|
||||
mProjectionMatrix = glm::ortho(0.0f, static_cast<float>(sScreenWidth),
|
||||
static_cast<float>(sScreenHeight), 0.0f, -1.0f, 1.0f);
|
||||
}
|
||||
else if (mScreenRotation == 90) {
|
||||
mViewport.x = mWindowWidth + mScreenOffsetX - sScreenHeight;
|
||||
mViewport.y = mWindowHeight + mScreenOffsetY - sScreenWidth;
|
||||
mViewport.w = sScreenHeight;
|
||||
mViewport.h = sScreenWidth;
|
||||
projection = glm::ortho(0.0f, static_cast<float>(sScreenHeight),
|
||||
static_cast<float>(sScreenWidth), 0.0f, -1.0f, 1.0f);
|
||||
projection = glm::rotate(projection, glm::radians(90.0f), {0.0f, 0.0f, 1.0f});
|
||||
mProjectionMatrix = glm::translate(projection, {0.0f, sScreenHeight * -1.0f, 0.0f});
|
||||
}
|
||||
else if (mScreenRotation == 180) {
|
||||
mViewport.x = mWindowWidth + mScreenOffsetX - sScreenWidth;
|
||||
mViewport.y = mWindowHeight + mScreenOffsetY - sScreenHeight;
|
||||
mViewport.w = sScreenWidth;
|
||||
mViewport.h = sScreenHeight;
|
||||
projection = glm::ortho(0.0f, static_cast<float>(sScreenWidth),
|
||||
static_cast<float>(sScreenHeight), 0.0f, -1.0f, 1.0f);
|
||||
projection = glm::rotate(projection, glm::radians(180.0f), {0.0f, 0.0f, 1.0f});
|
||||
|
@ -315,6 +359,10 @@ bool Renderer::init()
|
|||
glm::translate(projection, {sScreenWidth * -1.0f, sScreenHeight * -1.0f, 0.0f});
|
||||
}
|
||||
else if (mScreenRotation == 270) {
|
||||
mViewport.x = mWindowWidth + mScreenOffsetX - sScreenHeight;
|
||||
mViewport.y = mWindowHeight + mScreenOffsetY - sScreenWidth;
|
||||
mViewport.w = sScreenHeight;
|
||||
mViewport.h = sScreenWidth;
|
||||
projection = glm::ortho(0.0f, static_cast<float>(sScreenHeight),
|
||||
static_cast<float>(sScreenWidth), 0.0f, -1.0f, 1.0f);
|
||||
projection = glm::rotate(projection, glm::radians(270.0f), {0.0f, 0.0f, 1.0f});
|
||||
|
@ -323,11 +371,7 @@ bool Renderer::init()
|
|||
|
||||
mProjectionMatrixNormal = glm::ortho(0.0f, static_cast<float>(sScreenWidth),
|
||||
static_cast<float>(sScreenHeight), 0.0f, -1.0f, 1.0f);
|
||||
|
||||
viewport.x = mScreenOffsetX;
|
||||
viewport.y = mScreenOffsetY;
|
||||
viewport.w = sScreenWidth;
|
||||
viewport.h = sScreenHeight;
|
||||
setViewport(mViewport);
|
||||
|
||||
// This is required to avoid a brief white screen flash during startup on some systems.
|
||||
drawRect(0.0f, 0.0f, static_cast<float>(getScreenWidth()),
|
||||
|
@ -353,19 +397,20 @@ void Renderer::pushClipRect(const glm::ivec2& pos, const glm::ivec2& size)
|
|||
box.h = sScreenHeight - box.y;
|
||||
|
||||
if (mScreenRotation == 0) {
|
||||
box = {mScreenOffsetX + box.x, mScreenOffsetY + box.y, box.w, box.h};
|
||||
box = {mScreenOffsetX + box.x + mPaddingWidth, mScreenOffsetY + box.y + mPaddingHeight,
|
||||
box.w, box.h};
|
||||
}
|
||||
else if (mScreenRotation == 90) {
|
||||
box = {mScreenOffsetX + mWindowWidth - (box.y + box.h), mScreenOffsetY + box.x, box.h,
|
||||
box.w};
|
||||
box.w + mPaddingHeight};
|
||||
}
|
||||
else if (mScreenRotation == 270) {
|
||||
box = {mScreenOffsetX + box.y, mScreenOffsetY + mWindowHeight - (box.x + box.w), box.h,
|
||||
box.w};
|
||||
box = {mScreenOffsetX + box.y + mPaddingWidth,
|
||||
mScreenOffsetY + mWindowHeight - (box.x + box.w), box.h, box.w};
|
||||
}
|
||||
else if (mScreenRotation == 180) {
|
||||
box = {mWindowWidth - mScreenOffsetX - box.x - box.w,
|
||||
mWindowHeight - mScreenOffsetY - box.y - box.h, box.w, box.h};
|
||||
box = {mWindowWidth + mScreenOffsetX - box.x - box.w,
|
||||
mWindowHeight + mScreenOffsetY - box.y - box.h, box.w, box.h};
|
||||
}
|
||||
|
||||
// Make sure the box fits within mClipStack.top(), and clip further accordingly.
|
||||
|
@ -400,7 +445,7 @@ void Renderer::popClipRect()
|
|||
mClipStack.pop();
|
||||
|
||||
if (mClipStack.empty())
|
||||
setScissor(Rect {0, 0, 0, 0});
|
||||
setScissor(Rect());
|
||||
else
|
||||
setScissor(mClipStack.top());
|
||||
}
|
||||
|
|
|
@ -118,6 +118,19 @@ public:
|
|||
};
|
||||
|
||||
struct Rect {
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
Rect()
|
||||
: x(0)
|
||||
, y(0)
|
||||
, w(0)
|
||||
, h(0)
|
||||
{
|
||||
}
|
||||
|
||||
Rect(const int xValue, const int yValue, const int wValue, const int hValue)
|
||||
: x(xValue)
|
||||
, y(yValue)
|
||||
|
@ -125,10 +138,6 @@ public:
|
|||
, h(hValue)
|
||||
{
|
||||
}
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
};
|
||||
|
||||
static Renderer* getInstance();
|
||||
|
@ -160,8 +169,6 @@ public:
|
|||
const glm::mat4& getProjectionMatrixNormal() { return mProjectionMatrixNormal; }
|
||||
SDL_Window* getSDLWindow() { return mSDLWindow; }
|
||||
const int getScreenRotation() { return mScreenRotation; }
|
||||
const float getWindowWidth() { return static_cast<float>(mWindowWidth); }
|
||||
const float getWindowHeight() { return static_cast<float>(mWindowHeight); }
|
||||
static const bool getIsVerticalOrientation() { return sIsVerticalOrientation; }
|
||||
static const float getScreenWidth() { return static_cast<float>(sScreenWidth); }
|
||||
static const float getScreenHeight() { return static_cast<float>(sScreenHeight); }
|
||||
|
@ -204,21 +211,28 @@ public:
|
|||
const BlendFactor srcBlendFactor = BlendFactor::ONE,
|
||||
const BlendFactor dstBlendFactor = BlendFactor::ONE_MINUS_SRC_ALPHA) = 0;
|
||||
virtual void setMatrix(const glm::mat4& matrix) = 0;
|
||||
virtual void setViewport(const Rect& viewport) = 0;
|
||||
virtual void setScissor(const Rect& scissor) = 0;
|
||||
virtual void setSwapInterval() = 0;
|
||||
virtual void swapBuffers() = 0;
|
||||
|
||||
protected:
|
||||
Rect mViewport;
|
||||
int mWindowWidth {0};
|
||||
int mWindowHeight {0};
|
||||
int mPaddingWidth {0};
|
||||
int mPaddingHeight {0};
|
||||
int mScreenOffsetX {0};
|
||||
int mScreenOffsetY {0};
|
||||
|
||||
private:
|
||||
std::stack<Rect> mClipStack;
|
||||
SDL_Window* mSDLWindow {nullptr};
|
||||
glm::mat4 mProjectionMatrix {};
|
||||
glm::mat4 mProjectionMatrixNormal {};
|
||||
int mWindowWidth {0};
|
||||
int mWindowHeight {0};
|
||||
|
||||
static inline int sScreenWidth {0};
|
||||
static inline int sScreenHeight {0};
|
||||
int mScreenOffsetX {0};
|
||||
int mScreenOffsetY {0};
|
||||
int mScreenRotation {0};
|
||||
bool mInitialCursorState {true};
|
||||
static inline bool sIsVerticalOrientation {false};
|
||||
|
|
|
@ -228,15 +228,13 @@ bool RendererOpenGL::createContext()
|
|||
LOG(LogInfo) << "GL renderer: " << renderer;
|
||||
LOG(LogInfo) << "GL version: " << version;
|
||||
#if defined(USE_OPENGLES)
|
||||
LOG(LogInfo) << "EmulationStation renderer: OpenGL ES " << mMajorGLVersion << "."
|
||||
<< mMinorGLVersion;
|
||||
LOG(LogInfo) << "Application renderer: OpenGL ES " << mMajorGLVersion << "." << mMinorGLVersion;
|
||||
#else
|
||||
#if defined(_WIN64)
|
||||
LOG(LogInfo) << "EmulationStation renderer: OpenGL " << mMajorGLVersion << "."
|
||||
<< mMinorGLVersion << " with GLEW";
|
||||
LOG(LogInfo) << "Application renderer: OpenGL " << mMajorGLVersion << "." << mMinorGLVersion
|
||||
<< " with GLEW";
|
||||
#else
|
||||
LOG(LogInfo) << "EmulationStation renderer: OpenGL " << mMajorGLVersion << "."
|
||||
<< mMinorGLVersion;
|
||||
LOG(LogInfo) << "Application renderer: OpenGL " << mMajorGLVersion << "." << mMinorGLVersion;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -326,6 +324,13 @@ void RendererOpenGL::setMatrix(const glm::mat4& matrix)
|
|||
mTrans = getProjectionMatrix() * matrix;
|
||||
}
|
||||
|
||||
void RendererOpenGL::setViewport(const Rect& viewport)
|
||||
{
|
||||
// glViewport starts at the bottom left of the window.
|
||||
GL_CHECK_ERROR(
|
||||
glViewport(viewport.x, mWindowHeight - viewport.y - viewport.h, viewport.w, viewport.h));
|
||||
}
|
||||
|
||||
void RendererOpenGL::setScissor(const Rect& scissor)
|
||||
{
|
||||
if ((scissor.x == 0) && (scissor.y == 0) && (scissor.w == 0) && (scissor.h == 0)) {
|
||||
|
@ -334,7 +339,7 @@ void RendererOpenGL::setScissor(const Rect& scissor)
|
|||
else {
|
||||
// glScissor starts at the bottom left of the window.
|
||||
GL_CHECK_ERROR(glScissor(scissor.x,
|
||||
static_cast<GLint>(getWindowHeight()) - scissor.y - scissor.h,
|
||||
static_cast<GLint>(mWindowHeight) - scissor.y - scissor.h,
|
||||
scissor.w, scissor.h));
|
||||
GL_CHECK_ERROR(glEnable(GL_SCISSOR_TEST));
|
||||
}
|
||||
|
@ -579,6 +584,15 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
|
|||
GLuint width {static_cast<GLuint>(widthf)};
|
||||
GLuint height {static_cast<GLuint>(heightf)};
|
||||
const int screenRotation {getScreenRotation()};
|
||||
const bool offsetOrPadding {mScreenOffsetX != 0 || mScreenOffsetY != 0 || mPaddingWidth != 0 ||
|
||||
mPaddingHeight != 0};
|
||||
|
||||
if (offsetOrPadding) {
|
||||
Rect viewportTemp {mViewport};
|
||||
viewportTemp.x -= mScreenOffsetX + mPaddingWidth;
|
||||
viewportTemp.y -= mScreenOffsetY;
|
||||
setViewport(viewportTemp);
|
||||
}
|
||||
|
||||
// Set vertex positions and texture coordinates to full screen as all
|
||||
// post-processing is applied to the complete screen area.
|
||||
|
@ -628,15 +642,20 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
|
|||
|
||||
// Blit the screen contents to mPostProcTexture.
|
||||
if (screenRotation == 0) {
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(
|
||||
0, 0, width + mPaddingWidth, height - mScreenOffsetY, -mScreenOffsetX - mPaddingWidth,
|
||||
mScreenOffsetY, width - mScreenOffsetX, height, GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
}
|
||||
else if (screenRotation == 90 || screenRotation == 270) {
|
||||
if (!evenBlurPasses || !textureRGBA)
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, height, width, 0, 0, height, width,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, height + mPaddingWidth, width - mScreenOffsetY,
|
||||
-mScreenOffsetX - mPaddingWidth, mScreenOffsetY,
|
||||
height - mScreenOffsetX, width, GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST));
|
||||
else
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, height, width, height, width, 0, 0,
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, height + mPaddingWidth, width - mScreenOffsetY,
|
||||
height + mScreenOffsetX + mPaddingWidth,
|
||||
width - mScreenOffsetY, mScreenOffsetX, 0,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
// If not rendering to a texture, apply shaders without any rotation applied.
|
||||
if (!textureRGBA)
|
||||
|
@ -644,11 +663,15 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
|
|||
}
|
||||
else {
|
||||
if ((shaderCalls + (textureRGBA ? 1 : 0)) % 2 == 0)
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width + mPaddingWidth, height - mScreenOffsetY,
|
||||
-mScreenOffsetX - mPaddingWidth, mScreenOffsetY,
|
||||
width - mScreenOffsetX, height, GL_COLOR_BUFFER_BIT,
|
||||
GL_NEAREST));
|
||||
else
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(0, 0, width, height, width, height, 0, 0,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
GL_CHECK_ERROR(glBlitFramebuffer(
|
||||
0, 0, width + mPaddingWidth, height + (mPaddingHeight / 2),
|
||||
width + mScreenOffsetX + mPaddingWidth, height - mScreenOffsetY, mScreenOffsetX,
|
||||
-(mPaddingHeight / 2) - mScreenOffsetY, GL_COLOR_BUFFER_BIT, GL_NEAREST));
|
||||
}
|
||||
|
||||
if (shaderCalls > 1)
|
||||
|
@ -669,6 +692,8 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
|
|||
for (int p {0}; p < shaderPasses; ++p) {
|
||||
if (!textureRGBA && i == shaderList.size() - 1 && p == shaderPasses - 1) {
|
||||
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
|
||||
if (offsetOrPadding)
|
||||
setViewport(mViewport);
|
||||
drawTriangleStrips(vertices, 4, BlendFactor::SRC_ALPHA,
|
||||
BlendFactor::ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
|
@ -723,4 +748,7 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
|
|||
}
|
||||
|
||||
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
|
||||
|
||||
if (offsetOrPadding)
|
||||
setViewport(mViewport);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
void destroyContext() override;
|
||||
|
||||
void setMatrix(const glm::mat4& matrix) override;
|
||||
void setViewport(const Rect& viewport) override;
|
||||
void setScissor(const Rect& scissor) override;
|
||||
void setSwapInterval() override;
|
||||
void swapBuffers() override;
|
||||
|
|
Loading…
Reference in a new issue