Added support for 2x and 4x MSAA anti-aliasing (OpenGL renderer only).

This commit is contained in:
Leon Styhre 2023-01-09 17:55:54 +01:00
parent 3020ed69bc
commit 6d3d2ddb34
4 changed files with 90 additions and 11 deletions

View file

@ -1224,6 +1224,30 @@ void GuiMenu::openOtherOptions()
} }
}); });
#if !defined(USE_OPENGLES)
// Anti-aliasing (MSAA).
auto antiAliasing = std::make_shared<OptionListComponent<std::string>>(
getHelpStyle(), "ANTI-ALIASING (MSAA)", false);
const std::string& selectedAntiAliasing {
std::to_string(Settings::getInstance()->getInt("AntiAliasing"))};
antiAliasing->add("DISABLED", "0", selectedAntiAliasing == "0");
antiAliasing->add("2X", "2", selectedAntiAliasing == "2");
antiAliasing->add("4X", "4", selectedAntiAliasing == "4");
// If there are no objects returned, then there must be a manually modified entry in the
// configuration file. Simply set anti-aliasing to "0" in this case.
if (antiAliasing->getSelectedObjects().size() == 0)
antiAliasing->selectEntry(0);
s->addWithLabel("ANTI-ALIASING (MSAA) (REQUIRES RESTART)", antiAliasing);
s->addSaveFunc([this, antiAliasing, s] {
if (antiAliasing->getSelected() !=
std::to_string(Settings::getInstance()->getInt("AntiAliasing"))) {
Settings::getInstance()->setInt("AntiAliasing",
atoi(antiAliasing->getSelected().c_str()));
s->setNeedsSaving();
}
});
#endif
// Display/monitor. // Display/monitor.
auto displayIndex = std::make_shared<OptionListComponent<std::string>>( auto displayIndex = std::make_shared<OptionListComponent<std::string>>(
getHelpStyle(), "DISPLAY/MONITOR INDEX", false); getHelpStyle(), "DISPLAY/MONITOR INDEX", false);

View file

