Fix OpenGL framebuffer object support on macOS (#14769)

* Fix OpenGL framebuffer object support on macOS
this enables the outline on macOS

* Revert "Fix OpenGL framebuffer object support on macOS"

This reverts commit 9872708954.

* Enable ARB framebuffer if OpenGL >= 3.0 (OrcaSlicer/OrcaSlicer#14770)

* FIX: plater toolbar image update

jira: STUDIO-12457

Change-Id: Ia855b4bd9bec884d52202f5d8f5cfad9efce0f2f
(cherry picked from commit 474691813b497654ef701fe7073992db366e81a9)

* FIX: thumbinal regen

jira: STUDIO-16732

Change-Id: I4cc4e76b36caf1a41793c1f84ee5e88a44ebdd42
(cherry picked from commit 53f33b7db260005e477842d6459b1b28aa8aa0d8)

* FIX: force update thumbinal once dirty

jira: STUDIO-13041

Change-Id: I770743b53c51351cb3b8a7133140974c75c05364
(cherry picked from commit 96198a12712f21d2b4521b6e3d1caff50bed21ff)

* FIX:thumbnail update

jira: STUDIO-13041 / STUDIO-13304

Change-Id: I9dec25f12454fc8485195cf5dc3feb421b6347c4
(cherry picked from commit cf778dc90f805d3f46e28f8f1d1d5814d3fb4d51)

---------

Co-authored-by: jun.zhang <jun.zhang@bambulab.com>
This commit is contained in:
Noisyfox
2026-07-16 11:02:55 +08:00
committed by GitHub
parent 8d8e4c2835
commit 5e7ad1ad70
12 changed files with 76 additions and 32 deletions

View File

@@ -2338,11 +2338,6 @@ void GLCanvas3D::remove_curr_plate_all()
m_dirty = true;
}
void GLCanvas3D::update_plate_thumbnails()
{
_update_imgui_select_plate_toolbar();
}
void GLCanvas3D::select_all()
{
if (!m_gizmos.is_allow_select_all()) {
@@ -3223,7 +3218,6 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt)
// BBS
//m_dirty |= wxGetApp().plater()->get_view_toolbar().update_items_state();
m_dirty |= wxGetApp().plater()->get_collapse_toolbar().update_items_state();
_update_imgui_select_plate_toolbar();
bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(wxGetApp().plater()->get_camera());
m_dirty |= mouse3d_controller_applied;
m_dirty |= wxGetApp().plater()->get_notification_manager()->update_notifications(*this);
@@ -4833,11 +4827,6 @@ void GLCanvas3D::force_set_focus() {
void GLCanvas3D::on_set_focus(wxFocusEvent& evt)
{
m_tooltip_enabled = false;
if (m_canvas_type == ECanvasType::CanvasPreview) {
// update thumbnails and update plate toolbar
wxGetApp().plater()->update_all_plate_thumbnails();
_update_imgui_select_plate_toolbar();
}
_refresh_if_shown_on_screen();
m_tooltip_enabled = true;
m_is_touchpad_navigation = wxGetApp().app_config->get_bool("camera_navigation_style");
@@ -6920,13 +6909,28 @@ void GLCanvas3D::_update_select_plate_toolbar_stats_item(bool force_selected) {
bool GLCanvas3D::_update_imgui_select_plate_toolbar()
{
bool result = true;
if (!m_sel_plate_toolbar.is_enabled() || m_sel_plate_toolbar.is_render_finish) return false;
if (!m_sel_plate_toolbar.is_enabled()) {
return false;
}
const auto& p_plater = wxGetApp().plater();
if (!p_plater) {
return false;
}
if (!p_plater->is_plate_toolbar_image_dirty()) {
return false;
}
if (!p_plater->is_gcode_3mf()) {
p_plater->update_all_plate_thumbnails(true);
}
_update_select_plate_toolbar_stats_item();
m_sel_plate_toolbar.del_all_item();
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
PartPlateList& plate_list = p_plater->get_partplate_list();
for (int i = 0; i < plate_list.get_plate_count(); i++) {
IMToolbarItem* item = new IMToolbarItem();
PartPlate* plate = plate_list.get_plate(i);
@@ -6939,7 +6943,7 @@ bool GLCanvas3D::_update_imgui_select_plate_toolbar()
}
m_sel_plate_toolbar.m_items.push_back(item);
}
p_plater->clear_plate_toolbar_image_dirty();
m_sel_plate_toolbar.is_display_scrollbar = false;
return result;
}
@@ -8797,6 +8801,8 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar()
return;
}
_update_imgui_select_plate_toolbar();
IMToolbarItem* all_plates_stats_item = m_sel_plate_toolbar.m_all_plates_stats_item;
PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list();
@@ -9213,7 +9219,6 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar()
m_sel_plate_toolbar.is_display_scrollbar = is_win_hovered;
imgui.end();
m_sel_plate_toolbar.is_render_finish = true;
}
//BBS: GUI refactor: GLToolbar adjust

View File

@@ -997,7 +997,6 @@ public:
void select_curr_plate_all();
void select_object_from_idx(std::vector<int>& object_idxs);
void remove_curr_plate_all();
void update_plate_thumbnails();
void select_all();
void deselect_all();

View File

@@ -61,8 +61,6 @@ void IMToolbar::del_stats_item()
void IMToolbar::set_enabled(bool enable)
{
m_enabled = enable;
if (!m_enabled)
is_render_finish = false;
}
bool IMReturnToolbar::init()

View File

@@ -51,7 +51,6 @@ public:
float icon_height;
bool is_display_scrollbar;
bool show_stats_item{ false };
bool is_render_finish{false};
IMToolbar() {
icon_width = DEFAULT_TOOLBAR_BUTTON_WIDTH;
icon_height = DEFAULT_TOOLBAR_BUTTON_HEIGHT;

View File

@@ -3158,6 +3158,9 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
shader->set_uniform("Texture", 0);
shader->set_uniform("ProjMtx", ortho_projection);
const uint8_t stage = 0;
shader->set_uniform("s_texture", stage);
// Will project scissor/clipping rectangles into framebuffer space
const ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
const ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
@@ -3222,6 +3225,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data)
glsafe(::glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)));
// Bind texture, Draw
glsafe(::glActiveTexture(GL_TEXTURE0 + stage));
glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()));
glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx))));
}

