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 <string>
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

View File

@ -9,11 +9,6 @@
#include <cctype>
#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 {
#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<const char*>(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

View File

@ -8,6 +8,8 @@
// OpenGL loader
#include "../glad/include/glad/glad.h"
#include <string>
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

View File

@ -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()

View File

@ -318,24 +318,25 @@ const std::map<EOptionType, Color> 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);

View File

@ -19,6 +19,8 @@
#include "Layers.hpp"
#include "ExtrusionRoles.hpp"
#include <string>
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

View File

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