@ -238,7 +238,7 @@ bool parseArgs(int argc, char* argv[])
} }
if (strcmp(argv[i], "--display") == 0) { if (strcmp(argv[i], "--display") == 0) {
if (i >= argc - 1 || atoi(argv[i + 1]) < 1 || atoi(argv[i + 1]) > 4) { if (i >= argc - 1 || atoi(argv[i + 1]) < 1 || atoi(argv[i + 1]) > 4) {
std::cerr << "Error: Invalid display index supplied.\n"; std::cerr << "Error: Invalid display index supplied\n";
return false; return false;
} }
int DisplayIndex {atoi(argv[i + 1])}; int DisplayIndex {atoi(argv[i + 1])};
@ -248,14 +248,14 @@ bool parseArgs(int argc, char* argv[])
} }
else if (strcmp(argv[i], "--resolution") == 0) { else if (strcmp(argv[i], "--resolution") == 0) {
if (i >= argc - 2) { if (i >= argc - 2) {
std::cerr << "Error: Invalid resolution values supplied.\n"; std::cerr << "Error: Invalid resolution values supplied\n";
return false; return false;
} }
std::string widthArg {argv[i + 1]}; std::string widthArg {argv[i + 1]};
std::string heightArg {argv[i + 2]}; std::string heightArg {argv[i + 2]};
if (widthArg.find_first_not_of("0123456789") != std::string::npos || if (widthArg.find_first_not_of("0123456789") != std::string::npos ||
heightArg.find_first_not_of("0123456789") != std::string::npos) { heightArg.find_first_not_of("0123456789") != std::string::npos) {
std::cerr << "Error: Invalid resolution values supplied.\n"; std::cerr << "Error: Invalid resolution values supplied\n";
return false; return false;
} }
int width {atoi(argv[i + 1])}; int width {atoi(argv[i + 1])};
@ -263,7 +263,7 @@ bool parseArgs(int argc, char* argv[])
if (width < 224 || height < 224 || width > 7680 || height > 7680 || if (width < 224 || height < 224 || width > 7680 || height > 7680 ||
height < width / 4 || width < height / 2) { height < width / 4 || width < height / 2) {
std::cerr << "Error: Unsupported resolution " << width << "x" << height std::cerr << "Error: Unsupported resolution " << width << "x" << height
<< " supplied.\n"; << " supplied\n";
return false; return false;
} }
Settings::getInstance()->setInt("WindowWidth", width); Settings::getInstance()->setInt("WindowWidth", width);
@ -272,7 +272,7 @@ bool parseArgs(int argc, char* argv[])
} }
else if (strcmp(argv[i], "--screensize") == 0) { else if (strcmp(argv[i], "--screensize") == 0) {
if (i >= argc - 2) { if (i >= argc - 2) {
std::cerr << "Error: Invalid screensize values supplied.\n"; std::cerr << "Error: Invalid screensize values supplied\n";
return false; return false;
} }
int width {atoi(argv[i + 1])}; int width {atoi(argv[i + 1])};
@ -283,7 +283,7 @@ bool parseArgs(int argc, char* argv[])
} }
else if (strcmp(argv[i], "--screenoffset") == 0) { else if (strcmp(argv[i], "--screenoffset") == 0) {
if (i >= argc - 2) { if (i >= argc - 2) {
std::cerr << "Error: Invalid screenoffset values supplied.\n"; std::cerr << "Error: Invalid screenoffset values supplied\n";
return false; return false;
} }
int x {atoi(argv[i + 1])}; int x {atoi(argv[i + 1])};
@ -294,13 +294,13 @@ bool parseArgs(int argc, char* argv[])
} }
else if (strcmp(argv[i], "--screenrotate") == 0) { else if (strcmp(argv[i], "--screenrotate") == 0) {
if (i >= argc - 1) { if (i >= argc - 1) {
std::cerr << "Error: No screenrotate value supplied.\n"; std::cerr << "Error: No screenrotate value supplied\n";
return false; return false;
} }
std::string rotateValue {argv[i + 1]}; std::string rotateValue {argv[i + 1]};
if (rotateValue != "on" && rotateValue != "off" && rotateValue != "1" && if (rotateValue != "on" && rotateValue != "off" && rotateValue != "1" &&
rotateValue != "0") { rotateValue != "0") {
std::cerr << "Error: Invalid screenrotate value supplied.\n"; std::cerr << "Error: Invalid screenrotate value supplied\n";
return false; return false;
} }
bool screenRotate {(rotateValue == "on" || rotateValue == "1") ? true : false}; bool screenRotate {(rotateValue == "on" || rotateValue == "1") ? true : false};
@ -309,13 +309,13 @@ bool parseArgs(int argc, char* argv[])
} }
else if (strcmp(argv[i], "--vsync") == 0) { else if (strcmp(argv[i], "--vsync") == 0) {
if (i >= argc - 1) { if (i >= argc - 1) {
std::cerr << "Error: No VSync value supplied.\n"; std::cerr << "Error: No VSync value supplied\n";
return false; return false;
} }
std::string vSyncValue = argv[i + 1]; std::string vSyncValue = argv[i + 1];
if (vSyncValue != "on" && vSyncValue != "off" && vSyncValue != "1" && if (vSyncValue != "on" && vSyncValue != "off" && vSyncValue != "1" &&
vSyncValue != "0") { vSyncValue != "0") {
std::cerr << "Error: Invalid VSync value supplied.\n"; std::cerr << "Error: Invalid VSync value supplied\n";
return false; return false;
} }
bool vSync {(vSyncValue == "on" || vSyncValue == "1") ? true : false}; bool vSync {(vSyncValue == "on" || vSyncValue == "1") ? true : false};
@ -324,7 +324,7 @@ bool parseArgs(int argc, char* argv[])
} }
else if (strcmp(argv[i], "--max-vram") == 0) { else if (strcmp(argv[i], "--max-vram") == 0) {
if (i >= argc - 1) { if (i >= argc - 1) {
std::cerr << "Error: Invalid VRAM value supplied.\n"; std::cerr << "Error: Invalid VRAM value supplied\n";
return false; return false;
} }
int maxVRAM {atoi(argv[i + 1])}; int maxVRAM {atoi(argv[i + 1])};
@ -332,6 +332,27 @@ bool parseArgs(int argc, char* argv[])
settingsNeedSaving = true; settingsNeedSaving = true;
++i; ++i;
} }
#if !defined(USE_OPENGLES)
else if (strcmp(argv[i], "--anti-aliasing") == 0) {
bool invalidValue {false};
int antiAlias {0};
if (i >= argc - 1) {
invalidValue = true;
}
else {
antiAlias = atoi(argv[i + 1]);
if (antiAlias != 0 && antiAlias != 2 && antiAlias != 4)
invalidValue = true;
}
if (invalidValue) {
std::cerr << "Error: Invalid anti-aliasing value supplied\n";
return false;
}
Settings::getInstance()->setInt("AntiAliasing", antiAlias);
settingsNeedSaving = true;
++i;
}
#endif
else if (strcmp(argv[i], "--no-splash") == 0) { else if (strcmp(argv[i], "--no-splash") == 0) {
Settings::getInstance()->setBool("SplashScreen", false); Settings::getInstance()->setBool("SplashScreen", false);
} }
@ -385,6 +406,9 @@ bool parseArgs(int argc, char* argv[])
" --screenrotate [1/on or 0/off] Rotate application screen 180 degrees\n" " --screenrotate [1/on or 0/off] Rotate application screen 180 degrees\n"
" --vsync [1/on or 0/off] Turn VSync on or off (default is on)\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" " --max-vram [size] Max VRAM to use (in mebibytes) before swapping\n"
#if !defined(USE_OPENGLES)
" --anti-aliasing [0, 2 or 4] Set MSAA anti-aliasing to disabled, 2x or 4x\n"
#endif
" --no-splash Don't show the splash screen during startup\n" " --no-splash Don't show the splash screen during startup\n"
" --gamelist-only Skip automatic game ROM search, only read from gamelist.xml\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 (useful for troubleshooting)\n"