View File

@@ -348,6 +348,8 @@ void FillBedJob::finalize(bool canceled, std::exception_ptr &eptr)
}
m_plater->update();
}
m_plater->mark_plate_toolbar_image_dirty();
}
}} // namespace Slic3r::GUI

View File

@@ -266,7 +266,12 @@ bool OpenGLManager::init_gl(bool popup_error)
else
s_compressed_textures_supported = false;
if (GLAD_GL_ARB_framebuffer_object) {
if (s_gl_info.is_version_greater_or_equal_to(3, 0)) {
// ARB framebuffer became a mandatory part of core OpenGL 3.0
s_framebuffers_type = EFramebufferType::Arb;
BOOST_LOG_TRIVIAL(info) << "Opengl version >= 30, FrameBuffer Type ARB." << std::endl;
}
else if (GLAD_GL_ARB_framebuffer_object) {
s_framebuffers_type = EFramebufferType::Arb;
BOOST_LOG_TRIVIAL(info) << "Found Framebuffer Type ARB."<< std::endl;
}

View File

@@ -2433,6 +2433,9 @@ void PartPlate::set_pos_and_size(Vec3d& origin, int width, int depth, int height
m_depth = depth;
m_height = height;
if (with_instance_move && m_plater)
m_plater->mark_plate_toolbar_image_dirty();
return;
}
@@ -2780,6 +2783,8 @@ int PartPlate::add_instance(int obj_id, int instance_id, bool move_position, Bou
}
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1% , m_ready_for_slice changes to %2%") % m_plate_index %m_ready_for_slice;
if (m_plater)
m_plater->mark_plate_toolbar_image_dirty();
return 0;
}
@@ -5344,6 +5349,9 @@ int PartPlateList::notify_instance_removed(int obj_id, int instance_id)
unprintable_plate.update_object_index(obj_id, m_model->objects.size());
}
if (m_plater)
m_plater->mark_plate_toolbar_image_dirty();
return 0;
}
@@ -6265,6 +6273,9 @@ int PartPlateList::rebuild_plates_after_arrangement(bool recycle_plates, bool ex
}
#endif
if (m_plater)
m_plater->mark_plate_toolbar_image_dirty();
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":after rebuild, plates count %1%") % m_plate_list.size();
return ret;
}

