From 30114c66778bff7b01bb294022e5994b8a74dfc3 Mon Sep 17 00:00:00 2001 From: enricoturri1966 Date: Thu, 18 Jan 2024 10:49:23 +0100 Subject: [PATCH] New gcode visualization library - Modified OpenGL ES context detection --- src/libvgcode/include/Viewer.hpp | 7 +++-- src/libvgcode/src/OpenGLUtils.cpp | 52 +++++++++++++++---------------- src/libvgcode/src/OpenGLUtils.hpp | 16 +++++----- src/libvgcode/src/Viewer.cpp | 4 +-- src/libvgcode/src/ViewerImpl.cpp | 25 ++++++++------- src/libvgcode/src/ViewerImpl.hpp | 7 ++--- src/slic3r/GUI/GCodeViewer.cpp | 3 +- 7 files changed, 57 insertions(+), 57 deletions(-) diff --git a/src/libvgcode/include/Viewer.hpp b/src/libvgcode/include/Viewer.hpp index 6285512725..458309f8f9 100644 --- a/src/libvgcode/include/Viewer.hpp +++ b/src/libvgcode/include/Viewer.hpp @@ -7,6 +7,8 @@ #include "Types.hpp" +#include + namespace libvgcode { class ViewerImpl; @@ -26,15 +28,16 @@ public: // // Initialize the viewer. + // Param opengl_context_version must be the string returned by glGetString(GL_VERSION). // This method must be called after a valid OpenGL context has been already created // and before calling any other method of the viewer. // Throws an std::runtime_error exception if: // * the method is called before creating an OpenGL context - // * the created OpenGL context does not support for OpenGL 3.2 or greater + // * the created OpenGL context does not support OpenGL 3.2 or greater // * when using OpenGL ES, the created OpenGL ES context does not support OpenGL ES 2.0 or greater // * any of the shaders fails to compile // - void init(); + void init(const std::string& opengl_context_version); // // Release the resources used by the viewer. // This method must be called before releasing the OpenGL context if the viewer diff --git a/src/libvgcode/src/OpenGLUtils.cpp b/src/libvgcode/src/OpenGLUtils.cpp index e0e0f36196..411241b676 100644 --- a/src/libvgcode/src/OpenGLUtils.cpp +++ b/src/libvgcode/src/OpenGLUtils.cpp @@ -9,11 +9,6 @@ #include #include -// Visual Studio warnings -#ifdef _MSC_VER -#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen -#endif // _MSC_VER - namespace libvgcode { #ifdef HAS_GLSAFE @@ -38,37 +33,40 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char } #endif // HAS_GLSAFE -static const std::string OPENGL_ES_STR = "OpenGL ES"; +static const char* OPENGL_ES_PREFIXES[] = { "OpenGL ES-CM ", "OpenGL ES-CL ", "OpenGL ES ", nullptr }; -bool OpenGLWrapper::s_detected = false; -bool OpenGLWrapper::s_valid = false; -bool OpenGLWrapper::s_es = false; - -bool OpenGLWrapper::load_opengl() +bool OpenGLWrapper::load_opengl(const std::string& context_version) { - if (gladLoadGL() == 0) - return false; + m_valid_context = false; + m_opengl_es = false; - s_detected = true; - - const char* version = reinterpret_cast(glGetString(GL_VERSION)); - if (version == nullptr) - return false; - - std::string version_str(version); - const size_t pos = version_str.find(OPENGL_ES_STR.c_str()); - if (pos == 0) { - s_es = true; - version_str = version_str.substr(OPENGL_ES_STR.length() + 1); + const char* version = context_version.c_str(); + for (int i = 0; OPENGL_ES_PREFIXES[i] != nullptr; ++i) { + const size_t length = strlen(OPENGL_ES_PREFIXES[i]); + if (strncmp(version, OPENGL_ES_PREFIXES[i], length) == 0) { + version += length; + m_opengl_es = true; + break; + } } + GLint major = 0; GLint minor = 0; - const int res = sscanf(version_str.c_str(), "%d.%d", &major, &minor); +#ifdef _MSC_VER + const int res = sscanf_s(version, "%d.%d", &major, &minor); +#else + const int res = sscanf(version, "%d.%d", &major, &minor); +#endif // _MSC_VER if (res != 2) return false; - s_valid = s_es ? major > 2 || (major == 2 && minor >= 0) : major > 3 || (major == 3 && minor >= 2); - return s_valid; + m_valid_context = m_opengl_es ? major > 2 || (major == 2 && minor >= 0) : major > 3 || (major == 3 && minor >= 2); + + const int glad_res = gladLoadGL(); + if (glad_res == 0) + return false; + + return m_valid_context; } } // namespace libvgcode diff --git a/src/libvgcode/src/OpenGLUtils.hpp b/src/libvgcode/src/OpenGLUtils.hpp index 0ee0d7e954..ad8a3b3bcd 100644 --- a/src/libvgcode/src/OpenGLUtils.hpp +++ b/src/libvgcode/src/OpenGLUtils.hpp @@ -8,6 +8,8 @@ // OpenGL loader #include "../glad/include/glad/glad.h" +#include + namespace libvgcode { #ifndef NDEBUG #define HAS_GLSAFE @@ -27,17 +29,13 @@ inline void glAssertRecentCall() { } class OpenGLWrapper { public: - OpenGLWrapper() = delete; - - static bool load_opengl(); - static bool is_detected() { return s_detected; } - static bool is_valid() { return s_valid; } - static bool is_es() { return s_es; } + bool load_opengl(const std::string& context_version); + bool is_valid_context() { return m_valid_context; } + bool is_opengl_es() { return m_opengl_es; } private: - static bool s_detected; - static bool s_valid; - static bool s_es; + bool m_valid_context{ false }; + bool m_opengl_es{ false }; }; } // namespace libvgcode diff --git a/src/libvgcode/src/Viewer.cpp b/src/libvgcode/src/Viewer.cpp index 4757deb044..903760dc63 100644 --- a/src/libvgcode/src/Viewer.cpp +++ b/src/libvgcode/src/Viewer.cpp @@ -17,9 +17,9 @@ Viewer::~Viewer() delete m_impl; } -void Viewer::init() +void Viewer::init(const std::string& opengl_context_version) { - m_impl->init(); + m_impl->init(opengl_context_version); } void Viewer::shutdown() diff --git a/src/libvgcode/src/ViewerImpl.cpp b/src/libvgcode/src/ViewerImpl.cpp index 9ac6514cc2..ae63363de0 100644 --- a/src/libvgcode/src/ViewerImpl.cpp +++ b/src/libvgcode/src/ViewerImpl.cpp @@ -318,24 +318,25 @@ const std::map ViewerImpl::DEFAULT_OPTIONS_COLORS{ { { EOptionType::CustomGCodes, { 226, 210, 67 } } } }; -void ViewerImpl::init() +void ViewerImpl::init(const std::string& opengl_context_version) { if (m_initialized) return; - if (!OpenGLWrapper::load_opengl()) { - if (!OpenGLWrapper::is_detected()) - throw std::runtime_error("LibVGCode was unable to initialize OpenGL. A valid OpenGL context is missing.\n"); - else if (!OpenGLWrapper::is_valid()) { - if (OpenGLWrapper::is_es()) - throw std::runtime_error("LibVGCode requires an active OpenGL ES context based on OpenGL ES 2.0 or higher:\n"); + OpenGLWrapper opengl_wrapper; + if (!opengl_wrapper.load_opengl(opengl_context_version)) { + if (opengl_wrapper.is_valid_context()) + throw std::runtime_error("LibVGCode was unable to initialize the GLAD library.\n"); + else { + if (opengl_wrapper.is_opengl_es()) + throw std::runtime_error("LibVGCode requires an OpenGL ES context based on OpenGL ES 2.0 or higher.\n"); else - throw std::runtime_error("LibVGCode requires an active OpenGL context based on OpenGL 3.2 or higher:\n"); + throw std::runtime_error("LibVGCode requires an OpenGL context based on OpenGL 3.2 or higher.\n"); } } // segments shader - m_segments_shader_id = OpenGLWrapper::is_es() ? + m_segments_shader_id = opengl_wrapper.is_opengl_es() ? init_shader("segments", Segments_Vertex_Shader_ES, Segments_Fragment_Shader_ES) : init_shader("segments", Segments_Vertex_Shader, Segments_Fragment_Shader); @@ -358,7 +359,7 @@ void ViewerImpl::init() m_segment_template.init(); // options shader - m_options_shader_id = OpenGLWrapper::is_es() ? + m_options_shader_id = opengl_wrapper.is_opengl_es() ? init_shader("options", Options_Vertex_Shader_ES, Options_Fragment_Shader_ES) : init_shader("options", Options_Vertex_Shader, Options_Fragment_Shader); @@ -380,7 +381,7 @@ void ViewerImpl::init() #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS // cog marker shader - m_cog_marker_shader_id = OpenGLWrapper::is_es() ? + m_cog_marker_shader_id = opengl_wrapper.is_opengl_es() ? init_shader("cog_marker", Cog_Marker_Vertex_Shader_ES, Cog_Marker_Fragment_Shader_ES) : init_shader("cog_marker", Cog_Marker_Vertex_Shader, Cog_Marker_Fragment_Shader); @@ -397,7 +398,7 @@ void ViewerImpl::init() m_cog_marker.init(32, 1.0f); // tool marker shader - m_tool_marker_shader_id = OpenGLWrapper::is_es() ? + m_tool_marker_shader_id = opengl_wrapper.is_opengl_es() ? init_shader("tool_marker", Tool_Marker_Vertex_Shader_ES, Tool_Marker_Fragment_Shader_ES) : init_shader("tool_marker", Tool_Marker_Vertex_Shader, Tool_Marker_Fragment_Shader); diff --git a/src/libvgcode/src/ViewerImpl.hpp b/src/libvgcode/src/ViewerImpl.hpp index 25f4d8ba07..318cb75b0b 100644 --- a/src/libvgcode/src/ViewerImpl.hpp +++ b/src/libvgcode/src/ViewerImpl.hpp @@ -19,6 +19,8 @@ #include "Layers.hpp" #include "ExtrusionRoles.hpp" +#include + namespace libvgcode { struct GCodeInputData; @@ -36,17 +38,15 @@ public: // // Initialize shaders, uniform indices and segment geometry. // - void init(); + void init(const std::string& opengl_context_version); // // Release the resources used by the viewer. // void shutdown(); - // // Reset all caches and free gpu memory. // void reset(); - // // Setup all the variables used for visualization of the toolpaths // from the given gcode data. @@ -58,7 +58,6 @@ public: // of the current settings // void update_enabled_entities(); - // // Update the color of toolpaths in dependence of the current // view type and settings diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index f53322e7c9..0f403c78d9 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -1098,7 +1098,8 @@ void GCodeViewer::init() #if ENABLE_NEW_GCODE_VIEWER try { - m_viewer.init(); + m_viewer.init(reinterpret_cast(glGetString(GL_VERSION))); + glcheck(); } catch (const std::exception& e) {