diff --git a/src/PrusaSlicer.cpp b/src/PrusaSlicer.cpp index a2f7b7c629..87e61ec5de 100644 --- a/src/PrusaSlicer.cpp +++ b/src/PrusaSlicer.cpp @@ -122,6 +122,9 @@ int CLI::run(int argc, char **argv) #endif // _WIN32 #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 #endif // ENABLE_GL_CORE_PROFILE const std::vector &load_configs = m_config.option("load", true)->values; @@ -173,7 +176,7 @@ int CLI::run(int argc, char **argv) it = std::find(m_actions.begin(), m_actions.end(), "opengl-core"); if (it != m_actions.end()) { std::string opengl_version_str = m_config.opt_string("opengl-core"); - const std::vector valid_versions = { "3.3", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6" }; + const std::vector valid_versions = { "3.2", "3.3", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6" }; if (std::find(valid_versions.begin(), valid_versions.end(), opengl_version_str) == valid_versions.end()) { boost::nowide::cerr << "Found invalid OpenGL version: " << opengl_version_str << std::endl; opengl_version_str.clear(); @@ -188,6 +191,15 @@ int CLI::run(int argc, char **argv) start_gui = true; 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 // are we starting as gcodeviewer ? for (auto it = m_actions.begin(); it != m_actions.end(); ++it) { @@ -650,6 +662,9 @@ int CLI::run(int argc, char **argv) params.start_as_gcodeviewer = start_as_gcodeviewer; #if ENABLE_GL_CORE_PROFILE params.opengl_version = opengl_version; +#if ENABLE_OPENGL_DEBUG_OPTION + params.opengl_debug = opengl_debug; +#endif // ENABLE_OPENGL_DEBUG_OPTION #endif // ENABLE_GL_CORE_PROFILE return Slic3r::GUI::GUI_Run(params); #else // SLIC3R_GUI diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 96786ccdea..945722ba4d 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -4310,6 +4310,12 @@ CLIActionsConfigDef::CLIActionsConfigDef() def->tooltip = L("Select the specified OpenGL version supporting core profile"); def->cli = "opengl-core"; def->set_default_value(new ConfigOptionString()); + + 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->cli = "opengl-debug"; + def->set_default_value(new ConfigOptionBool(false)); #endif // ENABLE_GL_CORE_PROFILE def = this->add("slice", coBool); diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index 9c5551bad6..b2b02b643e 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -55,6 +55,8 @@ #define ENABLE_LEGACY_OPENGL_REMOVAL (1 && ENABLE_2_5_0_ALPHA1) // Enable OpenGL core profile context (tested against Mesa 20.1.8 on Windows) #define ENABLE_GL_CORE_PROFILE (1 && ENABLE_LEGACY_OPENGL_REMOVAL) +// Enable OpenGL debug messages using debug context +#define ENABLE_OPENGL_DEBUG_OPTION (1 && ENABLE_GL_CORE_PROFILE) // Shows an imgui dialog with GLModel statistics data #define ENABLE_GLMODEL_STATISTICS (0 && ENABLE_LEGACY_OPENGL_REMOVAL) // Enable show non-manifold edges diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 56aa5f2704..bf5443b030 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -758,11 +758,6 @@ void GCodeViewer::init() // initializes tool marker m_sequential_view.marker.init(); - // initializes point sizes - std::array point_sizes; - ::glGetIntegerv(GL_ALIASED_POINT_SIZE_RANGE, point_sizes.data()); - m_detected_point_sizes = { static_cast(point_sizes[0]), static_cast(point_sizes[1]) }; - m_gl_data_initialized = true; } @@ -2065,8 +2060,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) #if ENABLE_GL_CORE_PROFILE GLuint vao_id = 0; - glsafe(::glGenVertexArrays(1, &vao_id)); - glsafe(::glBindVertexArray(vao_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) { + glsafe(::glGenVertexArrays(1, &vao_id)); + glsafe(::glBindVertexArray(vao_id)); + } #endif // ENABLE_GL_CORE_PROFILE GLuint vbo_id = 0; @@ -2076,9 +2073,10 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); - - t_buffer.vertices.vaos.push_back(static_cast(vao_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) { + glsafe(::glBindVertexArray(0)); + t_buffer.vertices.vaos.push_back(static_cast(vao_id)); + } #endif // ENABLE_GL_CORE_PROFILE t_buffer.vertices.vbos.push_back(static_cast(vbo_id)); t_buffer.vertices.sizes.push_back(size_bytes); @@ -2160,10 +2158,11 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) if (i_multibuffer.empty()) { i_multibuffer.push_back(IndexBuffer()); #if ENABLE_GL_CORE_PROFILE - if (!t_buffer.vertices.vaos.empty()) { + if (!t_buffer.vertices.vaos.empty() && OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); + + if (!t_buffer.vertices.vbos.empty()) vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); - } #else if (!t_buffer.vertices.vbos.empty()) vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); @@ -2176,7 +2175,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) if (i_multibuffer.back().size() * sizeof(IBufferType) >= IBUFFER_THRESHOLD_BYTES - indiced_size_to_add) { i_multibuffer.push_back(IndexBuffer()); #if ENABLE_GL_CORE_PROFILE - vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); #endif // ENABLE_GL_CORE_PROFILE vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); if (t_buffer.render_primitive_type != TBuffer::ERenderPrimitiveType::BatchedModel) { @@ -2194,7 +2194,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) ++curr_vertex_buffer.first; curr_vertex_buffer.second = 0; #if ENABLE_GL_CORE_PROFILE - vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + vao_index_list.push_back(t_buffer.vertices.vaos[curr_vertex_buffer.first]); #endif // ENABLE_GL_CORE_PROFILE vbo_index_list.push_back(t_buffer.vertices.vbos[curr_vertex_buffer.first]); @@ -2254,7 +2255,8 @@ void GCodeViewer::load_toolpaths(const GCodeProcessorResult& gcode_result) IBuffer& ibuf = t_buffer.indices.back(); ibuf.count = size_elements; #if ENABLE_GL_CORE_PROFILE - ibuf.vao = vao_indices[i][t_buffer.indices.size() - 1]; + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + ibuf.vao = vao_indices[i][t_buffer.indices.size() - 1]; #endif // ENABLE_GL_CORE_PROFILE ibuf.vbo = vbo_indices[i][t_buffer.indices.size() - 1]; @@ -2886,7 +2888,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool const IBuffer& i_buffer = buffer.indices[ibuffer_id]; cap.buffer = &buffer; #if ENABLE_GL_CORE_PROFILE - cap.vao = i_buffer.vao; + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + cap.vao = i_buffer.vao; #endif // ENABLE_GL_CORE_PROFILE cap.vbo = i_buffer.vbo; @@ -2934,7 +2937,8 @@ void GCodeViewer::refresh_render_paths(bool keep_sequential_current_first, bool const IBuffer& i_buffer = buffer.indices[ibuffer_id]; cap.buffer = &buffer; #if ENABLE_GL_CORE_PROFILE - cap.vao = i_buffer.vao; + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + cap.vao = i_buffer.vao; #endif // ENABLE_GL_CORE_PROFILE cap.vbo = i_buffer.vbo; @@ -3113,7 +3117,8 @@ void GCodeViewer::render_toolpaths() const IBuffer& i_buffer = buffer.indices[j]; buffer_range.last = buffer_range.first + i_buffer.count / indices_per_instance; #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(i_buffer.vao)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(i_buffer.vao)); #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -3172,7 +3177,8 @@ void GCodeViewer::render_toolpaths() #endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE buffer_range.first = buffer_range.last; @@ -3239,7 +3245,8 @@ void GCodeViewer::render_toolpaths() continue; #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(i_buffer.vao)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(i_buffer.vao)); #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, i_buffer.vbo)); #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -3301,7 +3308,8 @@ void GCodeViewer::render_toolpaths() #endif // ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE } } @@ -3332,7 +3340,8 @@ void GCodeViewer::render_toolpaths() #endif // ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(cap.vao)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(cap.vao)); #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, cap.vbo)); #if ENABLE_LEGACY_OPENGL_REMOVAL @@ -3381,7 +3390,8 @@ void GCodeViewer::render_toolpaths() glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE shader->stop_using(); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index e3325f0552..0cdbf888bb 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -364,11 +364,7 @@ class GCodeViewer { case ERenderPrimitiveType::Line: case ERenderPrimitiveType::Triangle: { -#if ENABLE_GL_CORE_PROFILE - return !vertices.vaos.empty() && vertices.vaos.front() != 0 && !indices.empty() && indices.front().ibo != 0; -#else return !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; -#endif // ENABLE_GL_CORE_PROFILE } case ERenderPrimitiveType::InstancedModel: { return model.model.is_initialized() && !model.instances.buffer.empty(); } case ERenderPrimitiveType::BatchedModel: { @@ -377,11 +373,7 @@ class GCodeViewer #else return model.data.vertices_count() > 0 && model.data.indices_count() && #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if ENABLE_GL_CORE_PROFILE - !vertices.vaos.empty() && vertices.vaos.front() != 0 && !indices.empty() && indices.front().ibo != 0; -#else !vertices.vbos.empty() && vertices.vbos.front() != 0 && !indices.empty() && indices.front().ibo != 0; -#endif // ENABLE_GL_CORE_PROFILE } default: { return false; } } @@ -817,7 +809,6 @@ private: #if ENABLE_GCODE_VIEWER_STATISTICS Statistics m_statistics; #endif // ENABLE_GCODE_VIEWER_STATISTICS - std::array m_detected_point_sizes = { 0.0f, 0.0f }; GCodeProcessorResult::SettingsIds m_settings_ids; std::array m_sequential_range_caps; #if ENABLE_PREVIEW_LAYER_TIME diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 526f6ce9ae..c288b90e2a 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -124,8 +124,8 @@ void GLCanvas3D::LayersEditing::init() glsafe(::glGenTextures(1, (GLuint*)&m_z_texture_id)); glsafe(::glBindTexture(GL_TEXTURE_2D, m_z_texture_id)); if (!OpenGLManager::get_gl_info().is_core_profile() || !OpenGLManager::get_gl_info().is_mesa()) { - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)); - glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); } glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST)); @@ -389,7 +389,7 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 m_profile.background.reset(); GLModel::Geometry init_data; - init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P2T2 }; + init_data.format = { GLModel::Geometry::EPrimitiveType::Triangles, GLModel::Geometry::EVertexLayout::P3N3T2 }; init_data.reserve_vertices(4); init_data.reserve_indices(6); @@ -398,10 +398,10 @@ void GLCanvas3D::LayersEditing::render_active_object_annotations(const GLCanvas3 const float r = 1.0f; const float t = 1.0f; const float b = -1.0f; - init_data.add_vertex(Vec2f(l, b), Vec2f(0.0f, 0.0f)); - init_data.add_vertex(Vec2f(r, b), Vec2f(1.0f, 0.0f)); - init_data.add_vertex(Vec2f(r, t), Vec2f(1.0f, 1.0f)); - init_data.add_vertex(Vec2f(l, t), Vec2f(0.0f, 1.0f)); + init_data.add_vertex(Vec3f(l, b, 0.0f), Vec3f::UnitZ(), Vec2f(0.0f, 0.0f)); + init_data.add_vertex(Vec3f(r, b, 0.0f), Vec3f::UnitZ(), Vec2f(1.0f, 0.0f)); + init_data.add_vertex(Vec3f(r, t, 0.0f), Vec3f::UnitZ(), Vec2f(1.0f, 1.0f)); + init_data.add_vertex(Vec3f(l, t, 0.0f), Vec3f::UnitZ(), Vec2f(0.0f, 1.0f)); // indices init_data.add_triangle(0, 1, 2); diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index a2c9b54d7d..c8ffa71d10 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -112,6 +112,19 @@ void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal) vertices.emplace_back(normal.z()); } +void GLModel::Geometry::add_vertex(const Vec3f& position, const Vec3f& normal, const Vec2f& tex_coord) +{ + assert(format.vertex_layout == EVertexLayout::P3N3T2); + vertices.emplace_back(position.x()); + vertices.emplace_back(position.y()); + vertices.emplace_back(position.z()); + vertices.emplace_back(normal.x()); + vertices.emplace_back(normal.y()); + vertices.emplace_back(normal.z()); + vertices.emplace_back(tex_coord.x()); + vertices.emplace_back(tex_coord.y()); +} + void GLModel::Geometry::add_vertex(const Vec4f& position) { assert(format.vertex_layout == EVertexLayout::P4); @@ -253,13 +266,14 @@ size_t GLModel::Geometry::vertex_stride_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P2: { return 2; } - case EVertexLayout::P2T2: { return 4; } - case EVertexLayout::P3: { return 3; } - case EVertexLayout::P3T2: { return 5; } - case EVertexLayout::P3N3: { return 6; } - case EVertexLayout::P4: { return 4; } - default: { assert(false); return 0; } + case EVertexLayout::P2: { return 2; } + case EVertexLayout::P2T2: { return 4; } + case EVertexLayout::P3: { return 3; } + case EVertexLayout::P3T2: { return 5; } + case EVertexLayout::P3N3: { return 6; } + case EVertexLayout::P3N3T2: { return 8; } + case EVertexLayout::P4: { return 4; } + default: { assert(false); return 0; } }; } @@ -268,12 +282,13 @@ size_t GLModel::Geometry::position_stride_floats(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P2: - case EVertexLayout::P2T2: { return 2; } + case EVertexLayout::P2T2: { return 2; } case EVertexLayout::P3: case EVertexLayout::P3T2: - case EVertexLayout::P3N3: { return 3; } - case EVertexLayout::P4: { return 4; } - default: { assert(false); return 0; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3T2: { return 3; } + case EVertexLayout::P4: { return 4; } + default: { assert(false); return 0; } }; } @@ -286,6 +301,7 @@ size_t GLModel::Geometry::position_offset_floats(const Format& format) case EVertexLayout::P3: case EVertexLayout::P3T2: case EVertexLayout::P3N3: + case EVertexLayout::P3N3T2: case EVertexLayout::P4: { return 0; } default: { assert(false); return 0; } }; @@ -295,8 +311,9 @@ size_t GLModel::Geometry::normal_stride_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P3N3: { return 3; } - default: { assert(false); return 0; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3T2: { return 3; } + default: { assert(false); return 0; } }; } @@ -304,8 +321,9 @@ size_t GLModel::Geometry::normal_offset_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P3N3: { return 3; } - default: { assert(false); return 0; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3T2: { return 3; } + default: { assert(false); return 0; } }; } @@ -314,8 +332,9 @@ size_t GLModel::Geometry::tex_coord_stride_floats(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P2T2: - case EVertexLayout::P3T2: { return 2; } - default: { assert(false); return 0; } + case EVertexLayout::P3T2: + case EVertexLayout::P3N3T2: { return 2; } + default: { assert(false); return 0; } }; } @@ -323,9 +342,10 @@ size_t GLModel::Geometry::tex_coord_offset_floats(const Format& format) { switch (format.vertex_layout) { - case EVertexLayout::P2T2: { return 2; } - case EVertexLayout::P3T2: { return 3; } - default: { assert(false); return 0; } + case EVertexLayout::P2T2: { return 2; } + case EVertexLayout::P3T2: { return 3; } + case EVertexLayout::P3N3T2: { return 6; } + default: { assert(false); return 0; } }; } @@ -349,6 +369,7 @@ bool GLModel::Geometry::has_position(const Format& format) case EVertexLayout::P3: case EVertexLayout::P3T2: case EVertexLayout::P3N3: + case EVertexLayout::P3N3T2: case EVertexLayout::P4: { return true; } default: { assert(false); return false; } }; @@ -362,9 +383,10 @@ bool GLModel::Geometry::has_normal(const Format& format) case EVertexLayout::P2T2: case EVertexLayout::P3: case EVertexLayout::P3T2: - case EVertexLayout::P4: { return false; } - case EVertexLayout::P3N3: { return true; } - default: { assert(false); return false; } + case EVertexLayout::P4: { return false; } + case EVertexLayout::P3N3: + case EVertexLayout::P3N3T2: { return true; } + default: { assert(false); return false; } }; } @@ -373,12 +395,13 @@ bool GLModel::Geometry::has_tex_coord(const Format& format) switch (format.vertex_layout) { case EVertexLayout::P2T2: - case EVertexLayout::P3T2: { return true; } + case EVertexLayout::P3T2: + case EVertexLayout::P3N3T2: { return true; } case EVertexLayout::P2: case EVertexLayout::P3: case EVertexLayout::P3N3: - case EVertexLayout::P4: { return false; } - default: { assert(false); return false; } + case EVertexLayout::P4: { return false; } + default: { assert(false); return false; } }; } #else @@ -853,11 +876,7 @@ void GLModel::render(const std::pair& range) return; // sends data to gpu if not done yet -#if ENABLE_GL_CORE_PROFILE - if (m_render_data.vao_id == 0) { -#else if (m_render_data.vbo_id == 0 || m_render_data.ibo_id == 0) { -#endif // ENABLE_GL_CORE_PROFILE if (m_render_data.geometry.vertices_count() > 0 && m_render_data.geometry.indices_count() > 0 && !send_to_gpu()) return; } @@ -873,7 +892,8 @@ void GLModel::render(const std::pair& range) const bool tex_coord = Geometry::has_tex_coord(data.format); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(m_render_data.vao_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(m_render_data.vao_id)); // the following binding is needed to set the vertex attributes #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, m_render_data.vbo_id)); @@ -906,9 +926,10 @@ void GLModel::render(const std::pair& range) shader->set_uniform("uniform_color", data.color); -#if !ENABLE_GL_CORE_PROFILE - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); -#endif // !ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE + if (!OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_render_data.ibo_id)); glsafe(::glDrawElements(mode, range.second - range.first, index_type, (const void*)(range.first * Geometry::index_stride_bytes(data)))); #if !ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); @@ -923,7 +944,8 @@ void GLModel::render(const std::pair& range) glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE #if ENABLE_GLMODEL_STATISTICS @@ -958,11 +980,7 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance if (offset_id == -1 || scales_id == -1) return; -#if ENABLE_GL_CORE_PROFILE - if (m_render_data.vao_id == 0) { -#else if (m_render_data.vbo_id == 0 || m_render_data.ibo_id == 0) { -#endif // ENABLE_GL_CORE_PROFILE if (!send_to_gpu()) return; } @@ -981,7 +999,8 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance #endif // ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(m_render_data.vao_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(m_render_data.vao_id)); #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, instances_vbo)); @@ -1097,7 +1116,8 @@ void GLModel::render_instanced(unsigned int instances_vbo, unsigned int instance glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE #if ENABLE_GLMODEL_STATISTICS @@ -1120,8 +1140,10 @@ bool GLModel::send_to_gpu() } #if ENABLE_GL_CORE_PROFILE - glsafe(::glGenVertexArrays(1, &m_render_data.vao_id)); - glsafe(::glBindVertexArray(m_render_data.vao_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) { + glsafe(::glGenVertexArrays(1, &m_render_data.vao_id)); + glsafe(::glBindVertexArray(m_render_data.vao_id)); + } #endif // ENABLE_GL_CORE_PROFILE // vertices @@ -1163,9 +1185,11 @@ bool GLModel::send_to_gpu() glsafe(::glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.indices_size_bytes(), data.indices.data(), GL_STATIC_DRAW)); } -#if !ENABLE_GL_CORE_PROFILE - glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); -#endif // !ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE + if (!OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) +#endif // ENABLE_GL_CORE_PROFILE + glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); + m_render_data.indices_count = indices_count; #if ENABLE_GLMODEL_STATISTICS s_statistics.gpu_memory.indices.current += data.indices_size_bytes(); @@ -1174,7 +1198,8 @@ bool GLModel::send_to_gpu() data.indices = std::vector(); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE return true; diff --git a/src/slic3r/GUI/GLModel.hpp b/src/slic3r/GUI/GLModel.hpp index 64f0c67625..43398f4505 100644 --- a/src/slic3r/GUI/GLModel.hpp +++ b/src/slic3r/GUI/GLModel.hpp @@ -63,6 +63,7 @@ namespace GUI { P3, // position 3 floats P3T2, // position 3 floats + texture coords 2 floats P3N3, // position 3 floats + normal 3 floats + P3N3T2, // position 3 floats + normal 3 floats + texture coords 2 floats P4, // position 4 floats }; @@ -88,12 +89,13 @@ namespace GUI { void reserve_vertices(size_t vertices_count) { vertices.reserve(vertices_count * vertex_stride_floats(format)); } void reserve_indices(size_t indices_count) { indices.reserve(indices_count); } - void add_vertex(const Vec2f& position); // EVertexLayout::P2 - void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2 - void add_vertex(const Vec3f& position); // EVertexLayout::P3 - void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2 - void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 - void add_vertex(const Vec4f& position); // EVertexLayout::P4 + void add_vertex(const Vec2f& position); // EVertexLayout::P2 + void add_vertex(const Vec2f& position, const Vec2f& tex_coord); // EVertexLayout::P2T2 + void add_vertex(const Vec3f& position); // EVertexLayout::P3 + void add_vertex(const Vec3f& position, const Vec2f& tex_coord); // EVertexLayout::P3T2 + void add_vertex(const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 + void add_vertex(const Vec3f& position, const Vec3f& normal, const Vec2f& tex_coord); // EVertexLayout::P3N3T2 + void add_vertex(const Vec4f& position); // EVertexLayout::P4 void set_vertex(size_t id, const Vec3f& position, const Vec3f& normal); // EVertexLayout::P3N3 diff --git a/src/slic3r/GUI/GLSelectionRectangle.cpp b/src/slic3r/GUI/GLSelectionRectangle.cpp index 2386f2af06..9249afc831 100644 --- a/src/slic3r/GUI/GLSelectionRectangle.cpp +++ b/src/slic3r/GUI/GLSelectionRectangle.cpp @@ -116,7 +116,8 @@ namespace GUI { #endif // ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_GL_CORE_PROFILE - if (!OpenGLManager::get_gl_info().is_core_profile()) + const bool core_profile = OpenGLManager::get_gl_info().is_core_profile(); + if (!core_profile) #endif // ENABLE_GL_CORE_PROFILE glsafe(::glLineWidth(1.5f)); #if !ENABLE_LEGACY_OPENGL_REMOVAL @@ -139,15 +140,19 @@ namespace GUI { glsafe(::glScaled(gui_scale, gui_scale, 1.0)); #endif // !ENABLE_LEGACY_OPENGL_REMOVAL -#if !ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE + if (!core_profile) { +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glPushAttrib(GL_ENABLE_BIT)); glsafe(::glLineStipple(4, 0xAAAA)); glsafe(::glEnable(GL_LINE_STIPPLE)); -#endif // !ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE + } +#endif // ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_GL_CORE_PROFILE - GLShaderProgram* shader = OpenGLManager::get_gl_info().is_core_profile() ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); + GLShaderProgram* shader = core_profile ? wxGetApp().get_shader("dashed_thick_lines") : wxGetApp().get_shader("flat"); #else GLShaderProgram* shader = wxGetApp().get_shader("flat"); #endif // ENABLE_GL_CORE_PROFILE @@ -216,11 +221,13 @@ namespace GUI { shader->set_uniform("view_model_matrix", Transform3d::Identity()); shader->set_uniform("projection_matrix", Transform3d::Identity()); #if ENABLE_GL_CORE_PROFILE + if (core_profile) { const std::array& viewport = wxGetApp().plater()->get_camera().get_viewport(); shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); shader->set_uniform("width", 0.25f); shader->set_uniform("dash_size", 0.01f); shader->set_uniform("gap_size", 0.0075f); + } #endif // ENABLE_GL_CORE_PROFILE m_rectangle.set_color(ColorRGBA((m_state == EState::Select) ? 0.3f : 1.0f, (m_state == EState::Select) ? 1.0f : 0.3f, 0.3f, 1.0f)); @@ -236,9 +243,10 @@ namespace GUI { glsafe(::glEnd()); #endif // ENABLE_LEGACY_OPENGL_REMOVAL -#if !ENABLE_GL_CORE_PROFILE +#if ENABLE_GL_CORE_PROFILE + if (!core_profile) +#endif // ENABLE_GL_CORE_PROFILE glsafe(::glPopAttrib()); -#endif // !ENABLE_GL_CORE_PROFILE #if !ENABLE_LEGACY_OPENGL_REMOVAL glsafe(::glPopMatrix()); diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 7d55e5b14f..09412f0bd6 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -848,7 +848,12 @@ 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 #else return m_opengl_mgr.init_glcontext(canvas); #endif // ENABLE_GL_CORE_PROFILE diff --git a/src/slic3r/GUI/GUI_Init.cpp b/src/slic3r/GUI/GUI_Init.cpp index 2da68b5c80..6b7e38aa0a 100644 --- a/src/slic3r/GUI/GUI_Init.cpp +++ b/src/slic3r/GUI/GUI_Init.cpp @@ -53,7 +53,6 @@ int GUI_Run(GUI_InitParams ¶ms) // gui->autosave = m_config.opt_string("autosave"); GUI::GUI_App::SetInstance(gui); gui->init_params = ¶ms; - return wxEntry(params.argc, params.argv); } catch (const Slic3r::Exception &ex) { boost::nowide::cerr << ex.what() << std::endl; diff --git a/src/slic3r/GUI/GUI_Init.hpp b/src/slic3r/GUI/GUI_Init.hpp index 44bcd00c81..d3ababe241 100644 --- a/src/slic3r/GUI/GUI_Init.hpp +++ b/src/slic3r/GUI/GUI_Init.hpp @@ -23,6 +23,9 @@ struct GUI_InitParams bool start_as_gcodeviewer; #if ENABLE_GL_CORE_PROFILE std::pair opengl_version; +#if ENABLE_OPENGL_DEBUG_OPTION + bool opengl_debug; +#endif // ENABLE_OPENGL_DEBUG_OPTION #endif // ENABLE_GL_CORE_PROFILE }; diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp index 7f06b2a2e4..fd9f988daf 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMmuSegmentation.cpp @@ -709,7 +709,7 @@ void GLMmSegmentationGizmo3DScene::release_geometry() { triangle_indices_VBO_id = 0; } #if ENABLE_GL_CORE_PROFILE - if (this->vertices_VAO_id) { + if (this->vertices_VAO_id > 0) { glsafe(::glDeleteVertexArrays(1, &this->vertices_VAO_id)); this->vertices_VAO_id = 0; } @@ -723,7 +723,8 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const assert(triangle_indices_idx < this->triangle_indices_VBO_ids.size()); assert(this->triangle_indices_sizes.size() == this->triangle_indices_VBO_ids.size()); #if ENABLE_GL_CORE_PROFILE - assert(this->vertices_VAO_id != 0); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + assert(this->vertices_VAO_id != 0); #endif // ENABLE_GL_CORE_PROFILE assert(this->vertices_VBO_id != 0); assert(this->triangle_indices_VBO_ids[triangle_indices_idx] != 0); @@ -735,7 +736,8 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const #endif // ENABLE_LEGACY_OPENGL_REMOVAL #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(this->vertices_VAO_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(this->vertices_VAO_id)); // the following binding is needed to set the vertex attributes #endif // ENABLE_GL_CORE_PROFILE glsafe(::glBindBuffer(GL_ARRAY_BUFFER, this->vertices_VBO_id)); @@ -770,20 +772,23 @@ void GLMmSegmentationGizmo3DScene::render(size_t triangle_indices_idx) const glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); #if ENABLE_GL_CORE_PROFILE - glsafe(::glBindVertexArray(0)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE } void GLMmSegmentationGizmo3DScene::finalize_vertices() { #if ENABLE_GL_CORE_PROFILE - assert(this->vertices_VAO_id == 0); + assert(this->vertices_VAO_id == 0); #endif // ENABLE_GL_CORE_PROFILE assert(this->vertices_VBO_id == 0); if (!this->vertices.empty()) { #if ENABLE_GL_CORE_PROFILE - glsafe(::glGenVertexArrays(1, &this->vertices_VAO_id)); - glsafe(::glBindVertexArray(this->vertices_VAO_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) { + glsafe(::glGenVertexArrays(1, &this->vertices_VAO_id)); + glsafe(::glBindVertexArray(this->vertices_VAO_id)); + } #endif // ENABLE_GL_CORE_PROFILE glsafe(::glGenBuffers(1, &this->vertices_VBO_id)); @@ -793,6 +798,7 @@ void GLMmSegmentationGizmo3DScene::finalize_vertices() this->vertices.clear(); #if ENABLE_GL_CORE_PROFILE + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) glsafe(::glBindVertexArray(0)); #endif // ENABLE_GL_CORE_PROFILE } diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index 2a24961de1..f326ab4725 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -182,7 +182,12 @@ void GLGizmoPainterBase::render_cursor_circle() const float cnv_inv_height = 1.0f / cnv_height; const Vec2d center = m_parent.get_local_mouse_position(); +#if ENABLE_GL_CORE_PROFILE + const float zoom = float(wxGetApp().plater()->get_camera().get_zoom()); + const float radius = m_cursor_radius * zoom; +#else const float radius = m_cursor_radius * float(wxGetApp().plater()->get_camera().get_zoom()); +#endif // ENABLE_GL_CORE_PROFILE #else const float cnv_half_width = 0.5f * float(cnv_size.get_width()); const float cnv_half_height = 0.5f * float(cnv_size.get_height()); @@ -220,44 +225,45 @@ void GLGizmoPainterBase::render_cursor_circle() #endif // !ENABLE_GL_CORE_PROFILE #if ENABLE_LEGACY_OPENGL_REMOVAL +#if ENABLE_GL_CORE_PROFILE + if (!m_circle.is_initialized() || std::abs(m_old_cursor_radius - radius) > EPSILON) { + m_old_cursor_radius = radius; + m_circle.reset(); +#else if (!m_circle.is_initialized() || !m_old_center.isApprox(center) || std::abs(m_old_cursor_radius - radius) > EPSILON) { m_old_cursor_radius = radius; m_old_center = center; m_circle.reset(); +#endif // ENABLE_GL_CORE_PROFILE GLModel::Geometry init_data; +#if ENABLE_GL_CORE_PROFILE + const unsigned int StepsCount = (unsigned int)(2 * (4 + int(252 * (zoom - 1.0f) / (250.0f - 1.0f)))); + const float StepSize = 2.0f * float(PI) / float(StepsCount); + init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P2 }; +#else static const unsigned int StepsCount = 32; static const float StepSize = 2.0f * float(PI) / float(StepsCount); -#if ENABLE_GL_CORE_PROFILE - init_data.format = { GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P4 }; -#else init_data.format = { GLModel::Geometry::EPrimitiveType::LineLoop, GLModel::Geometry::EVertexLayout::P2 }; #endif // ENABLE_GL_CORE_PROFILE init_data.color = { 0.0f, 1.0f, 0.3f, 1.0f }; -#if ENABLE_GL_CORE_PROFILE - init_data.reserve_vertices(2 * StepsCount); - init_data.reserve_indices(2 * StepsCount); -#else init_data.reserve_vertices(StepsCount); init_data.reserve_indices(StepsCount); -#endif // ENABLE_GL_CORE_PROFILE // vertices + indices -#if ENABLE_GL_CORE_PROFILE - float perimeter = 0.0f; -#endif // ENABLE_GL_CORE_PROFILE - for (unsigned int i = 0; i < StepsCount; ++i) { #if ENABLE_GL_CORE_PROFILE + if (i % 2 != 0) continue; + const float angle_i = float(i) * StepSize; const unsigned int j = (i + 1) % StepsCount; const float angle_j = float(j) * StepSize; - const Vec2d v_i(2.0f * ((center.x() + ::cos(angle_i) * radius) * cnv_inv_width - 0.5f), -2.0f * ((center.y() + ::sin(angle_i) * radius) * cnv_inv_height - 0.5f)); - const Vec2d v_j(2.0f * ((center.x() + ::cos(angle_j) * radius) * cnv_inv_width - 0.5f), -2.0f * ((center.y() + ::sin(angle_j) * radius) * cnv_inv_height - 0.5f)); - init_data.add_vertex(Vec4f(v_i.x(), v_i.y(), 0.0f, perimeter)); - perimeter += (v_j - v_i).norm(); - init_data.add_vertex(Vec4f(v_j.x(), v_j.y(), 0.0f, perimeter)); - init_data.add_line(i * 2 + 0, i * 2 + 1); + const Vec2d v_i(::cos(angle_i), ::sin(angle_i)); + const Vec2d v_j(::cos(angle_j), ::sin(angle_j)); + init_data.add_vertex(Vec2f(v_i.x(), v_i.y())); + init_data.add_vertex(Vec2f(v_j.x(), v_j.y())); + const size_t vcount = init_data.vertices_count(); + init_data.add_line(vcount - 2, vcount - 1); #else const float angle = float(i) * StepSize; init_data.add_vertex(Vec2f(2.0f * ((center.x() + ::cos(angle) * radius) * cnv_inv_width - 0.5f), @@ -276,14 +282,19 @@ void GLGizmoPainterBase::render_cursor_circle() #endif // ENABLE_GL_CORE_PROFILE if (shader != nullptr) { shader->start_using(); +#if ENABLE_GL_CORE_PROFILE + const Transform3d view_model_matrix = Geometry::translation_transform(Vec3d(2.0f * (center.x() * cnv_inv_width - 0.5f), -2.0f * (center.y() * cnv_inv_height - 0.5f), 0.0)) * + Geometry::scale_transform(Vec3d(2.0f * radius * cnv_inv_width, 2.0f * radius * cnv_inv_height, 1.0f)); + shader->set_uniform("view_model_matrix", view_model_matrix); +#else shader->set_uniform("view_model_matrix", Transform3d::Identity()); +#endif // ENABLE_GL_CORE_PROFILE shader->set_uniform("projection_matrix", Transform3d::Identity()); #if ENABLE_GL_CORE_PROFILE const std::array& viewport = wxGetApp().plater()->get_camera().get_viewport(); shader->set_uniform("viewport_size", Vec2d(double(viewport[2]), double(viewport[3]))); shader->set_uniform("width", 0.25f); - shader->set_uniform("dash_size", 0.01f); - shader->set_uniform("gap_size", 0.0075f); + shader->set_uniform("gap_size", 0.0f); #endif // ENABLE_GL_CORE_PROFILE m_circle.render(); shader->stop_using(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp index 368be50118..04f24b20d3 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.hpp @@ -213,7 +213,9 @@ protected: #if ENABLE_LEGACY_OPENGL_REMOVAL GLModel m_circle; +#if !ENABLE_GL_CORE_PROFILE Vec2d m_old_center{ Vec2d::Zero() }; +#endif // !ENABLE_GL_CORE_PROFILE float m_old_cursor_radius{ 0.0f }; #endif // ENABLE_LEGACY_OPENGL_REMOVAL diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 9a72b3161d..b8220d609e 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -1486,7 +1486,9 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) GLuint last_program; glsafe(::glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program)); GLuint last_texture; glsafe(::glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture)); GLuint last_array_buffer; glsafe(::glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer)); - GLuint last_vertex_array_object; glsafe(::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object)); + GLuint last_vertex_array_object = 0; + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glGetIntegerv(GL_VERTEX_ARRAY_BINDING, (GLint*)&last_vertex_array_object)); GLint last_viewport[4]; glsafe(::glGetIntegerv(GL_VIEWPORT, last_viewport)); GLint last_scissor_box[4]; glsafe(::glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box)); GLenum last_blend_src_rgb; glsafe(::glGetIntegerv(GL_BLEND_SRC_RGB, (GLint*)&last_blend_src_rgb)); @@ -1583,8 +1585,10 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) #if ENABLE_GL_CORE_PROFILE GLuint vao_id = 0; - glsafe(::glGenVertexArrays(1, &vao_id)); - glsafe(::glBindVertexArray(vao_id)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) { + glsafe(::glGenVertexArrays(1, &vao_id)); + glsafe(::glBindVertexArray(vao_id)); + } #endif // ENABLE_GL_CORE_PROFILE GLuint vbo_id; @@ -1669,6 +1673,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glDeleteBuffers(1, &ibo_id)); glsafe(::glDeleteBuffers(1, &vbo_id)); #if ENABLE_GL_CORE_PROFILE + if (vao_id > 0) glsafe(::glDeleteVertexArrays(1, &vao_id)); #endif // ENABLE_GL_CORE_PROFILE #endif // ENABLE_LEGACY_OPENGL_REMOVAL @@ -1678,7 +1683,8 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) // Restore modified GL state glsafe(::glBindTexture(GL_TEXTURE_2D, last_texture)); glsafe(::glActiveTexture(last_active_texture)); - glsafe(::glBindVertexArray(last_vertex_array_object)); + if (OpenGLManager::get_gl_info().is_version_greater_or_equal_to(3, 0)) + glsafe(::glBindVertexArray(last_vertex_array_object)); glsafe(::glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer)); glsafe(::glBlendEquationSeparate(last_blend_equation_rgb, last_blend_equation_alpha)); glsafe(::glBlendFuncSeparate(last_blend_src_rgb, last_blend_dst_rgb, last_blend_src_alpha, last_blend_dst_alpha)); diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index b4729335a4..339abe3010 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -66,11 +66,6 @@ const std::string& OpenGLManager::GLInfo::get_renderer() const return m_renderer; } -bool OpenGLManager::GLInfo::is_core_profile() const -{ - return !GLEW_ARB_compatibility; -} - bool OpenGLManager::GLInfo::is_mesa() const { return boost::icontains(m_version, "mesa"); @@ -273,6 +268,52 @@ OpenGLManager::~OpenGLManager() #endif //__APPLE__ } +#if ENABLE_OPENGL_DEBUG_OPTION +#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) + return; + + std::string out = "OpenGL DEBUG message ["; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: out += "Error"; break; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: out += "Deprecated Behaviour"; break; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: out += "Undefined Behaviour"; break; + case GL_DEBUG_TYPE_PORTABILITY: out += "Portability"; break; + case GL_DEBUG_TYPE_PERFORMANCE: out += "Performance"; break; + case GL_DEBUG_TYPE_MARKER: out += "Marker"; break; + case GL_DEBUG_TYPE_PUSH_GROUP: out += "Push Group"; break; + case GL_DEBUG_TYPE_POP_GROUP: out += "Pop Group"; break; + case GL_DEBUG_TYPE_OTHER: out += "Other"; break; + } + out += "/"; + switch (source) + { + case GL_DEBUG_SOURCE_API: out += "API"; break; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: out += "Window System"; break; + case GL_DEBUG_SOURCE_SHADER_COMPILER: out += "Shader Compiler"; break; + case GL_DEBUG_SOURCE_THIRD_PARTY: out += "Third Party"; break; + case GL_DEBUG_SOURCE_APPLICATION: out += "Application"; break; + case GL_DEBUG_SOURCE_OTHER: out += "Other"; break; + } + out += "/"; + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: out += "high"; break; + case GL_DEBUG_SEVERITY_MEDIUM: out += "medium"; break; + case GL_DEBUG_SEVERITY_LOW: out += "low"; break; + case GL_DEBUG_SEVERITY_NOTIFICATION: out += "notification"; break; + } + out += "]:\n"; + std::cout << out << "(" << id << "): " << message << "\n\n"; +} +#endif // ENABLE_OPENGL_DEBUG_OPTION + bool OpenGLManager::init_gl() { if (!m_gl_initialized) { @@ -313,10 +354,11 @@ bool OpenGLManager::init_gl() s_framebuffers_type = EFramebufferType::Unknown; #if ENABLE_GL_CORE_PROFILE - bool valid_version = s_gl_info.is_core_profile() ? s_gl_info.is_version_greater_or_equal_to(3, 3) : s_gl_info.is_version_greater_or_equal_to(2, 0); + 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); #else bool valid_version = s_gl_info.is_version_greater_or_equal_to(2, 0); #endif // ENABLE_GL_CORE_PROFILE + if (!valid_version) { // Complain about the OpenGL version. wxString message = from_u8((boost::format( @@ -344,6 +386,14 @@ bool OpenGLManager::init_gl() _utf8(L("Unable to load the following shaders:\n%s"))) % error).str()); wxMessageBox(message, wxString("PrusaSlicer - ") + _L("Error loading shaders"), wxOK | wxICON_ERROR); } +#if ENABLE_OPENGL_DEBUG_OPTION + if (m_debug_enabled && 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); + } +#endif // ENABLE_OPENGL_DEBUG_OPTION } } @@ -351,33 +401,49 @@ 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 #else wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) #endif // ENABLE_GL_CORE_PROFILE { if (m_context == nullptr) { #if ENABLE_GL_CORE_PROFILE - if (required_opengl_version != std::make_pair(0, 0)) { // the user specified a required version in the command line using --opengl=M.m - m_required_version = required_opengl_version; - const bool supports_core_profile = (m_required_version.first < 3) ? false : - (m_required_version.first > 3) ? true : m_required_version.second >= 3; +#if ENABLE_OPENGL_DEBUG_OPTION + m_debug_enabled = enable_debug; +#endif // ENABLE_OPENGL_DEBUG_OPTION + + if (required_opengl_version != std::make_pair(0, 0)) { // the user specified a required version in the command line using --opengl-core=M.m + const bool supports_core_profile = (required_opengl_version.first < 3) ? false : + (required_opengl_version.first > 3) ? true : required_opengl_version.second >= 2; 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; - attrs.MajorVersion(m_required_version.first).MinorVersion(m_required_version.second).CoreProfile().ForwardCompatible().EndList(); +#if ENABLE_OPENGL_DEBUG_OPTION + attrs.MajorVersion(required_opengl_version.first).MinorVersion(required_opengl_version.second).CoreProfile().ForwardCompatible(); + if (m_debug_enabled) + attrs.DebugCtx(); + attrs.EndList(); +#else + attrs.MajorVersion(required_opengl_version.first).MinorVersion(required_opengl_version.second).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 " << required_opengl_version.first << "." << required_opengl_version.second; delete m_context; m_context = nullptr; } - } + else + s_gl_info.set_core_profile(true); + } } //else { // // try to get the highest supported OpenGL version with core profile - // static const std::vector> valid_core_versions = { {4,6}, {4,5}, {4,4}, {4,3}, {4,2}, {4,1}, {4,0}, {3,3} }; + // static const std::vector> valid_core_versions = { {4,6}, {4,5}, {4,4}, {4,3}, {4,2}, {4,1}, {4,0}, {3,3}, {3,2} }; // // disable wxWidgets logging to avoid showing the log dialog in case the following code fails generating a valid gl context // wxLogNull logNo; // for (const auto& [major, minor] : valid_core_versions) { @@ -393,9 +459,20 @@ wxGLContext* OpenGLManager::init_glcontext(wxGLCanvas& canvas) // } //} +#if ENABLE_OPENGL_DEBUG_OPTION + if (m_context == nullptr) { + wxGLContextAttrs attrs; + 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 #else m_context = new wxGLContext(&canvas); #endif // ENABLE_GL_CORE_PROFILE @@ -415,6 +492,10 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) #if ENABLE_GL_CORE_PROFILE wxGLAttributes attribList; attribList.PlatformDefaults().RGBA().DoubleBuffer().MinRGBA(8, 8, 8, 8).Depth(24).SampleBuffers(1).Samplers(4).EndList(); +#ifdef __APPLE__ + // on MAC the method RGBA() has no effect + attribList.SetNeedsARB(true); +#endif // __APPLE__ #else int attribList[] = { WX_GL_RGBA, @@ -444,6 +525,10 @@ wxGLCanvas* OpenGLManager::create_wxglcanvas(wxWindow& parent) { attribList.Reset(); attribList.PlatformDefaults().RGBA().DoubleBuffer().MinRGBA(8, 8, 8, 8).Depth(24).EndList(); +#ifdef __APPLE__ + // on MAC the method RGBA() has no effect + attribList.SetNeedsARB(true); +#endif // __APPLE__ } return new wxGLCanvas(&parent, attribList, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxWANTS_CHARS); diff --git a/src/slic3r/GUI/OpenGLManager.hpp b/src/slic3r/GUI/OpenGLManager.hpp index 12717740e3..fb9d385a4a 100644 --- a/src/slic3r/GUI/OpenGLManager.hpp +++ b/src/slic3r/GUI/OpenGLManager.hpp @@ -27,6 +27,7 @@ public: class GLInfo { bool m_detected{ false }; + bool m_core_profile{ false }; int m_max_tex_size{ 0 }; float m_max_anisotropy{ 0.0f }; @@ -43,7 +44,9 @@ public: const std::string& get_vendor() const; const std::string& get_renderer() const; - bool is_core_profile() const; + bool is_core_profile() const { return m_core_profile; } + void set_core_profile(bool value) { m_core_profile = value; } + bool is_mesa() const; int get_max_tex_size() const; @@ -84,9 +87,9 @@ private: bool m_gl_initialized{ false }; wxGLContext* m_context{ nullptr }; -#if ENABLE_GL_CORE_PROFILE - std::pair m_required_version{ 0, 0 }; -#endif // ENABLE_GL_CORE_PROFILE +#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__ @@ -103,7 +106,11 @@ 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 #else wxGLContext* init_glcontext(wxGLCanvas& canvas); #endif // ENABLE_GL_CORE_PROFILE