New gcode visualization library - Modified OpenGL ES context detection

This commit is contained in:
enricoturri1966 2024-01-18 10:49:23 +01:00 committed by Lukas Matena
parent 895df5bae2
commit 30114c6677
7 changed files with 57 additions and 57 deletions

View File

@ -7,6 +7,8 @@
#include "Types.hpp" #include "Types.hpp"
#include <string>
namespace libvgcode { namespace libvgcode {
class ViewerImpl; class ViewerImpl;
@ -26,15 +28,16 @@ public:
// //
// Initialize the viewer. // 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 // This method must be called after a valid OpenGL context has been already created
// and before calling any other method of the viewer. // and before calling any other method of the viewer.
// Throws an std::runtime_error exception if: // Throws an std::runtime_error exception if:
// * the method is called before creating an OpenGL context // * 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 // * 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 // * any of the shaders fails to compile
// //
void init(); void init(const std::string& opengl_context_version);
// //
// Release the resources used by the viewer. // Release the resources used by the viewer.
// This method must be called before releasing the OpenGL context if the viewer // This method must be called before releasing the OpenGL context if the viewer

View File

@ -9,11 +9,6 @@
#include <cctype> #include <cctype>
#include <stdio.h> #include <stdio.h>
// 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 { namespace libvgcode {
#ifdef HAS_GLSAFE #ifdef HAS_GLSAFE
@ -38,37 +33,40 @@ void glAssertRecentCallImpl(const char* file_name, unsigned int line, const char
} }
#endif // HAS_GLSAFE #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::load_opengl(const std::string& context_version)
bool OpenGLWrapper::s_valid = false;
bool OpenGLWrapper::s_es = false;
bool OpenGLWrapper::load_opengl()
{ {
if (gladLoadGL() == 0) m_valid_context = false;
return false; m_opengl_es = false;
s_detected = true; const char* version = context_version.c_str();
for (int i = 0; OPENGL_ES_PREFIXES[i] != nullptr; ++i) {
const char* version = reinterpret_cast<const char*>(glGetString(GL_VERSION)); const size_t length = strlen(OPENGL_ES_PREFIXES[i]);
if (version == nullptr) if (strncmp(version, OPENGL_ES_PREFIXES[i], length) == 0) {
return false; version += length;
m_opengl_es = true;
std::string version_str(version); break;
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);
} }
GLint major = 0; GLint major = 0;
GLint minor = 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) if (res != 2)
return false; return false;
s_valid = s_es ? major > 2 || (major == 2 && minor >= 0) : major > 3 || (major == 3 && minor >= 2); m_valid_context = m_opengl_es ? major > 2 || (major == 2 && minor >= 0) : major > 3 || (major == 3 && minor >= 2);
return s_valid;
const int glad_res = gladLoadGL();
if (glad_res == 0)
return false;
return m_valid_context;
} }
} // namespace libvgcode } // namespace libvgcode

View File