View file

@ -247,6 +247,9 @@ void Settings::setDefaults()
mIntMap["MaxVRAM"] = {512, 512}; mIntMap["MaxVRAM"] = {512, 512};
#endif #endif
mIntMap["DisplayIndex"] = {1, 1}; mIntMap["DisplayIndex"] = {1, 1};
#if !defined(USE_OPENGLES)
mIntMap["AntiAliasing"] = {0, 0};
#endif
#if defined(__APPLE__) #if defined(__APPLE__)
mStringMap["KeyboardQuitShortcut"] = {"CmdQ", "CmdQ"}; mStringMap["KeyboardQuitShortcut"] = {"CmdQ", "CmdQ"};
#else #else

View file

@ -192,6 +192,14 @@ void RendererOpenGL::setup()
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
#if !defined(USE_OPENGLES)
const int antiAliasing {Settings::getInstance()->getInt("AntiAliasing")};
if (antiAliasing == 2 || antiAliasing == 4) {
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, antiAliasing);
}
#endif
} }
bool RendererOpenGL::createContext() bool RendererOpenGL::createContext()
@ -238,6 +246,17 @@ bool RendererOpenGL::createContext()
GL_CHECK_ERROR(glPixelStorei(GL_PACK_ALIGNMENT, 1)); GL_CHECK_ERROR(glPixelStorei(GL_PACK_ALIGNMENT, 1));
GL_CHECK_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1)); GL_CHECK_ERROR(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
#if !defined(USE_OPENGLES)
const int antiAliasing {Settings::getInstance()->getInt("AntiAliasing")};
if (antiAliasing == 2 || antiAliasing == 4) {
GL_CHECK_ERROR(glEnable(GL_MULTISAMPLE));
LOG(LogInfo) << "Anti-aliasing: " << antiAliasing << "x MSAA";
}
else {
LOG(LogInfo) << "Anti-aliasing: disabled";
}
#endif
// These are used for the shader post processing. // These are used for the shader post processing.
GL_CHECK_ERROR(glGenFramebuffers(1, &mShaderFBO1)); GL_CHECK_ERROR(glGenFramebuffers(1, &mShaderFBO1));
GL_CHECK_ERROR(glGenFramebuffers(1, &mShaderFBO2)); GL_CHECK_ERROR(glGenFramebuffers(1, &mShaderFBO2));
@ -279,6 +298,15 @@ void RendererOpenGL::destroyContext()
destroyTexture(mPostProcTexture1); destroyTexture(mPostProcTexture1);
destroyTexture(mPostProcTexture2); destroyTexture(mPostProcTexture2);
destroyTexture(mWhiteTexture); destroyTexture(mWhiteTexture);
mShaderProgramVector.clear();
mCoreShader.reset();
mBlurHorizontalShader.reset();
mBlurVerticalShader.reset();
mScanlinelShader.reset();
mLastShader.reset();
SDL_GL_DeleteContext(mSDLContext); SDL_GL_DeleteContext(mSDLContext);
mSDLContext = nullptr; mSDLContext = nullptr;
} }