From 1832c833a1747e5ff6ba5025d634182313737db7 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Wed, 3 Jan 2024 12:53:43 +0100 Subject: [PATCH 1/2] #12000: Fixes incorrect detection of supported OpenGL version (SPE-2092) 1) Force OpenGL 3.2 as minimum required. If the graphic card does not support it, automatically switch to software renderer. 2) command line option: --opengl-version=X.Y -> allows to select core profile of version X.Y. 3) command line option: --opengl-compatibility -> allows to select compatibility profile of the highest OpenGL version supported by the graphic card. 4) command line option: --opengl-debug -> enable OpenGL debug output on card supporting OpenGL 4.3 or higher (output on console). --- src/PrusaSlicer.cpp | 30 ++++++----- src/PrusaSlicer_app_msvc.cpp | 2 +- src/libslic3r/PrintConfig.cpp | 8 ++- src/libslic3r/Technologies.hpp | 2 - src/slic3r/GUI/GUI_App.cpp | 6 +-- src/slic3r/GUI/GUI_Init.hpp | 13 +++-- src/slic3r/GUI/OpenGLManager.cpp | 92 ++++++++++++++------------------ src/slic3r/GUI/OpenGLManager.hpp | 14 ++--- 8 files changed, 76 insertions(+), 91 deletions(-) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 04b481bc42..80a990fb8c 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -170,10 +170,9 @@ int CLI::run(int argc, char **argv) #ifdef SLIC3R_GUI #if ENABLE_GL_CORE_PROFILE - std::pair opengl_version = { 0, 0 }; -#if ENABLE_OPENGL_DEBUG_OPTION - bool opengl_debug = false; -#endif // ENABLE_OPENGL_DEBUG_OPTION + std::pair opengl_version = { 0, 0 }; + bool opengl_debug = false; + bool opengl_compatibility_profile = false; // search for special keys into command line parameters auto it = std::find(m_actions.begin(), m_actions.end(), "gcodeviewer"); @@ -187,10 +186,8 @@ int CLI::run(int argc, char **argv) if (it != m_actions.end()) { std::string opengl_version_str = m_config.opt_string("opengl-version"); if (std::find(Slic3r::GUI::OpenGLVersions::core_str.begin(), Slic3r::GUI::OpenGLVersions::core_str.end(), opengl_version_str) == Slic3r::GUI::OpenGLVersions::core_str.end()) { - if (std::find(Slic3r::GUI::OpenGLVersions::precore_str.begin(), Slic3r::GUI::OpenGLVersions::precore_str.end(), opengl_version_str) == Slic3r::GUI::OpenGLVersions::precore_str.end()) { - boost::nowide::cerr << "Found invalid OpenGL version: " << opengl_version_str << std::endl; - opengl_version_str.clear(); - } + boost::nowide::cerr << "Required OpenGL version " << opengl_version_str << " is invalid. Must be greater than or equal to 3.2" << std::endl; + opengl_version_str.clear(); } if (!opengl_version_str.empty()) { @@ -203,12 +200,20 @@ int CLI::run(int argc, char **argv) m_actions.erase(it); } + it = std::find(m_actions.begin(), m_actions.end(), "opengl-compatibility"); + if (it != m_actions.end()) { + start_gui = true; + opengl_compatibility_profile = true; + // reset version as compatibility profile always take the highest version + // supported by the graphic card + opengl_version = std::make_pair(0, 0); + m_actions.erase(it); + } + it = std::find(m_actions.begin(), m_actions.end(), "opengl-debug"); if (it != m_actions.end()) { start_gui = true; -#if ENABLE_OPENGL_DEBUG_OPTION opengl_debug = true; -#endif // ENABLE_OPENGL_DEBUG_OPTION m_actions.erase(it); } #else @@ -224,7 +229,7 @@ int CLI::run(int argc, char **argv) #endif // ENABLE_GL_CORE_PROFILE #else // SLIC3R_GUI // If there is no GUI, we shall ignore the parameters. Remove them from the list. - for (const std::string& s : { "opengl-version", "opengl-debug", "gcodeviewer" }) { + for (const std::string& s : { "opengl-version", "opengl-compatibility", "opengl-debug", "gcodeviewer" }) { auto it = std::find(m_actions.cbegin(), m_actions.cend(), s); if (it != m_actions.end()) { boost::nowide::cerr << "Parameter '" << s << "' is ignored, this PrusaSlicer build is CLI only." << std::endl; @@ -714,10 +719,9 @@ int CLI::run(int argc, char **argv) params.download_url = download_url; params.delete_after_load = delete_after_load; #if ENABLE_GL_CORE_PROFILE -#if ENABLE_OPENGL_DEBUG_OPTION params.opengl_version = opengl_version; params.opengl_debug = opengl_debug; -#endif // ENABLE_OPENGL_DEBUG_OPTION + params.opengl_compatibiity_profile = opengl_compatibility_profile; #endif // ENABLE_GL_CORE_PROFILE return Slic3r::GUI::GUI_Run(params); #else // SLIC3R_GUI diff --git a/src/PrusaSlicer_app_msvc.cpp b/src/PrusaSlicer_app_msvc.cpp index 06f15aa5ad..c6ba41e4ea 100644 --- a/src/PrusaSlicer_app_msvc.cpp +++ b/src/PrusaSlicer_app_msvc.cpp @@ -266,7 +266,7 @@ int wmain(int argc, wchar_t **argv) // In that case, use Mesa. (::GetSystemMetrics(SM_REMOTESESSION) && !force_hw) || // Try to load the default OpenGL driver and test its context version. - ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(2, 0); + ! opengl_version_check.load_opengl_dll() || ! opengl_version_check.is_version_greater_or_equal_to(3, 2); #endif /* SLIC3R_GUI */ wchar_t path_to_exe[MAX_PATH + 1] = { 0 }; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 02e824efe6..34e513f571 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4889,9 +4889,15 @@ CLIActionsConfigDef::CLIActionsConfigDef() def->cli = "opengl-version"; def->set_default_value(new ConfigOptionString()); + def = this->add("opengl-compatibility", coBool); + def->label = L("OpenGL compatibility profile"); + def->tooltip = L("Enable OpenGL compatibility profile"); + def->cli = "opengl-compatibility"; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("opengl-debug", coBool); def->label = L("OpenGL debug output"); - def->tooltip = L("Activate OpenGL debug output on graphic cards which support it"); + def->tooltip = L("Activate OpenGL debug output on graphic cards which support it (OpenGL 4.3 or higher)"); def->cli = "opengl-debug"; def->set_default_value(new ConfigOptionBool(false)); #endif // ENABLE_GL_CORE_PROFILE diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 3989eab3d2..b95b7a37fd 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,8 +55,6 @@ #define ENABLE_OPENGL_ES 0 // Enable OpenGL core profile context (tested against Mesa 20.1.8 on Windows) #define ENABLE_GL_CORE_PROFILE (1 && !ENABLE_OPENGL_ES) -// Enable OpenGL debug messages using debug context -#define ENABLE_OPENGL_DEBUG_OPTION (1 && ENABLE_GL_CORE_PROFILE) // Enable imgui dialog which allows to set the parameters used to export binarized gcode #define ENABLE_BINARIZED_GCODE_DEBUG_WINDOW 0 diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 75f52eaf36..fd88b61573 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -889,12 +889,8 @@ std::string GUI_App::get_gl_info(bool for_github) wxGLContext* GUI_App::init_glcontext(wxGLCanvas& canvas) { #if ENABLE_GL_CORE_PROFILE -#if ENABLE_OPENGL_DEBUG_OPTION return m_opengl_mgr.init_glcontext(canvas, init_params != nullptr ? init_params->opengl_version : std::make_pair(0, 0), - init_params != nullptr ? init_params->opengl_debug : false); -#else - return m_opengl_mgr.init_glcontext(canvas, init_params != nullptr ? init_params->opengl_version : std::make_pair(0, 0)); -#endif // ENABLE_OPENGL_DEBUG_OPTION + init_params != nullptr ? init_params->opengl_compatibiity_profile : false, init_params != nullptr ? init_params->opengl_debug : false); #else return m_opengl_mgr.init_glcontext(canvas); #endif // ENABLE_GL_CORE_PROFILE diff --git a/src/slic3r/GUI/GUI_Init.hpp b/src/slic3r/GUI/GUI_Init.hpp index e2d43ae6da..30c24d2bee 100644 --- a/src/slic3r/GUI/GUI_Init.hpp +++ b/src/slic3r/GUI/GUI_Init.hpp @@ -33,15 +33,14 @@ struct GUI_InitParams DynamicPrintConfig extra_config; std::vector input_files; - bool start_as_gcodeviewer; - bool start_downloader; - bool delete_after_load; + bool start_as_gcodeviewer; + bool start_downloader; + bool delete_after_load; std::string download_url; #if ENABLE_GL_CORE_PROFILE - std::pair opengl_version; -#if ENABLE_OPENGL_DEBUG_OPTION - bool opengl_debug; -#endif // ENABLE_OPENGL_DEBUG_OPTION + std::pair opengl_version; + bool opengl_debug; + bool opengl_compatibiity_profile; #endif // ENABLE_GL_CORE_PROFILE }; diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index c64cf9b5a6..c9df0caaa6 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -127,6 +127,10 @@ void OpenGLManager::GLInfo::detect() const float* max_anisotropy = const_cast(&m_max_anisotropy); glsafe(::glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, max_anisotropy)); } + + if (!GLEW_ARB_compatibility) + *const_cast(&m_core_profile) = true; + *const_cast(&m_detected) = true; } @@ -197,7 +201,7 @@ std::string OpenGLManager::GLInfo::to_string(bool for_github) const std::string line_end = format_as_html ? "
" : "\n"; out << h2_start << "OpenGL installation" << h2_end << line_end; - out << b_start << "GL version: " << b_end << m_version << line_end; + out << b_start << "GL version: " << b_end << m_version << " (" << m_version_string << ")" << line_end; #if ENABLE_GL_CORE_PROFILE out << b_start << "Profile: " << b_end << (is_core_profile() ? "Core" : "Compatibility") << line_end; #endif // ENABLE_GL_CORE_PROFILE @@ -287,14 +291,14 @@ OpenGLManager::~OpenGLManager() #endif //__APPLE__ } -#if ENABLE_OPENGL_DEBUG_OPTION +#if ENABLE_GL_CORE_PROFILE #ifdef _WIN32 static void APIENTRY CustomGLDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char* message, const void* userParam) #else static void CustomGLDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char* message, const void* userParam) #endif // _WIN32 { - if (severity == GL_DEBUG_SEVERITY_NOTIFICATION) + if (severity != GL_DEBUG_SEVERITY_HIGH) return; std::string out = "OpenGL DEBUG message ["; @@ -331,7 +335,7 @@ static void CustomGLDebugOutput(GLenum source, GLenum type, unsigned int id, GLe out += "]:\n"; std::cout << out << "(" << id << "): " << message << "\n\n"; } -#endif // ENABLE_OPENGL_DEBUG_OPTION +#endif // ENABLE_GL_CORE_PROFILE bool OpenGLManager::init_gl() { @@ -369,7 +373,7 @@ bool OpenGLManager::init_gl() #if ENABLE_OPENGL_ES bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); #elif ENABLE_GL_CORE_PROFILE - bool valid_version = s_gl_info.is_core_profile() ? s_gl_info.is_version_greater_or_equal_to(3, 2) : s_gl_info.is_version_greater_or_equal_to(2, 0); + const bool valid_version = s_gl_info.is_version_greater_or_equal_to(3, 2); #else bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); #endif // ENABLE_OPENGL_ES @@ -379,16 +383,16 @@ bool OpenGLManager::init_gl() wxString message = format_wxstr( #if ENABLE_OPENGL_ES _L("PrusaSlicer requires OpenGL ES 2.0 capable graphics driver to run correctly, \n" - "while OpenGL version %s, render %s, vendor %s was detected."), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor()); + "while OpenGL version %s, render %s, vendor %s was detected."), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor()); #elif ENABLE_GL_CORE_PROFILE - _L("PrusaSlicer requires OpenGL %s capable graphics driver to run correctly, \n" - "while OpenGL version %s, render %s, vendor %s was detected."), (s_gl_info.is_core_profile() ? "3.3" : "2.0"), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor()); + _L("PrusaSlicer requires OpenGL 3.2 capable graphics driver to run correctly,\n" + "while OpenGL version %s, render %s, vendor %s was detected."), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor()); #else _L("PrusaSlicer requires OpenGL 2.0 capable graphics driver to run correctly, \n" - "while OpenGL version %s, render %s, vendor %s was detected."), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor()); + "while OpenGL version %s, render %s, vendor %s was detected."), s_gl_info.get_version_string(), s_gl_info.get_renderer(), s_gl_info.get_vendor()); #endif // ENABLE_OPENGL_ES message += "\n"; - message += _L("You may need to update your graphics card driver."); + message += _L("You may need to update your graphics card driver."); #ifdef _WIN32 message += "\n"; message += _L("As a workaround, you may run PrusaSlicer with a software rendered 3D graphics by running prusa-slicer.exe with the --sw-renderer parameter."); @@ -403,14 +407,15 @@ bool OpenGLManager::init_gl() wxString message = format_wxstr(_L("Unable to load the following shaders:\n%s"), error); wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Error loading shaders"), wxOK | wxICON_ERROR); } -#if ENABLE_OPENGL_DEBUG_OPTION - if (m_debug_enabled && GLEW_KHR_debug) { +#if ENABLE_GL_CORE_PROFILE + if (m_debug_enabled && s_gl_info.is_version_greater_or_equal_to(4, 3) && GLEW_KHR_debug) { ::glEnable(GL_DEBUG_OUTPUT); ::glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); ::glDebugMessageCallback(CustomGLDebugOutput, nullptr); ::glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE); + std::cout << "Enabled OpenGL debug output\n"; } -#endif // ENABLE_OPENGL_DEBUG_OPTION +#endif // ENABLE_GL_CORE_PROFILE } #ifdef _WIN32 @@ -437,11 +442,8 @@ bool OpenGLManager::init_gl() } #if ENABLE_GL_CORE_PROFILE -#if ENABLE_OPENGL_DEBUG_OPTION -wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version, bool enable_debug) -#else -wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version) -#endif // ENABLE_OPENGL_DEBUG_OPTION +wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version, bool enable_compatibility_profile, + bool enable_debug) #else wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) #endif // ENABLE_GL_CORE_PROFILE @@ -452,33 +454,25 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) attrs.PlatformDefaults().ES2().MajorVersion(2).EndList(); m_context = new wxGLContext(&canvas, nullptr, &attrs); #elif ENABLE_GL_CORE_PROFILE -#if ENABLE_OPENGL_DEBUG_OPTION m_debug_enabled = enable_debug; -#endif // ENABLE_OPENGL_DEBUG_OPTION const int gl_major = required_opengl_version.first; const int gl_minor = required_opengl_version.second; const bool supports_core_profile = (gl_major < 3) ? false : (gl_major > 3) ? true : gl_minor >= 2; - if (gl_major == 0) { + if (gl_major == 0 && !enable_compatibility_profile) { // search for highest supported core profile version // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context wxLogNull logNo; for (auto v = OpenGLVersions::core.rbegin(); v != OpenGLVersions::core.rend(); ++v) { wxGLContextAttrs attrs; -#if ENABLE_OPENGL_DEBUG_OPTION attrs.PlatformDefaults().MajorVersion(v->first).MinorVersion(v->second).CoreProfile().ForwardCompatible(); if (m_debug_enabled) attrs.DebugCtx(); attrs.EndList(); -#else - attrs.PlatformDefaults().MajorVersion(gl_major).MinorVersion(gl_minor).CoreProfile().ForwardCompatible().EndList(); -#endif // ENABLE_OPENGL_DEBUG_OPTION m_context = new wxGLContext(&canvas, nullptr, &attrs); - if (m_context->IsOK()) { - s_gl_info.set_core_profile(true); + if (m_context->IsOK()) break; - } else { delete m_context; m_context = nullptr; @@ -487,45 +481,41 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) } if (m_context == nullptr) { - // search for requested core profile version - if (supports_core_profile) { + // search for requested compatibility profile version + if (enable_compatibility_profile) { + // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context + wxLogNull logNo; + wxGLContextAttrs attrs; + attrs.PlatformDefaults().CompatibilityProfile(); + if (m_debug_enabled) + attrs.DebugCtx(); + attrs.EndList(); + m_context = new wxGLContext(&canvas, nullptr, &attrs); + if (!m_context->IsOK()) { + delete m_context; + m_context = nullptr; + } + } + // search for requested core profile version + else if (supports_core_profile) { // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context wxLogNull logNo; wxGLContextAttrs attrs; -#if ENABLE_OPENGL_DEBUG_OPTION attrs.PlatformDefaults().MajorVersion(gl_major).MinorVersion(gl_minor).CoreProfile().ForwardCompatible(); if (m_debug_enabled) attrs.DebugCtx(); attrs.EndList(); -#else - attrs.PlatformDefaults().MajorVersion(gl_major).MinorVersion(gl_minor).CoreProfile().ForwardCompatible().EndList(); -#endif // ENABLE_OPENGL_DEBUG_OPTION m_context = new wxGLContext(&canvas, nullptr, &attrs); if (!m_context->IsOK()) { - BOOST_LOG_TRIVIAL(error) << "Unable to create context for required OpenGL " << gl_major << "." << gl_minor; delete m_context; m_context = nullptr; } - else - s_gl_info.set_core_profile(true); } } -#if ENABLE_OPENGL_DEBUG_OPTION - if (m_context == nullptr) { - wxGLContextAttrs attrs; - attrs.PlatformDefaults(); - if (m_debug_enabled) - attrs.DebugCtx(); - attrs.EndList(); - // if no valid context was created use the default one - m_context = new wxGLContext(&canvas, nullptr, &attrs); - } -#else if (m_context == nullptr) - // if no valid context was created use the default one - m_context = new wxGLContext(&canvas); -#endif // ENABLE_OPENGL_DEBUG_OPTION + // no valid context was created + throw Slic3r::RuntimeError("Unable to create context for OpenGL."); #else m_context = new wxGLContext(&canvas); #endif // ENABLE_OPENGL_ES diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 265ceb5160..9b45a08c0a 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -54,15 +54,13 @@ public: const std::string& get_renderer() const; bool is_core_profile() const { return m_core_profile; } - void set_core_profile(bool value) { m_core_profile = value; } bool is_mesa() const; bool is_es() const { - return #if ENABLE_OPENGL_ES - true; + return true; #else - false; + return false; #endif // ENABLE_OPENGL_ES } @@ -104,9 +102,7 @@ private: bool m_gl_initialized{ false }; wxGLContext* m_context{ nullptr }; -#if ENABLE_OPENGL_DEBUG_OPTION bool m_debug_enabled{ false }; -#endif // ENABLE_OPENGL_DEBUG_OPTION GLShadersManager m_shaders_manager; static GLInfo s_gl_info; #ifdef __APPLE__ @@ -125,11 +121,7 @@ public: bool init_gl(); #if ENABLE_GL_CORE_PROFILE -#if ENABLE_OPENGL_DEBUG_OPTION - wxGLContext* init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version, bool enable_debug); -#else - wxGLContext* init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version); -#endif // ENABLE_OPENGL_DEBUG_OPTION + wxGLContext* init_glcontext(wxGLCanvas& canvas, const std::pair& required_opengl_version, bool enable_compatibility_profile, bool enable_debug); #else wxGLContext* init_glcontext(wxGLCanvas& canvas); #endif // ENABLE_GL_CORE_PROFILE From 3cab0cbecb887c5a39030b40e42fa51659ddec7e Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 19 Jan 2024 16:12:27 +0100 Subject: [PATCH 2/2] Using Semver to check minimum required OpenGL version --- src/PrusaSlicer.cpp | 20 ++++++++------------ src/slic3r/GUI/GUI_Init.cpp | 4 ---- src/slic3r/GUI/GUI_Init.hpp | 4 ---- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index 80a990fb8c..44f1c28d34 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -184,18 +184,14 @@ int CLI::run(int argc, char **argv) it = std::find(m_actions.begin(), m_actions.end(), "opengl-version"); if (it != m_actions.end()) { - std::string opengl_version_str = m_config.opt_string("opengl-version"); - if (std::find(Slic3r::GUI::OpenGLVersions::core_str.begin(), Slic3r::GUI::OpenGLVersions::core_str.end(), opengl_version_str) == Slic3r::GUI::OpenGLVersions::core_str.end()) { - boost::nowide::cerr << "Required OpenGL version " << opengl_version_str << " is invalid. Must be greater than or equal to 3.2" << std::endl; - opengl_version_str.clear(); - } - - if (!opengl_version_str.empty()) { - std::vector tokens; - boost::split(tokens, opengl_version_str, boost::is_any_of("."), boost::token_compress_on); - opengl_version.first = std::stoi(tokens[0].c_str()); - opengl_version.second = std::stoi(tokens[1].c_str()); - } + const Semver opengl_minimum = Semver(3,2,0); + const std::string opengl_version_str = m_config.opt_string("opengl-version"); + boost::optional semver = Semver::parse(opengl_version_str); + if (semver.has_value() && (*semver) >= opengl_minimum ) { + opengl_version.first = semver->maj(); + opengl_version.second = semver->min(); + } else + boost::nowide::cerr << "Required OpenGL version " << opengl_version_str << " is invalid. Must be greater than or equal to " << opengl_minimum.to_string() << std::endl; start_gui = true; m_actions.erase(it); } diff --git a/src/slic3r/GUI/GUI_Init.cpp b/src/slic3r/GUI/GUI_Init.cpp index 6f734388e4..504a42a932 100644 --- a/src/slic3r/GUI/GUI_Init.cpp +++ b/src/slic3r/GUI/GUI_Init.cpp @@ -30,11 +30,7 @@ namespace Slic3r { namespace GUI { -const std::vector OpenGLVersions::core_str = { "3.2", "3.3", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6" }; -const std::vector OpenGLVersions::precore_str = { "2.0", "2.1", "3.0", "3.1" }; - const std::vector> OpenGLVersions::core = { {3,2}, {3,3}, {4,0}, {4,1}, {4,2}, {4,3}, {4,4}, {4,5}, {4,6} }; -const std::vector> OpenGLVersions::precore = { {2,0}, {2,1}, {3,0}, {3,1} }; int GUI_Run(GUI_InitParams ¶ms) { diff --git a/src/slic3r/GUI/GUI_Init.hpp b/src/slic3r/GUI/GUI_Init.hpp index 30c24d2bee..b21da42a5e 100644 --- a/src/slic3r/GUI/GUI_Init.hpp +++ b/src/slic3r/GUI/GUI_Init.hpp @@ -14,11 +14,7 @@ namespace GUI { struct OpenGLVersions { - static const std::vector core_str; - static const std::vector precore_str; - static const std::vector> core; - static const std::vector> precore; }; struct GUI_InitParams