View File

@@ -277,6 +277,21 @@ void Plater::show_illegal_characters_warning(wxWindow* parent)
show_error(parent, _L("Invalid name, the following characters are not allowed:") + " <>:/\\|?*\"");
}
void Plater::mark_plate_toolbar_image_dirty()
{
m_b_plate_toolbar_image_dirty = true;
}
bool Plater::is_plate_toolbar_image_dirty() const
{
return m_b_plate_toolbar_image_dirty;
}
void Plater::clear_plate_toolbar_image_dirty()
{
m_b_plate_toolbar_image_dirty = false;
}
static std::map<BedType, std::string> bed_type_thumbnails = {
{BedType::btPC, "bed_cool" },
{BedType::btEP, "bed_engineering" },
@@ -6326,10 +6341,8 @@ void Plater::priv::update(unsigned int flags)
//BBS assemble view
this->assemble_view->reload_scene(false, flags);
if (current_panel && is_preview_shown()) {
q->force_update_all_plate_thumbnails();
//update_fff_scene_only_shells(true);
}
// todo: better to mark thumbnail dirty here
q->mark_plate_toolbar_image_dirty();
if (force_background_processing_restart)
this->restart_background_process(update_status);
@@ -7884,6 +7897,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_
}
}
q->schedule_background_process(true);
q->mark_plate_toolbar_image_dirty();
return obj_idxs;
}
@@ -8263,6 +8277,8 @@ void Plater::priv::object_list_changed()
main_frame->update_slice_print_status(MainFrame::eEventObjectUpdate, can_slice);
wxGetApp().params_panel()->notify_object_config_changed();
q->mark_plate_toolbar_image_dirty();
}
void Plater::priv::select_curr_plate_all()
@@ -9166,6 +9182,8 @@ void Plater::priv::update_fff_scene()
view3D->reload_scene(true);
//BBS: add assemble view related logic
assemble_view->reload_scene(true);
q->mark_plate_toolbar_image_dirty();
}
//BBS: add print project related logic
@@ -10074,9 +10092,6 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice)
preview->get_canvas3d()->enable_select_plate_toolbar(true);
}
}
else {
preview->get_canvas3d()->enable_select_plate_toolbar(false);
}
if (current_panel == panel)
{
@@ -10935,6 +10950,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":finished, reload print soon");
m_is_slicing = false;
this->preview->reload_print(false);
q->mark_plate_toolbar_image_dirty();
/* BBS if in publishing progress */
if (m_is_publishing) {
if (m_publish_dlg && !m_publish_dlg->was_cancelled()) {
@@ -14651,6 +14667,7 @@ void Plater::invalid_all_plate_thumbnails()
plate->thumbnail_data.reset();
plate->no_light_thumbnail_data.reset();
}
mark_plate_toolbar_image_dirty();
}
void Plater::force_update_all_plate_thumbnails()
@@ -14661,7 +14678,6 @@ void Plater::force_update_all_plate_thumbnails()
invalid_all_plate_thumbnails();
update_all_plate_thumbnails(true);
}
get_preview_canvas3D()->update_plate_thumbnails();
}
// BBS: backup

View File

@@ -936,6 +936,10 @@ public:
bool is_loading_project() const { return m_loading_project; }
void mark_plate_toolbar_image_dirty();
bool is_plate_toolbar_image_dirty() const;
void clear_plate_toolbar_image_dirty();
private:
struct priv;
std::unique_ptr<priv> p;
@@ -956,6 +960,7 @@ private:
std::string m_preview_only_filename;
int m_valid_plates_count { 0 };
int m_check_status = 0; // 0 not check, 1 check success, 2 check failed
bool m_b_plate_toolbar_image_dirty{ true };
void suppress_snapshots();
void allow_snapshots();