@ -8,6 +8,8 @@
// OpenGL loader // OpenGL loader
#include "../glad/include/glad/glad.h" #include "../glad/include/glad/glad.h"
#include <string>
namespace libvgcode { namespace libvgcode {
#ifndef NDEBUG #ifndef NDEBUG
#define HAS_GLSAFE #define HAS_GLSAFE
@ -27,17 +29,13 @@ inline void glAssertRecentCall() { }
class OpenGLWrapper class OpenGLWrapper
{ {
public: public:
OpenGLWrapper() = delete; bool load_opengl(const std::string& context_version);
bool is_valid_context() { return m_valid_context; }
static bool load_opengl(); bool is_opengl_es() { return m_opengl_es; }
static bool is_detected() { return s_detected; }
static bool is_valid() { return s_valid; }
static bool is_es() { return s_es; }
private: private:
static bool s_detected; bool m_valid_context{ false };
static bool s_valid; bool m_opengl_es{ false };
static bool s_es;
}; };
} // namespace libvgcode } // namespace libvgcode

View File

@ -17,9 +17,9 @@ Viewer::~Viewer()
delete m_impl; 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() void Viewer::shutdown()

View File

@ -318,24 +318,25 @@ const std::map<EOptionType, Color> ViewerImpl::DEFAULT_OPTIONS_COLORS{ {
{ EOptionType::CustomGCodes, { 226, 210, 67 } } { EOptionType::CustomGCodes, { 226, 210, 67 } }
} }; } };
void ViewerImpl::init() void ViewerImpl::init(const std::string& opengl_context_version)
{ {
if (m_initialized) if (m_initialized)
return; return;
if (!OpenGLWrapper::load_opengl()) { OpenGLWrapper opengl_wrapper;
if (!OpenGLWrapper::is_detected()) if (!opengl_wrapper.load_opengl(opengl_context_version)) {
throw std::runtime_error("LibVGCode was unable to initialize OpenGL. A valid OpenGL context is missing.\n"); if (opengl_wrapper.is_valid_context())
else if (!OpenGLWrapper::is_valid()) { throw std::runtime_error("LibVGCode was unable to initialize the GLAD library.\n");
if (OpenGLWrapper::is_es()) else {
throw std::runtime_error("LibVGCode requires an active OpenGL ES context based on OpenGL ES 2.0 or higher:\n"); 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 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 // 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_ES, Segments_Fragment_Shader_ES) :
init_shader("segments", Segments_Vertex_Shader, Segments_Fragment_Shader); init_shader("segments", Segments_Vertex_Shader, Segments_Fragment_Shader);
@ -358,7 +359,7 @@ void ViewerImpl::init()
m_segment_template.init(); m_segment_template.init();
// options shader // 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_ES, Options_Fragment_Shader_ES) :
init_shader("options", Options_Vertex_Shader, Options_Fragment_Shader); init_shader("options", Options_Vertex_Shader, Options_Fragment_Shader);
@ -380,7 +381,7 @@ void ViewerImpl::init()
#if VGCODE_ENABLE_COG_AND_TOOL_MARKERS #if VGCODE_ENABLE_COG_AND_TOOL_MARKERS
// cog marker shader // 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_ES, Cog_Marker_Fragment_Shader_ES) :
init_shader("cog_marker", Cog_Marker_Vertex_Shader, Cog_Marker_Fragment_Shader); 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); m_cog_marker.init(32, 1.0f);
// tool marker shader // 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_ES, Tool_Marker_Fragment_Shader_ES) :
init_shader("tool_marker", Tool_Marker_Vertex_Shader, Tool_Marker_Fragment_Shader); init_shader("tool_marker", Tool_Marker_Vertex_Shader, Tool_Marker_Fragment_Shader);

View File

@ -19,6 +19,8 @@
#include "Layers.hpp" #include "Layers.hpp"
#include "ExtrusionRoles.hpp" #include "ExtrusionRoles.hpp"
#include <string>
namespace libvgcode { namespace libvgcode {
struct GCodeInputData; struct GCodeInputData;
@ -36,17 +38,15 @@ public:
// //
// Initialize shaders, uniform indices and segment geometry. // Initialize shaders, uniform indices and segment geometry.
// //
void init(); void init(const std::string& opengl_context_version);
// //
// Release the resources used by the viewer. // Release the resources used by the viewer.
// //
void shutdown(); void shutdown();
// //
// Reset all caches and free gpu memory. // Reset all caches and free gpu memory.
// //
void reset(); void reset();
// //
// Setup all the variables used for visualization of the toolpaths // Setup all the variables used for visualization of the toolpaths
// from the given gcode data. // from the given gcode data.
@ -58,7 +58,6 @@ public:
// of the current settings // of the current settings
// //
void update_enabled_entities(); void update_enabled_entities();
// //
// Update the color of toolpaths in dependence of the current // Update the color of toolpaths in dependence of the current
// view type and settings // view type and settings

View File

@ -1098,7 +1098,8 @@ void GCodeViewer::init()
#if ENABLE_NEW_GCODE_VIEWER #if ENABLE_NEW_GCODE_VIEWER
try try
{ {
m_viewer.init(); m_viewer.init(reinterpret_cast<const char*>(glGetString(GL_VERSION)));
glcheck();
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {